Updated Writing a Plugin: Server Type (markdown)

Matt Holt 2016-07-18 16:14:03 -06:00
parent 915b9436f4
commit 1162963413

@ -49,12 +49,28 @@ This is optional, but highly recommended in case you would rather not default to
Caddy tries to avoid as much global state as possible. When Caddy loads, parses, and executes a Caddyfile, it does so in a scope called an [Instance](https://godoc.org/github.com/mholt/caddy#Instance) so that a group of servers can be managed individually and multiple server types can be started in the same process.
Each time Caddy goes through this startup phase, it will create a new caddy.Instance and Caddy will ask your server type for a new [caddy.Context](https://godoc.org/github.com/mholt/caddy#Context) value so that it can execute your server's directives without sharing global state. Read the godoc for caddy.Context for more information.
Each time Caddy goes through this startup phase, it will create a new caddy.Instance and Caddy will ask your server type for a new [caddy.Context](https://godoc.org/github.com/mholt/caddy#Context) value so that it can execute your server's directives without sharing global state. Read the [godoc for caddy.Context](https://godoc.org/github.com/mholt/caddy#Context) for more information.
You should not store a a list of contexts with your server type; they will be stored with the Instance and are [accessible from Controllers](https://godoc.org/github.com/mholt/caddy#Controller.Context). Keeping references to contexts lying around will prevent them from being garbage collected if the server is stopped later.
You should _not_ store a a list of contexts with your server type; they will be stored with the Instance and are [accessible from Controllers](https://godoc.org/github.com/mholt/caddy#Controller.Context). Keeping references to contexts lying around will prevent them from being garbage collected if the server is stopped later, which is likely a memory leak.
Ultimately, your goal is to make it so that `MakeServers()` returns a list of servers that Caddy can use. How you do that is entirely up to you.
Ultimately, your goal is to make it so that `MakeServers()` returns a list of [caddy.Server](https://godoc.org/github.com/mholt/caddy#Server) values that Caddy can use. How you do that is entirely up to you.
For example: the HTTP server keeps a map of site configs in its context and has an exported function, `GetConfig(c Controller)` that gets a config for a certain site, designated by the [caddy.Controller](https://godoc.org/github.com/mholt/caddy#Controller) that is passed in. The config, in turn, stores the list of middleware, etc -- all the information needed to set up a site. Each directive's action calls the GetConfig function so they can help set up the site properly. By the time `MakeServers()` is called, all it has to do is combine those site configs into server instances and return them. (Server instances are types on which you can call `Listen()` and `Serve()`.)
For example: the HTTP server [uses its context type](https://github.com/mholt/caddy/blob/aede4ccbce94bcb67161674e30dd1bfa7296448c/caddyhttp/httpserver/plugin.go#L54-L63) to keep a map of site configs. The package also has an exported function, `GetConfig(c Controller)` that gets a config for a certain site, designated by the [caddy.Controller](https://godoc.org/github.com/mholt/caddy#Controller) that is passed in. The config, in turn, stores the list of middleware, etc -- all the information needed to set up a site. Each directive's action calls the GetConfig function so they can help set up the site properly. By the time `MakeServers()` is called, all it has to do is combine those site configs into server instances and return them. (Server instances implement [caddy.Server](https://godoc.org/github.com/mholt/caddy#Server).)
(TODO: We will expand this guide with more information...)
The caddy.Server interface has four methods; two are for TCP, two are for UDP or other:
```go
type Server interface {
// Required if using TCP
Listen() (net.Listener, error)
Serve(net.Listener) error
// Required if using UDP or other
ListenPacket() (net.PacketConn, error)
ServePacket(net.PacketConn) error
}
```
If your server only uses TCP, the `*Packet()` methods may be no-ops (i.e. they return `nil`). The inverse is true for non-TCP servers. A server may also use both TCP and UDP, and implement all four methods.
Once this interface is implemented and configuration is properly applied from Caddyfile directives, your server type is ready to roll. Put it under test and add it to the Caddy download page!