Search code examples
aws-lambdaamazon-cloudwatchaws-event-bridge

Is there a more graceful way to ignore the initial event callback when schedule is Rate based


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   

Solution

  • 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).