-
Notifications
You must be signed in to change notification settings - Fork 10
Durable Entities Support #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 69 commits
Commits
Show all changes
89 commits
Select commit
Hold shift + click to select a range
c342a89
Initial plan
Copilot b3b5a40
Add Durable Task Scheduler support for Azure-managed orchestration
Copilot 8ad77cd
Improve type safety in scheduler module based on code review
Copilot 1a727d8
Rename scheduler to azuremanaged and move to separate npm package
Copilot 1e79da0
Exclude packages from root jest configuration
Copilot 79d0d30
Fix grammar in error messages for connection string validation
Copilot e8edf4b
Rename packages to extensions and update package name to durabletask-…
Copilot 7823521
Fix typo in jest.config.js comment
Copilot 5905636
Add .npmignore to exclude extensions folder from main package
Copilot ca517d4
save
YunchuWang f953166
same eslint
YunchuWang 8ad398c
save
YunchuWang 4877a34
workerid
YunchuWang 7bbcb5e
save
YunchuWang 676d25e
save
YunchuWang feac6f9
save
YunchuWang 0426630
save
YunchuWang 5523d00
save
YunchuWang 79ee784
save
YunchuWang 77a5d32
align clientretryoptions
YunchuWang fb3a468
add code ref
YunchuWang 22381a4
test sample
YunchuWang 422c39c
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang b3b0105
save
YunchuWang ca901ac
fix incorrect grpc gen script
YunchuWang bb357c4
save
YunchuWang ed357b4
add completion token
YunchuWang 5857ea4
update sample
YunchuWang cb763d9
use default messagesize
YunchuWang 4995519
make output folder consistent
YunchuWang 8bd1ed8
use files instead of npmignore for cleaner packaging
YunchuWang 017e839
multipackage workspace layout
YunchuWang 8cca56c
cleanup
YunchuWang f13f7c7
update pr ci
YunchuWang b14e95a
fix e2e tests
YunchuWang 0048b8b
fix codeql
YunchuWang b7ee967
codeql
YunchuWang 9327d09
step 1
YunchuWang ba31622
add to json
YunchuWang b4a38f9
step 2
YunchuWang a9d5acf
step 3
YunchuWang ba6e062
step 4
YunchuWang 3dcc52c
step 5
YunchuWang 55e52d1
step 6
YunchuWang e5d9754
step 7
YunchuWang 5a8a4f3
step 8
YunchuWang 6d4d6cf
step 10
YunchuWang a50a281
step 11
YunchuWang 225d12e
add sample/update readme
YunchuWang e5499e3
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang c46fded
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang a94d177
cleanup
YunchuWang 7dd8222
fix import
YunchuWang 782a342
cleanup
YunchuWang 018e20a
linting
YunchuWang ab5604c
cleanup
YunchuWang 97b2a10
save
YunchuWang 7526f6c
save
YunchuWang 67a6239
test fix
YunchuWang 600b386
more entity e2e tests
YunchuWang 0e2edb3
locking tests
YunchuWang c406c12
more tests
YunchuWang 97c34e6
linting
YunchuWang 2e01158
test supporting real dts
YunchuWang 2da8a06
cleanup
YunchuWang 54b9183
test update
YunchuWang 5570512
getentities advanced async page iteration
YunchuWang 026b7b7
set parentexecutionid when callentity
YunchuWang 4f1f2b3
failure test
YunchuWang cd27ac4
remove commitactions
YunchuWang 4363151
fix unittest
YunchuWang 3fb9198
Update examples/hello-world/entity-counter.ts
YunchuWang b0c1eb0
Restructure entity examples as standalone apps with DTS emulator supp…
Copilot 9c07ea8
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang a7a1d91
Refactor entity locking and orchestration execution logic; improve te…
YunchuWang bcfb899
Rename pagination method from byPage() to asPages() in entity tests
YunchuWang f4e45fc
Adjust time window for orchestration scheduling to account for clock …
YunchuWang b21c23d
Fix eslint directive for empty interface in CallEntityOptions
YunchuWang 90556b4
revert codeql for separate pr
YunchuWang 6ff0bdd
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang 88c69a6
Remove CodeQL workflow configuration
YunchuWang 5b3588e
Enhance entity operation logging and tracing support
YunchuWang 48bf20a
Update entity-specific event IDs to start from 800 for better organiz…
YunchuWang 2b45c8c
Merge branch 'main' of https://github.com/microsoft/durabletask-js in…
YunchuWang 746ebcd
Refactor operation execution to improve input parsing and detail setting
YunchuWang 123c968
Enhance method lookup to support multi-level inheritance in TaskEntity
YunchuWang 2d29ade
Clarify default implementation of initializeState to handle non-objec…
YunchuWang 2550867
Add error handling for JSON serialization in TaskHubGrpcClient and St…
YunchuWang 927f580
add more tests
YunchuWang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| /** | ||
| * This example demonstrates a simple Counter entity using Durable Entities. | ||
| * | ||
| * Durable Entities are stateful objects that can be addressed by a unique ID. | ||
| * They process operations one at a time, ensuring consistency without explicit locks. | ||
| * | ||
| * Key concepts demonstrated: | ||
| * - Defining an entity with TaskEntity<TState> | ||
| * - Entity operations (add, get, reset) | ||
| * - Signaling entities from a client (fire-and-forget) | ||
| * - Getting entity state from a client | ||
| */ | ||
|
|
||
| import { TaskHubGrpcClient } from "../../packages/durabletask-js/src/client/client"; | ||
| import { TaskHubGrpcWorker } from "../../packages/durabletask-js/src/worker/task-hub-grpc-worker"; | ||
| import { TaskEntity, EntityInstanceId } from "../../packages/durabletask-js/src/entities"; | ||
|
|
||
| // ============================================================================ | ||
| // Step 1: Define the entity state type | ||
| // ============================================================================ | ||
|
|
||
| /** | ||
| * The state type for our Counter entity. | ||
| */ | ||
| interface CounterState { | ||
| value: number; | ||
| } | ||
|
|
||
| // ============================================================================ | ||
| // Step 2: Define the Counter entity class | ||
| // ============================================================================ | ||
|
|
||
| /** | ||
| * A simple counter entity that can be incremented, decremented, and reset. | ||
| * | ||
| * Operations are defined as public methods on the class. | ||
| * The operation name is the method name (case-insensitive). | ||
| */ | ||
| class CounterEntity extends TaskEntity<CounterState> { | ||
| /** | ||
| * Adds a value to the counter. | ||
| * @param amount - The amount to add (can be negative to subtract). | ||
| * @returns The new counter value. | ||
| */ | ||
| add(amount: number): number { | ||
| this.state.value += amount; | ||
| return this.state.value; | ||
| } | ||
|
|
||
| /** | ||
| * Gets the current counter value. | ||
| * @returns The current value. | ||
| */ | ||
| get(): number { | ||
| return this.state.value; | ||
| } | ||
|
|
||
| /** | ||
| * Resets the counter to zero. | ||
| */ | ||
| reset(): void { | ||
| this.state.value = 0; | ||
| } | ||
|
|
||
| /** | ||
| * Initializes the entity state when it's first created. | ||
| * @returns The initial state with value = 0. | ||
| */ | ||
| protected initializeState(): CounterState { | ||
| return { value: 0 }; | ||
| } | ||
| } | ||
|
|
||
| // ============================================================================ | ||
| // Step 3: Main - Set up worker and client, then interact with the entity | ||
| // ============================================================================ | ||
|
|
||
| (async () => { | ||
| const grpcServerAddress = "localhost:4001"; | ||
| const client = new TaskHubGrpcClient(grpcServerAddress); | ||
| const worker = new TaskHubGrpcWorker(grpcServerAddress); | ||
|
|
||
| // Register the entity with the worker | ||
| worker.addEntity("Counter", () => new CounterEntity()); | ||
|
|
||
| try { | ||
| await worker.start(); | ||
| console.log("Worker started successfully"); | ||
|
|
||
| // Create an entity ID - this identifies a specific counter instance | ||
| const counterId = new EntityInstanceId("Counter", "my-counter"); | ||
|
|
||
| // ======================================================================== | ||
| // Signal the entity (fire-and-forget operations) | ||
| // ======================================================================== | ||
|
|
||
| console.log("\n--- Signaling entity operations ---"); | ||
|
|
||
| // Signal the counter to add 5 (doesn't wait for result) | ||
| await client.signalEntity(counterId, "add", 5); | ||
| console.log("Signaled: add(5)"); | ||
|
|
||
| // Signal the counter to add 3 | ||
| await client.signalEntity(counterId, "add", 3); | ||
| console.log("Signaled: add(3)"); | ||
|
|
||
| // Signal the counter to add -2 (subtract) | ||
| await client.signalEntity(counterId, "add", -2); | ||
| console.log("Signaled: add(-2)"); | ||
|
|
||
| // Wait a moment for signals to be processed | ||
| await new Promise((resolve) => setTimeout(resolve, 2000)); | ||
|
|
||
| // ======================================================================== | ||
| // Get the entity state | ||
| // ======================================================================== | ||
|
|
||
| console.log("\n--- Getting entity state ---"); | ||
|
|
||
| const metadata = await client.getEntity<CounterState>(counterId); | ||
| if (metadata.exists) { | ||
| console.log(`Counter value: ${metadata.state?.value}`); | ||
| console.log(`Last modified: ${metadata.lastModifiedTime}`); | ||
| } else { | ||
| console.log("Entity does not exist yet"); | ||
| } | ||
|
|
||
| // ======================================================================== | ||
| // Reset and verify | ||
| // ======================================================================== | ||
|
|
||
| console.log("\n--- Resetting counter ---"); | ||
|
|
||
| await client.signalEntity(counterId, "reset"); | ||
| console.log("Signaled: reset()"); | ||
|
|
||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
|
||
| const afterReset = await client.getEntity<CounterState>(counterId); | ||
| console.log(`Counter value after reset: ${afterReset.state?.value}`); | ||
|
|
||
| // ======================================================================== | ||
| // Clean up | ||
| // ======================================================================== | ||
|
|
||
| console.log("\n--- Cleaning up ---"); | ||
| await worker.stop(); | ||
| console.log("Worker stopped"); | ||
|
|
||
| } catch (error) { | ||
| console.error("Error:", error); | ||
| await worker.stop(); | ||
| } | ||
| })(); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.