Home > OS >  Lambda - DynamoDB Pattern
Lambda - DynamoDB Pattern

Time:11-01

I am creating a simple matchmaking system using Lambda and DynamoDB.

For simplicity, imagine a game where you can bet 1$, 2$, and 5$. And people get matched based on the matching stake they bet.

I have a lambda function called 'findGame', it does:

  1. Reads from DynamoDB and checks that there is not the same stake (if there is, then we match these 2 people (using WebSockets))
  2. If no matching stake, we insert in the table the stake and the player's info

Now here is the problem: This works fine, until you consider that lambda can run in parallel. When testing, I figured that if 2 people clicked on 'findGame' at approximately the same time, both reads from the db will return nothing, and I will have both records in the db, without actually matchmaking them.

My temporary solution is to use DynamoDB Stream, which transforms my architecture into the following:

  • Lambda function 'findGame': Inserts the record in the DB
  • DynamoDB Stream -> Lambda function 'matchmake' -> On 'INSERT', I read from DB if there is a matching stake to matchmake them, and since streams are successive, this kind of fixes my problem. However, I have this feeling that having this architecture is wrong, as streams are mainly used for logging.

CodePudding user response:

What you are looking for is conditional put.

In case you have multiple concurrent inserts one will succeed and the rest will fail, then you can handle the error.

Something like

client.putItem({
   TableName: "BettingGame",
   Item: {
     "PK": "user#john#bet#2",
     ...extra properties ...
   },
   ConditionExpression='attribute_not_exists(PK)'
})

Another option would be to use a transaction, but tey use 2x more capacity units.

  • Related