[PM-1646] Add thread safety to migration process (#2453)

* Make migration process thread safe

* tweaks
This commit is contained in:
mp-bw 2023-03-28 17:22:09 -04:00 committed by GitHub
parent d7d044f717
commit 99ceb8dbc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 9 deletions

View file

@ -4,7 +4,6 @@ namespace Bit.Core.Abstractions
{ {
public interface IStateMigrationService public interface IStateMigrationService
{ {
Task<bool> NeedsMigration(); Task MigrateIfNeededAsync();
Task Migrate();
} }
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
@ -17,6 +18,7 @@ namespace Bit.Core.Services
private readonly IStorageService _preferencesStorageService; private readonly IStorageService _preferencesStorageService;
private readonly IStorageService _liteDbStorageService; private readonly IStorageService _liteDbStorageService;
private readonly IStorageService _secureStorageService; private readonly IStorageService _secureStorageService;
private readonly SemaphoreSlim _semaphore;
private enum Storage private enum Storage
{ {
@ -31,9 +33,27 @@ namespace Bit.Core.Services
_liteDbStorageService = liteDbStorageService; _liteDbStorageService = liteDbStorageService;
_preferencesStorageService = preferenceStorageService; _preferencesStorageService = preferenceStorageService;
_secureStorageService = secureStorageService; _secureStorageService = secureStorageService;
_semaphore = new SemaphoreSlim(1);
} }
public async Task<bool> NeedsMigration() public async Task MigrateIfNeededAsync()
{
await _semaphore.WaitAsync();
try
{
if (await IsMigrationNeededAsync())
{
await PerformMigrationAsync();
}
}
finally
{
_semaphore.Release();
}
}
private async Task<bool> IsMigrationNeededAsync()
{ {
var lastVersion = await GetLastStateVersionAsync(); var lastVersion = await GetLastStateVersionAsync();
if (lastVersion == 0) if (lastVersion == 0)
@ -45,7 +65,7 @@ namespace Bit.Core.Services
return lastVersion < StateVersion; return lastVersion < StateVersion;
} }
public async Task Migrate() private async Task PerformMigrationAsync()
{ {
var lastVersion = await GetLastStateVersionAsync(); var lastVersion = await GetLastStateVersionAsync();
switch (lastVersion) switch (lastVersion)

View file

@ -1537,11 +1537,8 @@ namespace Bit.Core.Services
{ {
if (!_migrationChecked) if (!_migrationChecked)
{ {
var migrationService = ServiceContainer.Resolve<IStateMigrationService>("stateMigrationService"); var migrationService = ServiceContainer.Resolve<IStateMigrationService>();
if (await migrationService.NeedsMigration()) await migrationService.MigrateIfNeededAsync();
{
await migrationService.Migrate();
}
_migrationChecked = true; _migrationChecked = true;
} }