|
16 | 16 | usingCoder.Desktop.Vpn.Utilities;
|
17 | 17 | usingGrpc.Core;
|
18 | 18 | usingMicrosoft.Extensions.Options;
|
| 19 | +usingMicrosoft.Extensions.Logging; |
| 20 | +usingSerilog; |
19 | 21 | usingDaemonTerminateRequest=Coder.Desktop.MutagenSdk.Proto.Service.Daemon.TerminateRequest;
|
20 | 22 | usingMutagenProtocol=Coder.Desktop.MutagenSdk.Proto.Url.Protocol;
|
21 | 23 | usingSynchronizationTerminateRequest=Coder.Desktop.MutagenSdk.Proto.Service.Synchronization.TerminateRequest;
|
| 24 | +usingMicrosoft.Extensions.Hosting; |
22 | 25 |
|
23 | 26 | namespaceCoder.Desktop.App.Services;
|
24 | 27 |
|
@@ -110,6 +113,8 @@ public sealed class MutagenController : ISyncSessionController
|
110 | 113 | // Protects all private non-readonly class members.
|
111 | 114 | privatereadonlyRaiiSemaphoreSlim_lock=new(1,1);
|
112 | 115 |
|
| 116 | +privatereadonlyILogger<MutagenController>_logger; |
| 117 | + |
113 | 118 | privatereadonlyCancellationTokenSource_stateUpdateCts=new();
|
114 | 119 | privateTask?_stateUpdateTask;
|
115 | 120 |
|
@@ -139,15 +144,19 @@ public sealed class MutagenController : ISyncSessionController
|
139 | 144 |
|
140 | 145 | privatestringMutagenDaemonLog=>Path.Combine(_mutagenDataDirectory,"daemon.log");
|
141 | 146 |
|
142 |
| -publicMutagenController(IOptions<MutagenControllerConfig>config) |
| 147 | +publicMutagenController(IOptions<MutagenControllerConfig>config,ILogger<MutagenController>logger) |
143 | 148 | {
|
144 | 149 | _mutagenExecutablePath=config.Value.MutagenExecutablePath;
|
| 150 | +_logger=logger; |
145 | 151 | }
|
146 | 152 |
|
147 | 153 | publicMutagenController(stringexecutablePath,stringdataDirectory)
|
148 | 154 | {
|
149 | 155 | _mutagenExecutablePath=executablePath;
|
150 | 156 | _mutagenDataDirectory=dataDirectory;
|
| 157 | +varbuilder=Host.CreateApplicationBuilder(); |
| 158 | +builder.Services.AddSerilog(); |
| 159 | +_logger=(ILogger<MutagenController>)builder.Build().Services.GetService(typeof(ILogger<MutagenController>))!; |
151 | 160 | }
|
152 | 161 |
|
153 | 162 | publiceventEventHandler<SyncSessionControllerStateModel>?StateChanged;
|
@@ -440,9 +449,9 @@ private async Task<MutagenClient> EnsureDaemon(CancellationToken ct)
|
440 | 449 | {
|
441 | 450 | awaitStopDaemon(cts.Token);
|
442 | 451 | }
|
443 |
| -catch |
| 452 | +catch(ExceptionstopEx) |
444 | 453 | {
|
445 |
| -// ignored |
| 454 | +_logger.LogError(stopEx,"failed to stop daemon"); |
446 | 455 | }
|
447 | 456 |
|
448 | 457 | ReplaceState(newSyncSessionControllerStateModel
|
@@ -494,6 +503,8 @@ private async Task<MutagenClient> StartDaemon(CancellationToken ct)
|
494 | 503 | }
|
495 | 504 | catch(Exceptione)when(eis notOperationCanceledException)
|
496 | 505 | {
|
| 506 | +_logger.LogWarning(e,"failed to start daemon process, attempt {attempt} of {maxAttempts}",attempts, |
| 507 | +maxAttempts); |
497 | 508 | if(attempts==maxAttempts)
|
498 | 509 | throw;
|
499 | 510 | // back off a little and try again.
|
@@ -548,8 +559,11 @@ private void StartDaemonProcess()
|
548 | 559 | // https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.environment?view=net-8.0
|
549 | 560 | _daemonProcess.StartInfo.UseShellExecute=false;
|
550 | 561 | _daemonProcess.StartInfo.RedirectStandardError=true;
|
551 |
| -// TODO: log exited process |
552 |
| -// _daemonProcess.Exited += ... |
| 562 | +_daemonProcess.EnableRaisingEvents=true; |
| 563 | +_daemonProcess.Exited+=(object?sender,EventArgse)=> |
| 564 | +{ |
| 565 | +_logger.LogInformation("mutagen daemon exited with code {exitCode}",_daemonProcess?.ExitCode); |
| 566 | +}; |
553 | 567 | if(!_daemonProcess.Start())
|
554 | 568 | thrownewInvalidOperationException("Failed to start mutagen daemon process, Start returned false");
|
555 | 569 |
|
|