mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: user friendly timeout handling changes (#1021)
* fn: user friendly timeout handling changes Timeout setting in routes now means "maximum amount of time a function can run in a container". Total wait time for a given http request is now expected to be handled by the client. As long as the client waits, the LB, runner or agents will search for resources to schedule it.
This commit is contained in:
@@ -254,40 +254,36 @@ func (a *agent) GetCall(opts ...CallOpt) (Call, error) {
|
||||
}
|
||||
|
||||
mem := c.Memory + uint64(c.TmpFsSize)
|
||||
|
||||
if !a.resources.IsResourcePossible(mem, uint64(c.CPUs), c.Type == models.TypeAsync) {
|
||||
// if we're not going to be able to run this call on this machine, bail here.
|
||||
return nil, models.ErrCallTimeoutServerBusy
|
||||
}
|
||||
|
||||
err := setMaxBodyLimit(&a.cfg, &c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setupCtx(&c)
|
||||
|
||||
c.da = a.da
|
||||
c.ct = a
|
||||
|
||||
ctx, _ := common.LoggerWithFields(c.req.Context(),
|
||||
logrus.Fields{"id": c.ID, "app_id": c.AppID, "route": c.Path})
|
||||
c.req = c.req.WithContext(ctx)
|
||||
|
||||
c.stderr = setupLogger(ctx, a.cfg.MaxLogSize, c.Call)
|
||||
c.stderr = setupLogger(c.req.Context(), a.cfg.MaxLogSize, c.Call)
|
||||
if c.w == nil {
|
||||
// send STDOUT to logs if no writer given (async...)
|
||||
// TODO we could/should probably make this explicit to GetCall, ala 'WithLogger', but it's dupe code (who cares?)
|
||||
c.w = c.stderr
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
slotDeadline := now.Add(time.Duration(c.Call.Timeout) * time.Second / 2)
|
||||
execDeadline := now.Add(time.Duration(c.Call.Timeout) * time.Second)
|
||||
|
||||
c.slotDeadline = slotDeadline
|
||||
c.execDeadline = execDeadline
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func setupCtx(c *call) {
|
||||
ctx, _ := common.LoggerWithFields(c.req.Context(),
|
||||
logrus.Fields{"id": c.ID, "app_id": c.AppID, "route": c.Path})
|
||||
c.req = c.req.WithContext(ctx)
|
||||
}
|
||||
|
||||
func setMaxBodyLimit(cfg *AgentConfig, c *call) error {
|
||||
if cfg.MaxRequestSize > 0 && c.req.ContentLength > 0 && uint64(c.req.ContentLength) > cfg.MaxRequestSize {
|
||||
return models.ErrRequestContentTooBig
|
||||
@@ -310,16 +306,10 @@ type call struct {
|
||||
stderr io.ReadWriteCloser
|
||||
ct callTrigger
|
||||
slots *slotQueue
|
||||
slotDeadline time.Time
|
||||
lbDeadline time.Time
|
||||
execDeadline time.Time
|
||||
requestState RequestState
|
||||
containerState ContainerState
|
||||
slotHashId string
|
||||
}
|
||||
|
||||
func (c *call) LbDeadline() time.Time {
|
||||
return c.lbDeadline
|
||||
isLB bool
|
||||
}
|
||||
|
||||
func (c *call) SlotHashId() string {
|
||||
@@ -358,8 +348,7 @@ func (c *call) Start(ctx context.Context) error {
|
||||
c.StartedAt = strfmt.DateTime(time.Now())
|
||||
c.Status = "running"
|
||||
|
||||
// Do not write this header if lb-agent
|
||||
if c.lbDeadline.IsZero() {
|
||||
if !c.isLB {
|
||||
if rw, ok := c.w.(http.ResponseWriter); ok { // TODO need to figure out better way to wire response headers in
|
||||
rw.Header().Set("XXX-FXLB-WAIT", time.Time(c.StartedAt).Sub(time.Time(c.CreatedAt)).String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user