[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
{
Task<bool> NeedsMigration();
Task Migrate();
Task MigrateIfNeededAsync();
}
}

View file

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

View file

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