Skip to content

Commit 95522fc

Browse files
committed
Merge branch 'ravendb-teardown-during-stop-sequence' into spike-ravendb-termination
2 parents dd1ca69 + ad8aa1b commit 95522fc

File tree

5 files changed

+75
-6
lines changed

5 files changed

+75
-6
lines changed

src/ServiceControl.Audit.Persistence.RavenDB/IRavenPersistenceLifecycle.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
interface IRavenPersistenceLifecycle
77
{
88
Task Initialize(CancellationToken cancellationToken = default);
9+
Task Stop(CancellationToken cancellationToken);
910
}
1011
}

src/ServiceControl.Audit.Persistence.RavenDB/RavenEmbeddedPersistenceLifecycle.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public async Task Initialize(CancellationToken cancellationToken = default)
7272
}
7373
}
7474

75+
public Task Stop(CancellationToken cancellationToken) => database!.Stop(cancellationToken);
76+
7577
public void Dispose()
7678
{
7779
documentStore?.Dispose();

src/ServiceControl.Audit.Persistence.RavenDB/RavenExternalPersistenceLifecycle.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public async Task Initialize(CancellationToken cancellationToken = default)
6464
}
6565
}
6666

67+
public Task Stop(CancellationToken cancellationToken) => Task.CompletedTask; // We are not stopping an external instance
68+
6769
public void Dispose() => documentStore?.Dispose();
6870

6971
IDocumentStore? documentStore;

src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceLifecycleHostedService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ sealed class RavenPersistenceLifecycleHostedService(IRavenPersistenceLifecycle l
88
{
99
public Task StartAsync(CancellationToken cancellationToken) => lifecycle.Initialize(cancellationToken);
1010

11-
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
11+
public Task StopAsync(CancellationToken cancellationToken) => lifecycle.Stop(cancellationToken);
1212
}
1313
}

src/ServiceControl.RavenDB/EmbeddedDatabase.cs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace ServiceControl.RavenDB
1515
using Raven.Client.Documents.Conventions;
1616
using Raven.Client.ServerWide.Operations;
1717
using Raven.Embedded;
18+
using Sparrow.Logging;
1819

