diff --git a/api/models/runner_pool.go b/api/models/runner_pool.go new file mode 100644 index 000000000..bcb3dfd26 --- /dev/null +++ b/api/models/runner_pool.go @@ -0,0 +1,31 @@ +package models + +import ( + "context" + "io" + "net/http" + "time" +) + +// RunnerPool is the abstraction for getting an ordered list of runners to try for a call +type RunnerPool interface { + Runners(call RunnerCall) ([]Runner, error) + Shutdown() error +} + +// Runner is the interface to invoke the execution of a function call on a specific runner +type Runner interface { + TryExec(ctx context.Context, call RunnerCall) (bool, error) + Close() error + Address() string +} + +// RunnerCall provides access to the necessary details of request in order for it to be +// processed by a RunnerPool +type RunnerCall interface { + SlotDeadline() time.Time + Request() *http.Request + ResponseWriter() io.Writer + StdErr() io.ReadWriteCloser + Model() *Call +} diff --git a/api/server/server.go b/api/server/server.go index 45e8a6cf2..bd54d3481 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -113,6 +113,7 @@ type Server struct { rootMiddlewares []fnext.Middleware apiMiddlewares []fnext.Middleware promExporter *prometheus.Exporter + runnerPool models.RunnerPool // Extensions can append to this list of contexts so that cancellations are properly handled. extraCtxs []context.Context } @@ -842,6 +843,12 @@ func (s *Server) Datastore() models.Datastore { return s.datastore } +// WithRunnerPool provides an extension point for overriding +// the default runner pool implementation when running in load-balanced mode +func (s *Server) WithRunnerPool(runnerPool models.RunnerPool) { + s.runnerPool = runnerPool +} + // returns the unescaped ?cursor and ?perPage values // pageParams clamps 0 < ?perPage <= 100 and defaults to 30 if 0 // ignores parsing errors and falls back to defaults. diff --git a/fnext/setup.go b/fnext/setup.go index 536cc3e71..99f23ae23 100644 --- a/fnext/setup.go +++ b/fnext/setup.go @@ -38,6 +38,9 @@ type ExtServer interface { // AddRouteEndpoint adds an endpoints to /v1/apps/:app/routes/:route/x AddRouteEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request, app *models.App, route *models.Route)) + // WithRunnerPool overrides the default runner pool implementation when running in load-balanced mode + WithRunnerPool(runnerPool models.RunnerPool) + // Datastore returns the Datastore Fn is using Datastore() models.Datastore }