Browse Source

Refactor `TelemetryActivityStorage` for improved readability.

pull/23059/head
Emre KARA 1 year ago
parent
commit
e2b5c46b7f
  1. 80
      framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs

80
framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs

@ -16,10 +16,15 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
{
private const string MutexName = "Global\\TelemetryActivityStorage";
private const string TestModeEnvironmentVariable = "ABP_TELEMETRY_TEST_MODE";
private readonly TimeSpan _infoExpirationPeriod;
private readonly TimeSpan _activitySendPeriod;
private TelemetryActivityStorageState? _cachedState;
private readonly static JsonSerializerOptions JsonSerializerOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public TelemetryActivityStorage()
{
@ -30,7 +35,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task BufferActivityAsync(ActivityEvent activityEvent)
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.Activities.Insert(0, activityEvent);
});
@ -44,7 +49,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task EndSessionAsync()
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.SessionId = null;
});
@ -59,7 +64,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
return state.SessionId.Value;
}
await ModifyStateAsync(s =>
await UpdateStateAsync(s =>
{
s.SessionId = Guid.NewGuid();
});
@ -68,7 +73,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task MarkActivitiesAsSentAsync()
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.ActivitySendTime = DateTimeOffset.UtcNow;
state.Activities.Clear();
@ -77,7 +82,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task MarkSolutionInfoAsAddedAsync(Guid solutionId)
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.Solutions[solutionId] = DateTimeOffset.UtcNow;
});
@ -85,7 +90,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task MarkApplicationInfoAsAddedAsync(Guid applicationId)
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.Applications[applicationId] = DateTimeOffset.UtcNow;
});
@ -93,7 +98,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
public async Task MarkDeviceInfoAsAddedAsync()
{
await ModifyStateAsync(state =>
await UpdateStateAsync(state =>
{
state.LastDeviceInfoAddTime = DateTimeOffset.UtcNow;
});
@ -130,11 +135,11 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
return bool.TryParse(testModeVariable, out var isTestMode) && isTestMode;
}
private async Task ModifyStateAsync(Action<TelemetryActivityStorageState> modifyAction)
private async Task UpdateStateAsync(Action<TelemetryActivityStorageState> modifyAction)
{
var state = await GetStateAsync();
modifyAction(state);
await SaveAsync();
Save();
}
private async Task<DateTimeOffset?> GetLastActivitySendTimeAsync()
@ -166,21 +171,16 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
return lastSend is null || DateTimeOffset.UtcNow - lastSend > _infoExpirationPeriod;
}
private async Task<TelemetryActivityStorageState> GetStateAsync()
private async ValueTask<TelemetryActivityStorageState> GetStateAsync()
{
if (_cachedState != null)
{
return _cachedState;
}
EnsureFileExists();
_cachedState = await LoadStateFromFileAsync() ?? new TelemetryActivityStorageState();
return _cachedState;
}
private async Task<TelemetryActivityStorageState?> LoadStateFromFileAsync()
{
return await WithExclusiveFileLockAsync(async stream =>
EnsureStorageExists();
_cachedState = await WithExclusiveFileLockAsync(async stream =>
{
using var reader = new StreamReader(stream, Encoding.UTF8);
var encryptedJson = await reader.ReadToEndAsync();
@ -191,51 +191,52 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
}
var json = EncryptionHelper.Decrypt(encryptedJson);
return JsonSerializer.Deserialize<TelemetryActivityStorageState?>(json, GetJsonSerializerOptions())
return JsonSerializer.Deserialize<TelemetryActivityStorageState>(json, JsonSerializerOptions)
?? new TelemetryActivityStorageState();
});
}) ?? new TelemetryActivityStorageState();
return _cachedState;
}
private Task SaveAsync()
private void Save()
{
var state = _cachedState ?? new TelemetryActivityStorageState();
var json = JsonSerializer.Serialize(state, GetJsonSerializerOptions());
var json = JsonSerializer.Serialize(state, JsonSerializerOptions);
var encryptedJson = EncryptionHelper.Encrypt(json);
File.WriteAllText(TelemetryPaths.ActivityStorage, encryptedJson, Encoding.UTF8);
return Task.CompletedTask;
}
private void EnsureFileExists()
private void EnsureStorageExists()
{
try
{
EnsureDirectoryExists();
CreateDirectoryIfNotExists(Path.GetDirectoryName(TelemetryPaths.ActivityStorage)!);
if (!File.Exists(TelemetryPaths.ActivityStorage))
{
CreateInitialFile();
InitializeStorage();
}
}
catch
{
// Ignored intentionally
// Ignored
}
}
private void EnsureDirectoryExists()
private static void CreateDirectoryIfNotExists(string path)
{
var directory = Path.GetDirectoryName(TelemetryPaths.ActivityStorage);
if (!Directory.Exists(directory))
if (!Directory.Exists(path))
{
Directory.CreateDirectory(directory!);
Directory.CreateDirectory(path);
}
}
private void CreateInitialFile()
private void InitializeStorage()
{
var initialState = _cachedState ?? new TelemetryActivityStorageState();
var json = JsonSerializer.Serialize(initialState, GetJsonSerializerOptions());
var json = JsonSerializer.Serialize(initialState, JsonSerializerOptions);
var encryptedJson = EncryptionHelper.Encrypt(json);
File.WriteAllText(TelemetryPaths.ActivityStorage, encryptedJson, Encoding.UTF8);
}
@ -253,15 +254,4 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep
return await action(stream);
});
}
private static JsonSerializerOptions GetJsonSerializerOptions()
{
return new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
}
}
Loading…
Cancel
Save