1920
public sealed class EmbeddedDatabase : IDisposable
2021
{
@@ -52,9 +53,20 @@ public static EmbeddedDatabase Start(EmbeddedDatabaseConfiguration databaseConfi
5253

5354
var nugetPackagesPath = Path.Combine(databaseConfiguration.DbPath, "Packages", "NuGet");
5455

56+
LoggingSource.Instance.SetupLogMode(
57+
(LogMode)255,
58+
Path.Combine(databaseConfiguration.LogPath, "Raven.Embedded"),
59+
retentionTime: TimeSpan.FromDays(14),
60+
retentionSize: 1024 * 1024 * 10,
61+
compress: false
62+
);
63+
64+
LoggingSource.Instance.EnableConsoleLogging();
65+
5566
Logger.InfoFormat("Loading RavenDB license from {0}", licenseFileNameAndServerDirectory.LicenseFileName);
5667
var serverOptions = new ServerOptions
5768
{
69+
GracefulShutdownTimeout = TimeSpan.FromHours(1), // During Stop/Dispose we manually control this
5870
CommandLineArgs =
5971
[
6072
$"--Logs.Mode={databaseConfiguration.LogsMode}",
@@ -85,6 +97,7 @@ public static EmbeddedDatabase Start(EmbeddedDatabaseConfiguration databaseConfi
8597

8698
void Start(ServerOptions serverOptions)
8799
{
100+
this.serverOptions = serverOptions;
88101
EmbeddedServer.Instance.ServerProcessExited += OnServerProcessExited;
89102
EmbeddedServer.Instance.StartServer(serverOptions);
90103

@@ -162,23 +175,72 @@ public async Task<IDocumentStore> Connect(CancellationToken cancellationToken)
162175

163176
public async Task DeleteDatabase(string dbName)
164177
{
165-
using var store = await EmbeddedServer.Instance.GetDocumentStoreAsync(new DatabaseOptions(dbName) { SkipCreatingDatabase = true });
178+
using var store = await EmbeddedServer.Instance.GetDocumentStoreAsync(new DatabaseOptions(dbName)
179+
{
180+
SkipCreatingDatabase = true
181+
});
166182
await store.Maintenance.Server.SendAsync(new DeleteDatabasesOperation(dbName, true));
167183
}
168184

185+
public async Task Stop(CancellationToken cancellationToken)
186+
{
187+
Logger.Debug("Stopping RavenDB server");
188+
EmbeddedServer.Instance.ServerProcessExited -= OnServerProcessExited;
189+
190+
await shutdownTokenSource.CancelAsync();
191+
192+
// TODO: await EmbeddedServer.Instance.StopAsync(cancellationToken);
193+
194+
var processId = await EmbeddedServer.Instance.GetServerProcessIdAsync(cancellationToken);
195+
196+
var waitForCancellationTask = Task.Delay(Timeout.Infinite, cancellationToken);
197+
var firstTask = await Task.WhenAny(
198+
Task.Run(() => EmbeddedServer.Instance.Dispose(), cancellationToken),
199+
waitForCancellationTask
200+
);
201+
202+
if (firstTask == waitForCancellationTask)
203+
{
204+
try
205+
{
206+
Logger.WarnFormat("Killing RavenDB server PID {0} child process because host cancelled", processId);
207+
var ravenChildProcess = Process.GetProcessById(processId);
208+
ravenChildProcess.Kill(entireProcessTree: true);
209+
}
210+
catch (Exception e)
211+
{
212+
Logger.ErrorFormat("Failed to kill RavenDB server PID {0}\n{1}", processId, e);
213+
}
214+
}
215+
216+
serverOptions = null!;
217+
Logger.Debug("Stopped RavenDB server");
218+
}
219+
169220
public void Dispose()
170221
{
171222
if (disposed)
172223
{
173224
return;
174225
}
175226

176-
EmbeddedServer.Instance.ServerProcessExited -= OnServerProcessExited;
227+
if (serverOptions != null)
228+
{
229+
EmbeddedServer.Instance.ServerProcessExited -= OnServerProcessExited;
230+
}
177231

178232
shutdownTokenSource.Cancel();
179-
Logger.Debug("Disposing RavenDB server");
180-
EmbeddedServer.Instance.Dispose();
181-
Logger.Debug("Dispose RavenDB server");
233+
234+
if (serverOptions != null)
235+
{
236+
// Set GracefulShutdownTimeout to Zero and exist ASAP, under normal operation instance would already
237+
// have been allowed to gracefully stop during "Stop" method.
238+
serverOptions!.GracefulShutdownTimeout = TimeSpan.Zero;
239+
Logger.Debug("Disposing RavenDB server");
240+
EmbeddedServer.Instance.Dispose();
241+
Logger.Debug("Disposed RavenDB server");
242+
}
243+
182244
shutdownTokenSource.Dispose();
183245
applicationStoppingRegistration.Dispose();
184246

@@ -213,6 +275,7 @@ static long DataSize(EmbeddedDatabaseConfiguration configuration)
213275
{
214276
return -1;
215277
}
278+
216279
return info.Length;
217280
}
218281
catch
@@ -262,6 +325,7 @@ static long DirSize(DirectoryInfo d)
262325
readonly EmbeddedDatabaseConfiguration configuration;
263326
readonly CancellationToken shutdownCancellationToken;
264327
readonly CancellationTokenRegistration applicationStoppingRegistration;
328+
ServerOptions? serverOptions;
265329

266330
static TimeSpan delayBetweenRestarts = TimeSpan.FromSeconds(60);
267331
static readonly ILog Logger = LogManager.GetLogger<EmbeddedDatabase>();

0 commit comments

Comments
 (0)