I have a multi-step process that calls back into a single Lambda on different intervals. On paper this seemed very clean, however, I found that rate-based scheduled events are invoked as soon, or soon after they are enabled, and then falls within the defined rate interval.
If an event is created with a schedule of "Rate(5 Minutes)" it will callback the assigned lambda within ~1-2 minute(s) and then follow the 5-minute callback cycle. This is not documented as far as I can tell. I have employed a nasty hack which is below. Is there a magic property I am oblivious to or is this the design?
Here, I hacked a callbackCount on the messages to ignore the first one. The frustrating part is that the initial callback seems to be anywhere 1 to even 4 minutes, or not at all, for a 5-minute timer which makes it kind of wonky.
def handle_and_skip_events_instant_start_callback(event):
# simply increment a count per event and ingnore the first call back as it can be
# called anytime after the event was enabled or put such a 1 minute or 4 minutes for a 5 minute timer
if event["callBackCount"] == 0:
# return false to ignore the event and place a new message with an incremented count
event["callBackCount"] = event["callBackCount"] + 1
events_client.put_targets(Rule = event["ruleName"],
Targets=[
{
'Id': "1",
'Arn': event["callbackFunctionArn"],
'Input': json.dumps(event, default=str)
}
]
)
return True
return False
def lambda_handler(event, context):
if event.get('callbackMessageId', None) == None:
start_replication_task(0, event, context)
return
# this is a callback from an event created for polling
if handle_and_skip_events_instant_start_callback(event):
#It is made so rate based scheduled events fire when they are
# enabled or within ~1 minute of being enabled. This means a 5 minute timed event could fire 25 seconds
# after created, afterwhich it would then ride on the schedule. Handle the awkward initial burst of the event here
return
if event["messageType"] == "task":
task_polling_callback_handler(event, context)
return
if event["messageType"] == "database":
database_polling_callback_handler(event, context)
return
if event["messageType"] == "stoptask":
stop_task_polling_callback_handler(event, context)
return
print("Error : Invalid callack message")
return 0
Are you using EventBridge scheduled rules or the new EventBridge scheduler service (https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduler.html)?
I recommend that you use EventBridge Scheduler to invoke targets on a schedule (https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html).