mirror of https://github.com/ErsatzTV/ErsatzTV.git
				
				
			
			
			
				Browse Source
			
			
			
			
				
		* unblock startup, show database initialization message * wait on search index to be ready (rebuild) * clean logging and fake delaypull/1326/head
				 22 changed files with 446 additions and 216 deletions
			
			
		@ -0,0 +1,33 @@ | 
				
			|||||||
 | 
					namespace ErsatzTV.Core; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SystemStartup | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					    private readonly SemaphoreSlim _databaseStartup = new(0, 100); | 
				
			||||||
 | 
					    private readonly SemaphoreSlim _searchIndexStartup = new(0, 100); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public event EventHandler OnDatabaseReady; | 
				
			||||||
 | 
					    public event EventHandler OnSearchIndexReady; | 
				
			||||||
 | 
					     | 
				
			||||||
 | 
					    public bool IsDatabaseReady { get; private set; } | 
				
			||||||
 | 
					    public bool IsSearchIndexReady { get; private set; } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task WaitForDatabase(CancellationToken cancellationToken) => | 
				
			||||||
 | 
					        await _databaseStartup.WaitAsync(cancellationToken); | 
				
			||||||
 | 
					     | 
				
			||||||
 | 
					    public async Task WaitForSearchIndex(CancellationToken cancellationToken) => | 
				
			||||||
 | 
					        await _searchIndexStartup.WaitAsync(cancellationToken); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void DatabaseIsReady() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        _databaseStartup.Release(100); | 
				
			||||||
 | 
					        IsDatabaseReady = true; | 
				
			||||||
 | 
					        OnDatabaseReady?.Invoke(this, EventArgs.Empty); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					     | 
				
			||||||
 | 
					    public void SearchIndexIsReady() | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        _searchIndexStartup.Release(100); | 
				
			||||||
 | 
					        IsSearchIndexReady = true; | 
				
			||||||
 | 
					        OnSearchIndexReady?.Invoke(this, EventArgs.Empty); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
@ -1,21 +1,32 @@ | 
				
			|||||||
using ErsatzTV.Application.Search; | 
					using ErsatzTV.Application.Search; | 
				
			||||||
 | 
					using ErsatzTV.Core; | 
				
			||||||
using MediatR; | 
					using MediatR; | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ErsatzTV.Services.RunOnce; | 
					namespace ErsatzTV.Services.RunOnce; | 
				
			||||||
 | 
					
 | 
				
			||||||
public class RebuildSearchIndexService : IHostedService | 
					public class RebuildSearchIndexService : BackgroundService | 
				
			||||||
{ | 
					{ | 
				
			||||||
    private readonly IServiceScopeFactory _serviceScopeFactory; | 
					    private readonly IServiceScopeFactory _serviceScopeFactory; | 
				
			||||||
 | 
					    private readonly SystemStartup _systemStartup; | 
				
			||||||
 | 
					
 | 
				
			||||||
    public RebuildSearchIndexService(IServiceScopeFactory serviceScopeFactory) => | 
					    public RebuildSearchIndexService(IServiceScopeFactory serviceScopeFactory, SystemStartup systemStartup) | 
				
			||||||
 | 
					    { | 
				
			||||||
        _serviceScopeFactory = serviceScopeFactory; | 
					        _serviceScopeFactory = serviceScopeFactory; | 
				
			||||||
 | 
					        _systemStartup = systemStartup; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected override async Task ExecuteAsync(CancellationToken cancellationToken) | 
				
			||||||
 | 
					    { | 
				
			||||||
 | 
					        await Task.Yield(); | 
				
			||||||
 | 
					
 | 
				
			||||||
    public async Task StartAsync(CancellationToken cancellationToken) | 
					        await _systemStartup.WaitForDatabase(cancellationToken); | 
				
			||||||
 | 
					        if (cancellationToken.IsCancellationRequested) | 
				
			||||||
        { | 
					        { | 
				
			||||||
 | 
					            return; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
        using IServiceScope scope = _serviceScopeFactory.CreateScope(); | 
					        using IServiceScope scope = _serviceScopeFactory.CreateScope(); | 
				
			||||||
        IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); | 
					        IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); | 
				
			||||||
        await mediator.Send(new RebuildSearchIndex(), cancellationToken); | 
					        await mediator.Send(new RebuildSearchIndex(), cancellationToken); | 
				
			||||||
    } | 
					    } | 
				
			||||||
 | 
					 | 
				
			||||||
    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; | 
					 | 
				
			||||||
} | 
					} | 
				
			||||||
 | 
				
			|||||||
					Loading…
					
					
				
		Reference in new issue