Fix webhook application hang on exit

* Import d9fee18b28 manually
This commit is contained in:
abraunegg 2023-10-28 07:21:54 +11:00
parent 16595efbdb
commit 4df36ffbbe
3 changed files with 61 additions and 16 deletions

View file

@ -680,6 +680,7 @@ final class ItemDatabase {
try {
auto stmt = db.prepare("VACUUM;");
stmt.exec();
log.vdebug("Database vacuum is complete");
} catch (SqliteException e) {
writeln();
log.error("ERROR: Unable to perform a database vacuum: " ~ e.msg);

View file

@ -898,28 +898,33 @@ int main(string[] cliArgs) {
void performStandardExitProcess(string scopeCaller) {
// Who called this function
log.vdebug("Running performStandardExitProcess due to: ", scopeCaller);
// Shutdown the database
if (itemDB !is null) {
// Make sure the .wal file is incorporated into the main db before we exit
itemDB.performVacuum();
object.destroy(itemDB);
}
// Wait for all parallel jobs that depend on the database to complete
log.vdebug("Wait for all parallel jobs that depend on the database to complete");
taskPool.finish(true);
// Shutdown the OneDrive API instance
if (oneDriveApiInstance !is null) {
log.vdebug("Shutdown OneDrive API instance");
oneDriveApiInstance.shutdown();
object.destroy(oneDriveApiInstance);
}
// Shutdown the sync engine
if (syncEngineInstance !is null) object.destroy(syncEngineInstance);
if (syncEngineInstance !is null) {
log.vdebug("Shutdown Sync Engine instance");
object.destroy(syncEngineInstance);
}
// Shutdown the client side filtering objects
if (selectiveSync !is null) object.destroy(selectiveSync);
if (selectiveSync !is null) {
log.vdebug("Shutdown Client Side Filtering instance");
object.destroy(selectiveSync);
}
// Shutdown the application configuration objects
if (appConfig !is null) {
log.vdebug("Shutdown Application Configuration instance");
// Cleanup any existing dry-run elements ... these should never be left hanging around
cleanupDryRunDatabaseFiles(appConfig.databaseFilePathDryRun);
object.destroy(appConfig);
@ -927,10 +932,22 @@ void performStandardExitProcess(string scopeCaller) {
// Shutdown any local filesystem monitoring
if (filesystemMonitor !is null) {
log.vdebug("Shutdown Filesystem Monitoring instance");
filesystemMonitor.shutdown();
object.destroy(filesystemMonitor);
}
// Shutdown the database
if (itemDB !is null) {
log.vdebug("Shutdown Database instance");
// Make sure the .wal file is incorporated into the main db before we exit
if (itemDB.isDatabaseInitialised()) {
itemDB.performVacuum();
}
object.destroy(itemDB);
}
// Set all objects to null
if (scopeCaller == "failureScope") {
// Set these to be null due to failure scope - prevent 'ERROR: Unable to perform a database vacuum: out of memory' when the exit scope is then called
log.vdebug("Setting Class Objects to null due to failure scope");

View file

@ -76,6 +76,7 @@ class OneDriveWebhook {
private ushort port;
private Tid parentTid;
private shared uint count;
private bool started;
static OneDriveWebhook getOrCreate(string host, ushort port, Tid parentTid) {
if (!instantiated_) {
@ -97,9 +98,23 @@ class OneDriveWebhook {
this.parentTid = parentTid;
this.count = 0;
}
void serve() {
spawn(&serveStatic);
this.started = true;
log.log("Started webhook server");
}
void stop() {
if (this.started) {
RequestServer.stop();
this.started = false;
}
log.log("Stopped webhook server");
}
// The static serve() is necessary because spawn() does not like instance methods
static serve() {
private static void serveStatic() {
// we won't create the singleton instance if it hasn't been created already
// such case is a bug which should crash the program and gets fixed
instance_.serveImpl();
@ -458,9 +473,20 @@ class OneDriveApi {
// Shutdown OneDrive API Curl Engine
void shutdown() {
// Delete subscription if there exists any
deleteSubscription();
try {
deleteSubscription();
} catch (OneDriveException e) {
logSubscriptionError(e);
}
// Shutdown webhook server if it is running
if (webhook !is null) {
webhook.stop();
object.destroy(webhook);
}
// Reset any values to defaults, freeing any set objects
curlEngine.http.clearRequestHeaders();
curlEngine.http.onSend = null;
@ -858,7 +884,7 @@ class OneDriveApi {
to!ushort(appConfig.getValueLong("webhook_listening_port")),
thisTid
);
spawn(&OneDriveWebhook.serve);
webhook.serve();
}
auto elapsed = Clock.currTime(UTC()) - subscriptionLastErrorAt;
@ -999,13 +1025,14 @@ class OneDriveApi {
private void deleteSubscription() {
if (!hasValidSubscription()) {
log.vdebug("No valid Microsoft OneDrive webhook subscription to delete");
return;
}
string url;
url = subscriptionUrl ~ "/" ~ subscriptionId;
del(url);
log.log("Deleted subscription");
performDelete(url);
log.vdebug("Deleted Microsoft OneDrive webhook subscription");
}
private void logSubscriptionError(OneDriveException e) {