HTTP Triggers hookup (#1086)

* Initial suypport for invoking tiggers

* dupe method

* tighten server constraints

* runner tests not working yet

* basic route tests passing

* post rebase fixes

* add hybrid support for trigger invoke and tests

* consoloidate all hybrid evil into one place

* cleanup and make triggers unique by source

* fix oops with Agent

* linting

* review fixes
This commit is contained in:
Owen Cliffe
2018-07-05 18:56:07 +01:00
committed by Reed Allman
parent b07a000a18
commit b8b544ed25
38 changed files with 2208 additions and 865 deletions

View File

@@ -88,24 +88,11 @@ type Agent interface {
io.Closer
AddCallListener(fnext.CallListener)
// Enqueue is to use the agent's sweet sweet client bindings to remotely
// queue async tasks and should be removed from Agent interface ASAP.
Enqueue(context.Context, *models.Call) error
// GetAppID is to get the match of an app name to its ID
GetAppID(ctx context.Context, appName string) (string, error)
// GetAppByID is to get the app by ID
GetAppByID(ctx context.Context, appID string) (*models.App, error)
// GetRoute is to get the route by appId and path
GetRoute(ctx context.Context, appID string, path string) (*models.Route, error)
}
type agent struct {
cfg AgentConfig
da DataAccess
da CallHandler
callListeners []fnext.CallListener
driver drivers.Driver
@@ -121,12 +108,15 @@ type agent struct {
disableAsyncDequeue bool
callOverrider CallOverrider
// deferred actions to call at end of initialisation
onStartup []func()
}
// AgentOption configures an agent at startup
type AgentOption func(*agent) error
// New creates an Agent that executes functions locally as Docker containers.
func New(da DataAccess, options ...AgentOption) Agent {
func New(da CallHandler, options ...AgentOption) Agent {
cfg, err := NewAgentConfig()
if err != nil {
@@ -137,6 +127,10 @@ func New(da DataAccess, options ...AgentOption) Agent {
cfg: *cfg,
}
a.shutWg = common.NewWaitGroup()
a.da = da
a.slotMgr = NewSlotQueueMgr()
// Allow overriding config
for _, option := range options {
err = option(a)
@@ -151,24 +145,31 @@ func New(da DataAccess, options ...AgentOption) Agent {
a.driver = NewDockerDriver(&a.cfg)
}
a.da = da
a.slotMgr = NewSlotQueueMgr()
a.resources = NewResourceTracker(&a.cfg)
a.shutWg = common.NewWaitGroup()
// TODO assert that agent doesn't get started for API nodes up above ?
if a.disableAsyncDequeue {
return a
for _, sup := range a.onStartup {
sup()
}
if !a.shutWg.AddSession(1) {
logrus.Fatalf("cannot start agent, unable to add session")
}
go a.asyncDequeue() // safe shutdown can nanny this fine
return a
}
func (a *agent) addStartup(sup func()) {
a.onStartup = append(a.onStartup, sup)
}
// WithAsync Enables Async operations on the agent
func WithAsync(dqda DequeueDataAccess) AgentOption {
return func(a *agent) error {
if !a.shutWg.AddSession(1) {
logrus.Fatalf("cannot start agent, unable to add session")
}
a.addStartup(func() {
go a.asyncDequeue(dqda) // safe shutdown can nanny this fine
})
return nil
}
}
func WithConfig(cfg *AgentConfig) AgentOption {
return func(a *agent) error {
a.cfg = *cfg
@@ -176,7 +177,7 @@ func WithConfig(cfg *AgentConfig) AgentOption {
}
}
// Provide a customer driver to agent
// WithDockerDriver Provides a customer driver to agent
func WithDockerDriver(drv drivers.Driver) AgentOption {
return func(a *agent) error {
if a.driver != nil {
@@ -188,14 +189,7 @@ func WithDockerDriver(drv drivers.Driver) AgentOption {
}
}
func WithoutAsyncDequeue() AgentOption {
return func(a *agent) error {
a.disableAsyncDequeue = true
return nil
}
}
// Agents can use this to register a CallOverrider to modify a Call and extensions
// WithCallOverrider registers register a CallOverrider to modify a Call and extensions on call construction
func WithCallOverrider(fn CallOverrider) AgentOption {
return func(a *agent) error {
if a.callOverrider != nil {
@@ -206,7 +200,7 @@ func WithCallOverrider(fn CallOverrider) AgentOption {
}
}
// Create a default docker driver from agent config
// NewDockerDriver creates a default docker driver from agent config
func NewDockerDriver(cfg *AgentConfig) *docker.DockerDriver {
return docker.NewDocker(drivers.Config{
DockerNetworks: cfg.DockerNetworks,
@@ -221,23 +215,6 @@ func NewDockerDriver(cfg *AgentConfig) *docker.DockerDriver {
})
}
func (a *agent) GetAppByID(ctx context.Context, appID string) (*models.App, error) {
return a.da.GetAppByID(ctx, appID)
}
func (a *agent) GetAppID(ctx context.Context, appName string) (string, error) {
return a.da.GetAppID(ctx, appName)
}
func (a *agent) GetRoute(ctx context.Context, appID string, path string) (*models.Route, error) {
return a.da.GetRoute(ctx, appID, path)
}
// TODO shuffle this around somewhere else (maybe)
func (a *agent) Enqueue(ctx context.Context, call *models.Call) error {
return a.da.Enqueue(ctx, call)
}
func (a *agent) Close() error {
var err error
@@ -251,12 +228,6 @@ func (a *agent) Close() error {
}
})
// shutdown any db/queue resources
// associated with DataAccess
daErr := a.da.Close()
if daErr != nil {
return daErr
}
return err
}
@@ -856,7 +827,7 @@ func (a *agent) runHot(ctx context.Context, call *call, tok ResourceToken, state
state.UpdateState(ctx, ContainerStateStart, call.slots)
defer state.UpdateState(ctx, ContainerStateDone, call.slots)
container, closer := NewHotContainer(ctx, call, &a.cfg)
container, closer := newHotContainer(ctx, call, &a.cfg)
defer closer()
logger := logrus.WithFields(logrus.Fields{"id": container.id, "app_id": call.AppID, "route": call.Path, "image": call.Image, "memory": call.Memory, "cpus": call.CPUs, "format": call.Format, "idle_timeout": call.IdleTimeout})
@@ -1041,7 +1012,8 @@ type container struct {
stats *drivers.Stats
}
func NewHotContainer(ctx context.Context, call *call, cfg *AgentConfig) (*container, func()) {
//newHotContainer creates a container that can be used for multiple sequential events
func newHotContainer(ctx context.Context, call *call, cfg *AgentConfig) (*container, func()) {
// if freezer is enabled, be consistent with freezer behavior and
// block stdout and stderr between calls.
isBlockIdleIO := MaxDisabledMsecs != cfg.FreezeIdle