Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Entity Orchestration Example

This example demonstrates using Durable Entities from within orchestrations, including entity locking for atomic operations.

What You'll Learn

This example demonstrates:

  • Calling entities from orchestrations (request/response)
  • Signaling entities from orchestrations (fire-and-forget)
  • Entity locking / Critical sections for atomic operations across multiple entities

Scenario

A bank transfer between two accounts (entities). We use entity locking to ensure the transfer is atomic - both the withdrawal and deposit happen together, or neither happens.

Prerequisites

You need a Durable Task-compatible backend. Choose one:

Option 1: DTS Emulator (Recommended for testing)

docker run --name dts-emulator -i -p 8080:8080 -d --rm mcr.microsoft.com/dts/dts-emulator:latest

Option 2: Local Sidecar

Install and run the Durable Task Sidecar or Dapr CLI on localhost:4001.

Running the Example

With DTS Emulator

npm run start:emulator

With Local Sidecar

npm run start

Expected Output

Connecting to endpoint: localhost:8080, taskHub: default
Worker started successfully

--- Initializing accounts ---
Alice balance: 1000
Bob balance: 500

--- Running transfer orchestration ---
Transfer orchestration started: [instance-id]
In critical section: true
Locked entities: BankAccount@alice, BankAccount@bob
From account balance: 1000
To account balance: 500
Transfer completed: {"success":true,"fromBalance":750,"toBalance":750,"message":"Transferred 250 from alice to bob"}

--- Final balances ---
Alice balance: 750
Bob balance: 750

--- Cleaning up ---
Worker stopped

Key Concepts

Entity Locking

Entity locking ensures that multiple entities can be locked together for atomic operations:

const lock: LockHandle = yield* ctx.entities.lockEntities(fromEntity, toEntity);
try {
  // Perform atomic operations
  yield* ctx.entities.callEntity(fromEntity, "withdraw", amount);
  yield* ctx.entities.callEntity(toEntity, "deposit", amount);
} finally {
  lock.release();
}

This prevents race conditions when multiple orchestrations try to access the same entities concurrently.