Commit da674fd5 authored by Henrique Dias's avatar Henrique Dias Committed by Matt Holt

Introducing Event Hooks Plugins (#1537)

* add Hook

* update hooks

* remove parenthesis

* Update requests
parent 4e1229e7
......@@ -100,11 +100,8 @@ func Run() {
mustLogFatalf("%v", err)
}
// Execute plugins that are registered to run as the process starts
err = caddy.StartupHooks(serverType)
if err != nil {
mustLogFatalf("%v", err)
}
// Executes Startup events
caddy.EmitEvent(caddy.StartupEvent)
// Get Caddyfile input
caddyfileinput, err := caddy.LoadCaddyfile(serverType)
......
......@@ -2,6 +2,7 @@ package caddy
import (
"fmt"
"log"
"net"
"sort"
......@@ -21,6 +22,10 @@ var (
// must have a name.
plugins = make(map[string]map[string]Plugin)
// eventHooks is a map of hook name to Hook. All hooks plugins
// must have a name.
eventHooks = make(map[string]EventHook)
// parsingCallbacks maps server type to map of directive
// to list of callback functions. These aren't really
// plugins on their own, but are often registered from
......@@ -69,30 +74,6 @@ func DescribePlugins() string {
return str
}
// StartupHooks executes the startup hooks defined when the
// plugins were registered and returns the first error
// it encounters.
func StartupHooks(serverType string) error {
for stype, stypePlugins := range plugins {
if stype != "" && stype != serverType {
continue
}
for name := range stypePlugins {
if stypePlugins[name].StartupHook == nil {
continue
}
err := stypePlugins[name].StartupHook()
if err != nil {
return err
}
}
}
return nil
}
// ValidDirectives returns the list of all directives that are
// recognized for the server type serverType. However, not all
// directives may be installed. This makes it possible to give
......@@ -200,10 +181,6 @@ type Plugin struct {
// Action is the plugin's setup function, if associated
// with a directive in the Caddyfile.
Action SetupFunc
// StartupHook is the plugin's function that is executed
// immediately after the flag parsing.
StartupHook func() error
}
// RegisterPlugin plugs in plugin. All plugins should register
......@@ -228,6 +205,42 @@ func RegisterPlugin(name string, plugin Plugin) {
plugins[plugin.ServerType][name] = plugin
}
// EventName represents the name of an event used with event hooks.
type EventName string
const (
StartupEvent EventName = "startup"
ShutdownEvent EventName = "shutdown"
)
// EventHook is a type which holds information about a startup hook plugin.
type EventHook func(eventType EventName) error
// RegisterEventHook plugs in hook. All the hooks should register themselves
// and they must have a name.
func RegisterEventHook(name string, hook EventHook) {
if name == "" {
panic("event hook must have a name")
}
if _, dup := eventHooks[name]; dup {
panic("hook named " + name + " already registered")
}
eventHooks[name] = hook
}
// EmitEvent executes the different hooks passing the EventType as an
// argument. This is a blocking function. Hook developers should
// use 'go' keyword if they don't want to block Caddy.
func EmitEvent(event EventName) {
for name, hook := range eventHooks {
err := hook(event)
if err != nil {
log.Printf("error on '%s' hook: %v", name, err)
}
}
}
// ParsingCallback is a function that is called after
// a directive's setup functions have been executed
// for all the server blocks.
......
......@@ -52,6 +52,9 @@ func trapSignalsCrossPlatform() {
// This function is idempotent; subsequent invocations always return 0.
func executeShutdownCallbacks(signame string) (exitCode int) {
shutdownCallbacksOnce.Do(func() {
// execute third-party shutdown hooks
EmitEvent(ShutdownEvent)
errs := allShutdownCallbacks()
if len(errs) > 0 {
for _, err := range errs {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment