mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user