in cfn/scheduler/scheduler.go [73:130]
func (s *Scheduler) Reschedule(lambdaCtx context.Context, secsFromNow int64, callbackRequest string, invocationIDS *ScheduleIDS) (*Result, error) {
lc, hasValue := lambdacontext.FromContext(lambdaCtx)
if !hasValue {
return nil, cfnerr.New(ServiceInternalError, "Lambda Context has no value", errors.New("Lambda Context has no value"))
}
deadline, _ := lambdaCtx.Deadline()
secondsUnitDeadline := time.Until(deadline).Seconds()
if secsFromNow <= 0 {
err := errors.New("Scheduled seconds must be greater than 0")
return nil, cfnerr.New(ServiceInternalError, "Scheduled seconds must be greater than 0", err)
}
if secsFromNow < 60 && secondsUnitDeadline > float64(secsFromNow)*1.2 {
s.logger.Printf("Scheduling re-invoke locally after %v seconds, with Context %s", secsFromNow, string(callbackRequest))
time.Sleep(time.Duration(secsFromNow) * time.Second)
return &Result{ComputeLocal: true, IDS: *invocationIDS}, nil
}
// re-invoke through CloudWatchEvents no less than 1 minute from now.
if secsFromNow < 60 {
secsFromNow = 60
}
cr := GenerateOneTimeCronExpression(secsFromNow, time.Now())
s.logger.Printf("Scheduling re-invoke at %s \n", cr)
_, rerr := s.client.PutRule(&cloudwatchevents.PutRuleInput{
Name: aws.String(invocationIDS.Handler),
ScheduleExpression: aws.String(cr),
State: aws.String(cloudwatchevents.RuleStateEnabled),
})
if rerr != nil {
return nil, cfnerr.New(ServiceInternalError, "Schedule error", rerr)
}
_, perr := s.client.PutTargets(&cloudwatchevents.PutTargetsInput{
Rule: aws.String(invocationIDS.Handler),
Targets: []*cloudwatchevents.Target{
&cloudwatchevents.Target{
Arn: aws.String(lc.InvokedFunctionArn),
Id: aws.String(invocationIDS.Target),
Input: aws.String(string(callbackRequest)),
},
},
})
if perr != nil {
return nil, cfnerr.New(ServiceInternalError, "Schedule error", perr)
}
return &Result{ComputeLocal: false, IDS: *invocationIDS}, nil
}