AWS IoT Greengrass
Developer Guide

Test Long-Lived Lambda Functions

A long-lived Lambda function starts automatically when the AWS IoT Greengrass core starts and runs in a single container (or sandbox). Any variables or preprocessing that are defined outside of the function handler are retained for every invocation of the function handler. Multiple invocations of the function handler are queued until earlier invocations have been executed.

The following code is from greengrassHelloWorldCounter.py. (Code comments are removed for brevity.) This Lambda function is similar to the greengrassHelloWorld.py function from Part 1 of this module, but it defines a my_counter variable outside of the function handler.

import greengrasssdk import platform import time import json client = greengrasssdk.client('iot-data') my_platform = platform.platform() my_counter = 0 def function_handler(event, context): global my_counter my_counter = my_counter + 1 if not my_platform: client.publish( topic='hello/world/counter', payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core. Invocation Count: {}'.format(my_counter)}) ) else: client.publish( topic='hello/world/counter', payload=json.dumps({'message': 'Hello world! Sent from Greengrass Core running on platform: {}. Invocation Count: {}' .format(my_platform, my_counter)}) ) time.sleep(20) return

In this step, you create subscriptions that allow the Lambda function and AWS IoT to exchange MQTT messages. Then you deploy the group and test the function.

  1. On the group configuration page, choose Subscriptions, and then choose Add Subscription.

  2. Under Select a source, choose the Lambdas tab, and then choose Greengrass_HelloWorld_Counter.

  3. Under Select a target, choose the Services tab, choose IoT Cloud, and then choose Next.

    
                            Select your source and target screenshot with
                                Greengrass_HelloWorld_Counter, IoT Cloud, and the Next button
                                highlighted.
  4. For Topic filter, enter hello/world/counter. Choose Next, and then choose Finish.

    
                            Screenshot with hello/world/counter and the Next button
                                highlighted.

    This single subscription goes in one direction only: from the Greengrass_HelloWorld_Counter Lambda function to AWS IoT. To invoke (or trigger) this Lambda function from the cloud, you must create a subscription in the opposite direction.

  5. Follow steps 1 - 4 to add another subscription that uses the following values. This subscription allows the Lambda function to receive messages from AWS IoT. This subscription is exercised later when you send a test message to the function from the console.

    • For the source, choose Services, and then choose IoT Cloud.

    • For the target, choose Lambdas, and then choose Greengrass_HelloWorld_Counter.

    • For the topic filter, enter hello/world/counter/trigger.

     

    
                            Screenshot of the Confirm and save your Subscription page with
                                IoT Cloud, hello/world/counter/trigger,
                                Greengrass_HelloWorld_Counter, and Finish highlighted.

    The /trigger extension is used in this topic filter because you created two subscriptions and don't want them to interfere with each other.

  6. Make sure that the AWS IoT Greengrass daemon is running, as described in Deploy Cloud Configurations to a Core Device.

  7. On the group configuration page, from Actions, choose Deploy.

    
                Screenshot of the Group page with the Deploy action 
                    highlighted.

    This deploys the group configuration to your AWS IoT Greengrass core device. For troubleshooting help, see Troubleshooting AWS IoT Greengrass.

  8. After your deployment is complete, return to the AWS IoT Core console home page and choose Test.

  9. Configure the following fields:

    • For Subscription topic, enter hello/world/counter.

    • For Quality of Service, choose 0.

    • For MQTT payload display, choose Display payloads as strings.

     

    
                            Subscriptions screenshot with hello/world/counter, 0, Display
                                payloads as strings, and the Subscribe to topic button
                                highlighted.
  10. Choose Subscribe to topic.

    Unlike Part 1 of this module, you shouldn't see any messages after you subscribe to hello/world/counter. This is because the greengrassHelloWorldCounter.py code that publishes to the hello/world/counter topic is inside the function handler, which runs only when the function is invoked.

    In this module, you configured the Greengrass_HelloWorld_Counter Lambda function to be invoked when it receives an MQTT message on the hello/world/counter/trigger topic. You can see this by examining the related subscriptions:

    
                            Subscriptions webpage showing greengrass_HelloWorld_Counter
                                related subscriptions.

    The Greengrass_HelloWorld_Counter to IoT Cloud subscription allows the function to send messages to AWS IoT on the hello/world/counter topic. The IoT Cloud to Greengrass_HelloWorld_Counter subscription allows AWS IoT to send messages to the function on the hello/world/counter/trigger topic.

    Note

    Greengrass_HelloWorld_Counter ignores the content of received messages. It just runs the code in function_handler, which sends a message to the hello/world/counter topic. To review this code, see the greengrassHelloWorldCounter.py code listing.

  11. To test the long-lived lifecycle, invoke the Lambda function by publishing a message to the hello/world/counter/trigger topic. You can use the default message.

    
                            Default Hello from AWS IoT Core console message sent to
                                hello/world/counter/trigger with the Publish to topic button
                                highlighted.

Every time a message is published to the hello/world/counter/trigger topic, the my_counter variable is incremented. This invocation count is shown in the messages sent from the Lambda function. Because the function handler includes a 20-second sleep cycle (time.sleep(20)), repeatedly triggering the handler queues up responses from the AWS IoT Greengrass core.


                            Screenshot showing the incrementing of Invocation Count from 1,
                                2, and 3.