From 2716e272c1145ec40f94fed2a09a8a8ccea09a41 Mon Sep 17 00:00:00 2001 From: elcore Date: Sun, 18 Mar 2018 01:29:22 +0100 Subject: [PATCH] Purge event hooks after USR1 reload, fix #2044 (#2047) * caddy: Purge event hooks after USR1 reload * caddy: Remove event hook purge logging * caddy: Remove deleteEventHook * caddy: use old event hooks in case of an unsuccessful restart * caddy: implement restoreEventHooks --- plugins.go | 32 +++++++++++++++++++++++++++++++- sigtrap_posix.go | 8 ++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/plugins.go b/plugins.go index 75f10e47..b0011009 100644 --- a/plugins.go +++ b/plugins.go @@ -39,7 +39,7 @@ var ( // eventHooks is a map of hook name to Hook. All hooks plugins // must have a name. - eventHooks = sync.Map{} + eventHooks = &sync.Map{} // parsingCallbacks maps server type to map of directive // to list of callback functions. These aren't really @@ -271,6 +271,36 @@ func EmitEvent(event EventName, info interface{}) { }) } +// cloneEventHooks return a clone of the event hooks *sync.Map +func cloneEventHooks() *sync.Map { + c := &sync.Map{} + eventHooks.Range(func(k, v interface{}) bool { + c.Store(k, v) + return true + }) + return c +} + +// purgeEventHooks purges all event hooks from the map +func purgeEventHooks() { + eventHooks.Range(func(k, _ interface{}) bool { + eventHooks.Delete(k) + return true + }) +} + +// restoreEventHooks restores eventHooks with a provided *sync.Map +func restoreEventHooks(m *sync.Map) { + // Purge old event hooks + purgeEventHooks() + + // Restore event hooks + m.Range(func(k, v interface{}) bool { + eventHooks.Store(k, v) + return true + }) +} + // ParsingCallback is a function that is called after // a directive's setup functions have been executed // for all the server blocks. diff --git a/sigtrap_posix.go b/sigtrap_posix.go index cc65ccb4..a14f9d35 100644 --- a/sigtrap_posix.go +++ b/sigtrap_posix.go @@ -76,9 +76,17 @@ func trapSignalsPosix() { caddyfileToUse = newCaddyfile } + // Backup old event hooks + oldEventHooks := cloneEventHooks() + + // Purge the old event hooks + purgeEventHooks() + // Kick off the restart; our work is done _, err = inst.Restart(caddyfileToUse) if err != nil { + restoreEventHooks(oldEventHooks) + log.Printf("[ERROR] SIGUSR1: %v", err) }