Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
RuntimeCounters.cs
1using System;
2using System.Threading.Tasks;
7
9{
13 public static class RuntimeCounters
14 {
15 private static readonly Cache<CaseInsensitiveString, CounterRec> counters;
16 private static readonly object synchObject = new object();
17
18 private class CounterRec
19 {
20 public TaskCompletionSource<bool> Stored = new TaskCompletionSource<bool>();
21 public RuntimeCounter Counter;
22 public bool Changed;
23 }
24
25 static RuntimeCounters()
26 {
27 counters = new Cache<CaseInsensitiveString, CounterRec>(int.MaxValue, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(1));
28
29 counters.Removed += Counters_Removed;
30 }
31
32 private static async Task Counters_Removed(object Sender, CacheItemEventArgs<CaseInsensitiveString, CounterRec> e)
33 {
34 try
35 {
36 lock (synchObject)
37 {
38 if (!e.Value.Changed)
39 {
40 e.Value.Stored.TrySetResult(true);
41 return;
42 }
43 }
44
45 if (e.Value.Counter.Counter == 0)
46 {
47 if (!string.IsNullOrEmpty(e.Value.Counter.ObjectId))
48 await Database.Delete(e.Value.Counter);
49 }
50 else
51 {
52 if (string.IsNullOrEmpty(e.Value.Counter.ObjectId))
53 await Database.Insert(e.Value.Counter);
54 else
55 await Database.Update(e.Value.Counter);
56 }
57
58 e.Value.Stored.TrySetResult(true);
59 }
60 catch (Exception)
61 {
62 e.Value.Stored.TrySetResult(false);
63 }
64 }
65
69 public static async Task FlushAsync()
70 {
71 CounterRec[] Records = counters.GetValues();
72 counters.Clear();
73
74 foreach (CounterRec Rec in Records)
75 await Rec.Stored.Task;
76 }
77
83 public static Task<long> IncrementCounter(CaseInsensitiveString Key)
84 {
85 return IncrementCounter(Key, 1);
86 }
87
94 public static async Task<long> IncrementCounter(CaseInsensitiveString Key, long Delta)
95 {
96 lock (synchObject)
97 {
98 if (counters.TryGetValue(Key, out CounterRec Rec))
99 {
100 Rec.Counter.Counter += Delta;
101 Rec.Changed = true;
102
103 return Rec.Counter.Counter;
104 }
105 }
106
107 RuntimeCounter Counter = await Database.FindFirstDeleteRest<RuntimeCounter>(new FilterFieldEqualTo("Key", Key));
108
109 lock (synchObject)
110 {
111 if (counters.TryGetValue(Key, out CounterRec Rec))
112 {
113 Rec.Counter.Counter += Delta;
114 Rec.Changed = true;
115
116 return Rec.Counter.Counter;
117 }
118 else
119 {
120 if (Counter is null)
121 {
122 Counter = new RuntimeCounter()
123 {
124 Counter = Delta,
125 Key = Key
126 };
127
128 counters[Key] = new CounterRec()
129 {
130 Counter = Counter,
131 Changed = true
132 };
133 }
134 else
135 {
136 Counter.Counter += Delta;
137 counters[Key] = new CounterRec()
138 {
139 Counter = Counter,
140 Changed = true
141 };
142
143 return Counter.Counter;
144 }
145 }
146 }
147
148 return Counter.Counter;
149 }
150
156 public static Task<long> DecrementCounter(CaseInsensitiveString Key)
157 {
158 return IncrementCounter(Key, -1);
159 }
160
167 public static Task<long> DecrementCounter(CaseInsensitiveString Key, long Delta)
168 {
169 return IncrementCounter(Key, -Delta);
170 }
171
177 public static async Task<long> GetCount(CaseInsensitiveString Key)
178 {
179 lock (synchObject)
180 {
181 if (counters.TryGetValue(Key, out CounterRec Rec))
182 return Rec.Counter.Counter;
183 }
184
185 RuntimeCounter Counter = await Database.FindFirstDeleteRest<RuntimeCounter>(new FilterFieldEqualTo("Key", Key));
186
187 lock (synchObject)
188 {
189 if (counters.TryGetValue(Key, out CounterRec Rec))
190 return Rec.Counter.Counter;
191 else
192 {
193 if (Counter is null)
194 {
195 Counter = new RuntimeCounter()
196 {
197 Counter = 0,
198 Key = Key
199 };
200
201 counters[Key] = new CounterRec()
202 {
203 Counter = Counter,
204 Changed = false
205 };
206 }
207 else
208 {
209 counters[Key] = new CounterRec()
210 {
211 Counter = Counter,
212 Changed = false
213 };
214 }
215 }
216 }
217
218 return Counter.Counter;
219 }
220 }
221}
Represents a case-insensitive string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:626
static async Task Delete(object Object)
Deletes an object in the database.
Definition: Database.cs:717
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:95
This filter selects objects that have a named field equal to a given value.
Implements an in-memory cache.
Definition: Cache.cs:15
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.
Static class managing persistent counters.
static Task< long > DecrementCounter(CaseInsensitiveString Key, long Delta)
Decrements a counter.
static Task< long > IncrementCounter(CaseInsensitiveString Key)
Increments a counter.
static async Task< long > IncrementCounter(CaseInsensitiveString Key, long Delta)
Increments a counter.
static Task< long > DecrementCounter(CaseInsensitiveString Key)
Decrements a counter.
static async Task FlushAsync()
Flushes all cached counters to the database.
static async Task< long > GetCount(CaseInsensitiveString Key)
Gets the current count of a counter.