@@ -13,6 +13,10 @@ namespace Volo.Abp.Telemetry.Activity.Storage;
13
13
14
14
public class TelemetryActivityStorage : ITelemetryActivityStorage , ISingletonDependency
15
15
{
16
+ private const int MaxFileRetries = 5 ;
17
+ private const int RetryDelayMs = 100 ;
18
+ private static readonly TimeSpan InfoExpirationPeriod = TimeSpan . FromDays ( 7 ) ;
19
+
16
20
private TelemetryActivityStorageState ? _cachedState ;
17
21
18
22
public async Task BufferActivityAsync ( ActivityData activityData )
@@ -31,19 +35,16 @@ public async Task<List<ActivityData>> GetBufferedActivitiesAsync()
31
35
public async Task EndSessionAsync ( )
32
36
{
33
37
var state = await GetStateAsync ( ) ;
34
-
35
38
state . SessionId = null ;
36
39
await SaveAsync ( ) ;
37
40
}
38
41
39
-
40
42
public async Task < DateTimeOffset ? > GetLastActivitySendTimeAsync ( )
41
43
{
42
44
var state = await GetStateAsync ( ) ;
43
45
return state . ActivitySendTime ;
44
46
}
45
47
46
-
47
48
public async Task < Guid > GetOrCreateSessionInfoAsync ( )
48
49
{
49
50
var state = await GetStateAsync ( ) ;
@@ -58,7 +59,6 @@ public async Task MarkActivitiesAsSentAsync()
58
59
state . ActivitySendTime = DateTimeOffset . UtcNow ;
59
60
state . Activities . Clear ( ) ;
60
61
state . SessionId = null ;
61
-
62
62
await SaveAsync ( ) ;
63
63
}
64
64
@@ -68,29 +68,12 @@ public async Task MarkSolutionInfoAsAddedAsync(Guid solutionId)
68
68
state . Solutions [ solutionId ] = DateTimeOffset . UtcNow ;
69
69
await SaveAsync ( ) ;
70
70
}
71
- public async Task MarkApplicationInfoAsAddedAsync ( Guid applicationInfo )
72
- {
73
- var state = await GetStateAsync ( ) ;
74
- state . Solutions [ applicationInfo ] = DateTimeOffset . UtcNow ;
75
- await SaveAsync ( ) ;
76
- }
77
-
78
- private async Task < DateTimeOffset ? > GetLastSolutionInfoSendTimeAsync ( Guid id )
79
- {
80
- var state = await GetStateAsync ( ) ;
81
-
82
- if ( state . Solutions . TryGetValue ( id , out var date ) )
83
- {
84
- return date ;
85
- }
86
-
87
- return null ;
88
- }
89
71
90
- private async Task < DateTimeOffset ? > GetLastDeviceInfoSendTimeAsync ( )
72
+ public async Task MarkApplicationInfoAsAddedAsync ( Guid applicationId )
91
73
{
92
74
var state = await GetStateAsync ( ) ;
93
- return state . LastDeviceInfoAddTime ;
75
+ state . ApplicationInfos [ applicationId ] = DateTimeOffset . UtcNow ;
76
+ await SaveAsync ( ) ;
94
77
}
95
78
96
79
public async Task MarkDeviceInfoAsAddedAsync ( )
@@ -99,22 +82,41 @@ public async Task MarkDeviceInfoAsAddedAsync()
99
82
state . LastDeviceInfoAddTime = DateTimeOffset . UtcNow ;
100
83
await SaveAsync ( ) ;
101
84
}
102
-
85
+
103
86
public virtual async Task < bool > ShouldAddDeviceInfoAsync ( )
104
87
{
105
88
var lastSend = await GetLastDeviceInfoSendTimeAsync ( ) ;
106
- return lastSend is null || DateTimeOffset . UtcNow - lastSend > TimeSpan . FromDays ( 7 ) ;
89
+ return ShouldAddInfo ( lastSend ) ;
107
90
}
108
91
109
92
public virtual async Task < bool > ShouldAddSolutionInformation ( Guid solutionId )
110
93
{
111
94
var lastSend = await GetLastSolutionInfoSendTimeAsync ( solutionId ) ;
112
- return lastSend is null || DateTimeOffset . UtcNow - lastSend > TimeSpan . FromDays ( 7 ) ;
95
+ return ShouldAddInfo ( lastSend ) ;
113
96
}
97
+
114
98
public virtual async Task < bool > ShouldAddApplicationInfoAsync ( Guid applicationId )
115
99
{
116
100
var lastSend = await GetLastApplicationInfoSendTimeAsync ( applicationId ) ;
117
- return lastSend is null || DateTimeOffset . UtcNow - lastSend > TimeSpan . FromDays ( 7 ) ;
101
+ return ShouldAddInfo ( lastSend ) ;
102
+ }
103
+
104
+ private async Task < DateTimeOffset ? > GetLastSolutionInfoSendTimeAsync ( Guid solutionId )
105
+ {
106
+ var state = await GetStateAsync ( ) ;
107
+ return state . Solutions . TryGetValue ( solutionId , out var date ) ? date : null ;
108
+ }
109
+
110
+ private async Task < DateTimeOffset ? > GetLastApplicationInfoSendTimeAsync ( Guid applicationId )
111
+ {
112
+ var state = await GetStateAsync ( ) ;
113
+ return state . ApplicationInfos . TryGetValue ( applicationId , out var date ) ? date : null ;
114
+ }
115
+
116
+ private async Task < DateTimeOffset ? > GetLastDeviceInfoSendTimeAsync ( )
117
+ {
118
+ var state = await GetStateAsync ( ) ;
119
+ return state . LastDeviceInfoAddTime ;
118
120
}
119
121
120
122
private async Task < TelemetryActivityStorageState > GetStateAsync ( )
@@ -129,19 +131,15 @@ private async Task<TelemetryActivityStorageState> GetStateAsync()
129
131
{
130
132
using var reader = new StreamReader ( stream , Encoding . UTF8 ) ;
131
133
var json = await reader . ReadToEndAsync ( ) ;
132
- return JsonSerializer . Deserialize < TelemetryActivityStorageState ? > ( json ,
133
- new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy . CamelCase } ) ??
134
- new TelemetryActivityStorageState ( ) ;
135
- } ) ;
134
+ return JsonSerializer . Deserialize < TelemetryActivityStorageState ? > ( json , GetJsonSerializerOptions ( ) )
135
+ ?? new TelemetryActivityStorageState ( ) ;
136
+ } ) ?? new TelemetryActivityStorageState ( ) ;
136
137
return _cachedState ;
137
138
}
138
139
139
- private async Task < TResult > WithExclusiveFileLockAsync < TResult > ( Func < FileStream , Task < TResult > > action )
140
+ private async Task < TResult ? > WithExclusiveFileLockAsync < TResult > ( Func < FileStream , Task < TResult > > action )
140
141
{
141
- const int maxRetries = 5 ;
142
- const int retryDelayMs = 100 ;
143
-
144
- for ( int i = 0 ; i < maxRetries ; i ++ )
142
+ for ( int i = 0 ; i < MaxFileRetries ; i ++ )
145
143
{
146
144
try
147
145
{
@@ -156,27 +154,29 @@ private async Task<TResult> WithExclusiveFileLockAsync<TResult>(Func<FileStream,
156
154
}
157
155
catch ( IOException )
158
156
{
159
- if ( i == maxRetries - 1 )
157
+ if ( i == MaxFileRetries - 1 )
160
158
{
161
- throw ;
159
+ return default ;
162
160
}
163
161
164
- await Task . Delay ( retryDelayMs ) ;
162
+ await Task . Delay ( RetryDelayMs ) ;
163
+ }
164
+ catch
165
+ {
166
+ return default ;
165
167
}
166
168
}
167
169
168
- throw new IOException ( "Unable to acquire file lock for ActivityStorage." ) ;
170
+ return default ;
169
171
}
170
172
171
173
private Task SaveAsync ( )
172
174
{
173
- var json = JsonSerializer . Serialize ( _cachedState ?? new TelemetryActivityStorageState ( ) ,
174
- new JsonSerializerOptions { WriteIndented = true , PropertyNamingPolicy = JsonNamingPolicy . CamelCase } ) ;
175
+ var json = JsonSerializer . Serialize ( _cachedState ?? new TelemetryActivityStorageState ( ) , GetJsonSerializerOptions ( ) ) ;
175
176
File . WriteAllText ( TelemetryPaths . ActivityStorage , json , Encoding . UTF8 ) ;
176
177
return Task . CompletedTask ;
177
178
}
178
179
179
-
180
180
private Task EnsureFileExistsAsync ( )
181
181
{
182
182
try
@@ -190,31 +190,29 @@ private Task EnsureFileExistsAsync()
190
190
191
191
if ( ! File . Exists ( TelemetryPaths . ActivityStorage ) )
192
192
{
193
- var json = JsonSerializer . Serialize ( _cachedState ?? new TelemetryActivityStorageState ( ) ,
194
- new JsonSerializerOptions
195
- {
196
- PropertyNamingPolicy = JsonNamingPolicy . CamelCase , WriteIndented = true
197
- } ) ;
193
+ var json = JsonSerializer . Serialize ( _cachedState ?? new TelemetryActivityStorageState ( ) , GetJsonSerializerOptions ( ) ) ;
198
194
File . WriteAllText ( TelemetryPaths . ActivityStorage , json , Encoding . UTF8 ) ;
199
195
}
200
196
}
201
197
catch
202
198
{
203
- //ignored
199
+ // Ignored intentionally
204
200
}
205
201
206
202
return Task . CompletedTask ;
207
203
}
208
204
209
- private async Task < DateTimeOffset ? > GetLastApplicationInfoSendTimeAsync ( Guid applicationId )
205
+ private static JsonSerializerOptions GetJsonSerializerOptions ( )
210
206
{
211
- var state = await GetStateAsync ( ) ;
212
- if ( state . ApplicationInfos . TryGetValue ( applicationId , out var lastActivitySendTime ) )
207
+ return new JsonSerializerOptions
213
208
{
214
- return lastActivitySendTime ;
215
- }
209
+ PropertyNamingPolicy = JsonNamingPolicy . CamelCase ,
210
+ WriteIndented = true
211
+ } ;
212
+ }
216
213
217
- return null ;
214
+ private static bool ShouldAddInfo ( DateTimeOffset ? lastSend )
215
+ {
216
+ return lastSend is null || DateTimeOffset . UtcNow - lastSend > InfoExpirationPeriod ;
218
217
}
219
-
220
218
}
0 commit comments