1
1
using System ;
2
2
using System . Threading ;
3
+ using System . Threading . Tasks ;
3
4
4
5
namespace BTDB . KVDBLayer ;
5
6
6
7
public class CompactorScheduler : IDisposable , ICompactorScheduler
7
8
{
8
- Func < CancellationToken , bool > [ ] _coreActions = new Func < CancellationToken , bool > [ 0 ] ;
9
+ Func < CancellationToken , ValueTask < bool > > [ ] _coreActions = [ ] ;
9
10
readonly Timer _timer ;
10
11
CancellationTokenSource _cancellationSource = new CancellationTokenSource ( ) ;
11
- readonly object _lock = new object ( ) ;
12
- bool _running ; //compacting in progress
13
- bool _advicedRunning ; //was advised again during compacting
14
- bool _firstTime ; //in time period before first compact (try save resource during app startup)
12
+ readonly object _lock = new ( ) ;
13
+ bool _running ; //compacting in progress
14
+ bool _advisedRunning ; //was advised again during compacting
15
+ bool _firstTime ; //in time period before first compact (try save resource during app startup)
15
16
bool _timerStarted ; //timer is planned
16
17
bool _disposed ;
17
18
internal TimeSpan WaitTime { get ; set ; }
18
19
19
- static ICompactorScheduler _instance ;
20
+ static ICompactorScheduler ? _instance ;
20
21
21
22
public static ICompactorScheduler Instance
22
23
{
@@ -26,9 +27,10 @@ public static ICompactorScheduler Instance
26
27
{
27
28
Interlocked . CompareExchange ( ref _instance , new CompactorScheduler ( ) , null ) ;
28
29
}
29
- return _instance ;
30
+
31
+ return _instance ! ;
30
32
}
31
- set { _instance = value ; }
33
+ set => _instance = value ;
32
34
}
33
35
34
36
internal CompactorScheduler ( )
@@ -38,7 +40,8 @@ internal CompactorScheduler()
38
40
WaitTime = TimeSpan . FromMinutes ( 10 + new Random ( ) . NextDouble ( ) * 5 ) ;
39
41
}
40
42
41
- public Func < CancellationToken , bool > AddCompactAction ( Func < CancellationToken , bool > compactAction )
43
+ public Func < CancellationToken , ValueTask < bool > > AddCompactAction (
44
+ Func < CancellationToken , ValueTask < bool > > compactAction )
42
45
{
43
46
if ( _disposed ) throw new ObjectDisposedException ( nameof ( CompactorScheduler ) ) ;
44
47
while ( true )
@@ -49,10 +52,11 @@ public Func<CancellationToken, bool> AddCompactAction(Func<CancellationToken, bo
49
52
newA [ oldA . Length ] = compactAction ;
50
53
if ( Interlocked . CompareExchange ( ref _coreActions , newA , oldA ) == oldA ) break ;
51
54
}
55
+
52
56
return compactAction ;
53
57
}
54
58
55
- public void RemoveCompactAction ( Func < CancellationToken , bool > compactAction )
59
+ public void RemoveCompactAction ( Func < CancellationToken , ValueTask < bool > > compactAction )
56
60
{
57
61
if ( _disposed ) return ;
58
62
lock ( _lock )
@@ -62,6 +66,7 @@ public void RemoveCompactAction(Func<CancellationToken, bool> compactAction)
62
66
{
63
67
Monitor . Wait ( _lock ) ;
64
68
}
69
+
65
70
_cancellationSource = new CancellationTokenSource ( ) ;
66
71
while ( true )
67
72
{
@@ -83,9 +88,10 @@ public void AdviceRunning(bool openingDb)
83
88
{
84
89
if ( _running )
85
90
{
86
- _advicedRunning = true ;
91
+ _advisedRunning = true ;
87
92
return ;
88
93
}
94
+
89
95
if ( openingDb )
90
96
{
91
97
if ( _timerStarted )
@@ -101,34 +107,36 @@ public void AdviceRunning(bool openingDb)
101
107
}
102
108
}
103
109
104
- void OnTimer ( object state )
110
+ // ReSharper disable once AsyncVoidMethod
111
+ async void OnTimer ( object state )
105
112
{
106
113
lock ( _lock )
107
114
{
108
115
_firstTime = false ;
109
116
_timerStarted = false ;
110
117
if ( _running ) return ;
111
118
_running = true ;
112
-
113
119
}
120
+
114
121
try
115
122
{
116
123
var needed = false ;
117
124
do
118
125
{
119
- _advicedRunning = false ;
126
+ _advisedRunning = false ;
120
127
var actions = _coreActions ;
121
128
for ( var i = 0 ; i < actions . Length ; i ++ )
122
129
{
123
130
if ( _cancellationSource . IsCancellationRequested ) break ;
124
- needed |= actions [ i ] ( _cancellationSource . Token ) ;
131
+ needed |= await actions [ i ] ( _cancellationSource . Token ) ;
125
132
}
126
- } while ( _advicedRunning ) ;
133
+ } while ( _advisedRunning ) ;
134
+
127
135
lock ( _lock )
128
136
{
129
137
_running = false ;
130
138
Monitor . PulseAll ( _lock ) ;
131
- needed |= _advicedRunning ;
139
+ needed |= _advisedRunning ;
132
140
if ( needed && ! _cancellationSource . IsCancellationRequested )
133
141
{
134
142
_timer . Change ( WaitTime , TimeSpan . FromMilliseconds ( - 1 ) ) ;
@@ -156,6 +164,7 @@ public void Dispose()
156
164
Monitor . Wait ( _lock ) ;
157
165
}
158
166
}
167
+
159
168
_timer . Dispose ( ) ;
160
169
}
161
170
}
0 commit comments