IDEMPOTENCY

One Serverless Principle to Rule Them All

Moar Serverless!!! 2022

@AdrienneTacke

@AdrienneTacke

IDEMPOTENCY

-- One Serverless Principle to Rule Them All

Agenda

idempotency

Not a real word,

according to Merriam-Webster.

idempotent

idem路鈥媝o路鈥媡ent : relating to or being a mathematical quantity which when applied to itself under a given binary operation equals itself

Merriam-Webster

idempotent

i路鈥媎em路鈥媝o路鈥媡ent : unchanged when multiplied by itself

Random House Webster's

idempotency

i路鈥媎em路鈥媝o路鈥媡en路cy聽: characteristic that ensures when running an operation over and over, and given the same input, that the same output is achieved every single time.

Adrienne and other developers

"...when multiplied by itself"

"unchanged"

Great, what does

聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 have to do with good serverless architecture?

鈥 Curious Moar Serverless Attendee

Have you heard about the seven design principles of well-architected applications?

鈥 Me, Adrienne

seven design principles of well-architected applications*

* Source: https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/general-design-principles.html

馃П聽 Speedy, simple, singular

馃攢聽 Think concurrent requests, not total requests

馃檯馃徎鈥嶁檧锔徛 聽Share Nothing

馃捊聽 Assume no hardware affinity

聽馃殾聽 聽Orchestrate your application with state machines, not functions

馃摠聽 Use events to trigger transactions

鈽斅 聽Design for failures and Duplicates

seven design principles of well-architected applications*

* Source: https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/general-design-principles.html

馃П聽 Speedy, simple, singular

馃攢聽 Think concurrent requests, not total requests

馃檯馃徎鈥嶁檧锔徛 聽Share Nothing

馃捊聽 Assume no hardware affinity

聽馃殾聽 聽Orchestrate your application with state machines, not functions

馃摠聽 Use events to trigger transactions

鈽斅 聽Design for failures and Duplicates

Impossible without idempotency!

鈽斅 聽Design for failures and Duplicates

Failures

retries

lead to

.

retries

means

duplicates

can and will occur.

Implementing

Failures

lead to

.

retries

duplicates

If

exist,

is key to mitigate side effects.

idempotency

retries

means

can and will occur.

Implementing

Failures

lead to

.

retries

duplicates

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

side effects

What happens without idempotency?

Order 馃嵃

Order placed

Order processed

Adrienne

Adrienne

Website

Website

API

API

What happens without idempotency?

Adrienne enters tunnel

Adrienne exits tunnel

Network failure

Time

Adrienne

Adrienne

Website

Website

API

API

Adrienne exits tunnel

Network failure

What happens without idempotency?

Time

Adrienne

Adrienne

Website

Website

API

API

Adrienne exits tunnel

Adrienne sees error and resubmits order

Order 馃嵃

Order placed

Order processed

馃殮 Cake is on the way!

What happens without idempotency?

Time

Order 馃嵃

Order placed

Order processed

馃殮 Cake is on the way!

Adrienne

Adrienne

Website

Website

API

API

What happens without idempotency?

Adrienne sees error and resubmits order

Network failure

Order 馃嵃

Order placed

Order processed

Adrienne enters tunnel

Adrienne exits tunnel

馃殮 Also, this first cake is on the way!

Time

Surprise!

Order 馃嵃

Order placed

Order processed

馃殮 Cake is on the way!

Adrienne

Adrienne

Website

Website

API

API

What happens without idempotency?

Adrienne sees error and resubmits order

Network failure

Order 馃嵃

Order placed

Order processed

Adrienne enters tunnel

Adrienne exits tunnel

馃殮 Also, this first cake is on the way!

Time

Surprise!

side effect:

duplicate requests are considered valid requests

How do we apply idempotency?

How do we apply idempotency?

elements of idempotency

idempotency key

Generated by caller, unique identifier, captures intent

How do we apply idempotency?

idempotency key

idempotency layer

Generated by caller, unique identifier, captures intent

Acts like a filter,聽 decides what to do with a request

elements of idempotency

How do we apply idempotency?

idempotency key

idempotency layer

persistent storage

Generated by caller, unique identifier, captures intent

Acts like a filter,聽 decides what to do with a request

Stores state, "source of truth" for idempotency keys, list of checkpoints in retries

elements of idempotency

How do we apply idempotency?

idempotency key

idempotency layer

persistent storage

Stores state, "source of truth" for idempotency keys, list of checkpoints in retries

Acts like a filter,聽 decides what to do with a request

Generated by caller, unique identifier, captures intent

elements of idempotency

How do we apply idempotency?

Generate unique identifier

Adrienne

placeOrder(event) {
  const context = event.context;
  const message = event.data;
  const order = {
    id: context.eventId,
    timestamp: context.timestamp,
    cake: message.data 
    	? Buffer.from(message.data, 'base64').toString() 
    	: '',
    idempotencyKey: "cb3d3141-a229-6ce0-b005-eb832e2cdabc"
  };
  
  // Remaining request logic
}

"cb3d3141-a229-6ce0-b005-eb832e2cdabc"

placeOrder(event)

How do we apply idempotency?

Adrienne

placeOrder(event)

API

Persistent Store

Run placeOrder handler(event)

Initial Request

Get idempotency key (event)?

Nothing found

Set idempotency key + handler result

Response not received by client

How do we apply idempotency?

Adrienne

placeOrder(event)

API

Persistent Store

Run placeOrder handler(event)

Initial Request

Get idempotency key (event)?

Nothing found

Set idempotency key + handler result

Response not received by client

Subsequent requests
(retries)

Get idempotency key (event)?

Exists: return result from initial request

Response sent to client

placeOrder(event)

Idempotency libraries and tools

Idempotency libraries and tools

鉁 Features

  • Prevent multiple Lambda handler function executions on the same payload during a time window.
  • Reuse the same DynamoDB table to store idempotency state. Function name is added in addition to the idempotency key as a hash key.
  • Set expiration period for idempotency records.
  • Ensure Lambda handler returns the same result when called with the same payload.

Java, Python

# Idempotent decorator
from aws_lambda_powertools.utilities.idempotency import (
    DynamoDBPersistenceLayer, idempotent
)

persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")

@idempotent(persistence_store=persistence_layer)
def handler(event, context):
    payment = create_subscription_payment(
        user=event['user'],
        product=event['product_id']
    )
    ...
    return {
        "payment_id": payment.id,
        "message": "success",
        "statusCode": 200,
    }

馃攽 Idempotency Key

hash representation of entire event or specific configured subset of the event

馃捑 Persistent Storage

Amazon DynamoDB (only supported persistent storage layer for now)

Other great tools and libraries!

Stripe API - Supports idempotent requests and implements idempotency keys.

https://stripe.com/blog/idempotency

IdempotentAPI聽- Performs additional idempotency checks. NuGet package.

https://www.nuget.org/packages/IdempotentAPI

https://stripe.com/docs/api/idempotent_requests

Step Functions聽- Serverless orchestration service.

https://docs.aws.amazon.com/step-functions

https://www.dotnetnakama.com/blog/idempotency-for-fault-tolerant-web-apis

Durable Functions聽- Azure's serverless orchestration service.

https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview

IDEMPOTENCY

One Serverless Principle to Rule Them All

@AdrienneTacke

Thank you Moar Serverless!!!

One Serverless Principle to Rule Them All: Idempotency

By Adrienne Tacke

One Serverless Principle to Rule Them All: Idempotency

  • 132