Documentation

Overview

Package module defines a framework for extending server.Server with optional reusable bundles of functionality (called "modules", naturally).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Dependency

type Dependency struct {
	// contains filtered or unexported fields
}

Dependency represents a dependency on a module.

It can be either required or optional. If a module A declares a require dependency on another module B, then A cannot function without B at all. Also B will be initialized before A.

If the dependency on B is optional, A will start even if B is not present. But if B is present, it will be initialized before A.

Dependency cycles result in an undefined order of initialization.

func OptionalDependency

func OptionalDependency(dep Name) Dependency

OptionalDependency declares an optional dependency.

func RequiredDependency

func RequiredDependency(dep Name) Dependency

Required declares a required dependency.

func (Dependency) Dependency

func (d Dependency) Dependency() Name

Dependency is the name of a module to depend on.

func (Dependency) Required

func (d Dependency) Required() bool

Required is true if this is a required dependency.

type Host

type Host interface {
	// ServiceRegistrar is a registrar that can be used to register gRPC services.
	ServiceRegistrar() grpc.ServiceRegistrar

	// Routes returns a router that servers HTTP requests hitting the main port.
	//
	// The module can use it to register additional request handlers.
	//
	// Note that users of server.Server can register more routers through
	// server.AddPort(...) and server.VirtualHost(...). Such application-specific
	// routers are not accessible to modules.
	Routes() *router.Router

	// RunInBackground launches the given callback in a separate goroutine right
	// before starting the serving loop.
	//
	// Should be used for background asynchronous activities like reloading
	// configs.
	//
	// All logs lines emitted by the callback are annotated with "activity" field
	// which can be arbitrary, but by convention has format "<namespace>.<name>",
	// where "luci" namespace is reserved for internal activities.
	//
	// The context passed to the callback is derived from the global server
	// context and it is canceled when the server is shutting down. It is expected
	// the goroutine will exit soon after the context is canceled.
	RunInBackground(activity string, f func(context.Context))

	// RegisterWarmup registers a callback that is run in server's ListenAndServe
	// right before the serving loop.
	//
	// It receives the global server context (including all customizations made
	// by the user code in server.Main). Intended for best-effort warmups: there's
	// no way to gracefully abort the server startup from a warmup callback.
	//
	// All module's essential initialization should happen in its Initialize
	// method instead. The downside is that Initialize runs before the user code
	// in server.Main and it can't depend on modifications done there.
	RegisterWarmup(cb func(context.Context))

	// RegisterCleanup registers a callback that is run in server's ListenAndServe
	// after the server exits the serving loop.
	//
	// It receives the global server context.
	RegisterCleanup(cb func(context.Context))

	// RegisterUnaryServerInterceptor registers an grpc.UnaryServerInterceptor
	// applied to all unary RPCs that hit the server.
	//
	// Interceptors are chained in order they are registered, which matches
	// the order of modules in the list of modules. The first registered
	// interceptor becomes the outermost.
	RegisterUnaryServerInterceptor(intr grpc.UnaryServerInterceptor)

	// RegisterCookieAuth registers an implementation of a cookie-based
	// authentication scheme.
	//
	// If there are multiple such schemes registered, the server will refuse to
	// start.
	RegisterCookieAuth(method auth.Method)
}

Host is part of server.Server API that modules are allowed to use during their initialization to inject useful functionality into the server.

TODO(vadimsh):

* Allow adding a middleware to the default middleware chain.

type HostOptions

type HostOptions struct {
	Prod         bool   // set when running in production (not on a dev workstation)
	GAE          bool   // set when running on Appengine, implies Prod
	CloudProject string // name of hosting Google Cloud Project if running in GCP
	CloudRegion  string // name of a hosting region (e.g. 'us-central1') if known
}

HostOptions are options the server was started with.

It is a subset of global server.Options that modules are allowed to use to tweak their behavior.

type Module

type Module interface {
	// Name is a name of this module for logs and dependency relations.
	//
	// Usually a package that implements the module registers module's name as
	// a public global variable (so other packages can refer to it) and this
	// method just returns it.
	Name() Name

	// Dependencies returns dependencies (required and optional) of this module.
	Dependencies() []Dependency

	// Initialize is called during the server startup after the core functionality
	// is initialized, but before the server enters the serving loop.
	//
	// The method receives the global server context and can return a derived
	// context which will become the new global server context. That way the
	// module may inject additional state into the context inherited by all
	// requests. If it returns nil, the server context won't be changed.
	//
	// The module may use the context (with all values available there) and the
	// given Host interface to register itself in various server systems. It must
	// not retain 'host': the object it points to becomes invalid after Initialize
	// finishes and using it causes panics. This is intentional.
	//
	// Modules are initialized sequentially in order they are registered. A module
	// observes effects of initialization of all prior modules, e.g. via
	// context.Context.
	//
	// An error causes the process to crash with the corresponding message.
	Initialize(ctx context.Context, host Host, opts HostOptions) (context.Context, error)
}

Module represents some optional part of a server.

It is generally a stateful object constructed from some configuration. It can be hooked to the server in server.New(...) or server.Main(...).

type Name

type Name struct {
	// contains filtered or unexported fields
}

Name is a name of a registered module.

Usually it is a full name of the go package that implements the module, but it can be arbitrary as long as it is unique within a server. Attempting to register two identical names results in a panic during the server startup.

Names are usually registered during init-time via RegisterName and stored as global variables, so they can be referred to in Dependencies() implementation of other modules.

func RegisterName

func RegisterName(name string) Name

RegisterName registers a module name and returns it.

It's the only way to construct new Name instances. Panics if such name was already registered.

func (Name) String

func (n Name) String() string

String returns the name string.

Source Files