Is there anyway to get notified on the application level when a Lambda function has completed? Currently I’m handling user photo uploads with S3 and then calling a Lambda to resize the photos which places them into another bucket with a “resized” prefix. As of right now when I do this sometimes I’m getting back a status of 403 from my “resized” bucket because the Lambda hasn’t completed. Is there a way to get the lambda to communicate back to my app and let it know exactly when the image has been created and successfully uploaded to the new bucket?
Just a few thoughts, have multiple callbacks as parameters, one that is called when it begins and one that is called at end? Or maybe add another lamda function that takes an event information object/summary and posts to a webhook on your server. Or just integrate that post webhook within the original lambda.
I have a similar process where uploaded audio files get transcoded to a different format. What you should consider is setting up an API endpoint for your app, that Lambda can notify when it’s done. I chose to use
However, if your app will react to Lambda by updating the database (and that’s it), I would strongly recommend you just have your Lambda function talk directly to your database instead, and let Meteor pick up the DB changes reactively. The reason for this is that if you push a code update while someone is using the Lambda functions, the Meteor app restart will make it unreachable when Lambda tries to hit the API endpoint.
I want to note that lamda functions cannot maintain a connection to mongodb, it cannot benefit from the db connection pool. Which is quite heavy with latency and processing compared the it just processing data and posting to a webhook or returning to a callback.
The availability issue becomes less once you have rolling updates with multiple instances in galaxy, but it is usually further addressed with a messaging queue, since disparate components can’t expect to rely on each other over the network
I’m not seeing how a webhook is better if the end goal is to just update the database? Rather than the chain being Lambda → Meteor → DB update, why not just Lambda → DB update? On a service like mLab or Compose, the DB change is replicated throughout the replica set, and then multiple Meteor instances on Galaxy will pick up the DB change.
It doesn’t need to. It just needs to connect, make an update, and close the DB connection. The Lambda function will run as long as it needs to, or until the Lambda process timeout is reached.
I understand, you are correct, it’s not necessary, and none of this matters on smaller scale probably.
It’s a pretty common topic with lambda on hackernews/aws groups, since Aws doesn’t support mongodb connection pooling in an optimized way. It may be coming to AWS down the road. Currently they recommend not using mongodb or to use the webhook/rest approach where another server that maintains the pool efficiently inserts the data for lamda.
If you do use a new connection each iteration in lamda, make sure you close the connection when it’s done. Again, I don’t think this as important at smaller scale, we had to investigate this when we had thousands of requests +, how to optimize. Depending on the connection, it can add several hundred - 1000ms to establish the connection to a replica set.
@ffxsam I’ll give you more a gist of what I’m trying to do.
Basically I’m saving information about a mp3 file that the user has just uploaded. On the client I am using Slingshot to send both the mp3, and a user uploaded image that will be associated with the mp3 to a S3 bucket. From there a Lambda that resizes the image gets trigged by the object creation event. The resized image is then re-uploaded to a different S3 bucket, and from there I call a Jquery event on the client to show the image. As of right now I’ve been estimating how long this whole process takes with a Meteor.setTimeout (it varies depending on image size, network etc, etc) and sometimes I’m getting a 403 status back from S3 because the object has not yet arrived.
In conclusion it looks like I should setup an api end-point and use that api to call the function that displays the image? I’d rather not have the lambda writing to the db. I appreciate the help.
There are a couple different ways. As @sbr464 mentioned, you could use a message queueing service like Amazon SQS (I have no experience with this firsthand), or you could just make an API call to your Meteor server using something like