Skip to content

Commit 03bc8de

Browse files
committed
Add support for update with start workflow
closes #98
1 parent f321908 commit 03bc8de

97 files changed

Lines changed: 42929 additions & 10136 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.omni.yaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ up:
44
bufbuild/buf: 1.50.0
55
golangci/golangci-lint: 1.63.4
66
protocolbuffers/protobuf-go: 1.36.4
7-
temporalio/cli: 1.2.0
7+
temporalio/cli: 1.3.0
88
vektra/mockery: 2.52.4
99
- go-install:
1010
- github.com/alta/protopatch/cmd/protoc-gen-go-patch@v0.5.3
@@ -21,6 +21,11 @@ path:
2121
- .omni/bin
2222

2323
commands:
24+
docs:
25+
desc: Generate documentation
26+
run: |
27+
cd docs && npm run start
28+
2429
gen:
2530
desc: Generate code
2631
run: |
@@ -32,6 +37,17 @@ commands:
3237
mockery --log-level=error
3338
go mod tidy
3439
40+
genlocal:
41+
desc: Generate code locally
42+
run: |
43+
rm -rf ./gen/**
44+
buf dep update
45+
buf format -w
46+
buf lint
47+
buf generate --template buf.local.gen.yaml
48+
mockery --log-level=error
49+
go mod tidy
50+
3551
test:
3652
desc: Run tests
3753
run: |

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
### ⚠ BREAKING CHANGES
1111

1212
### Added
13+
- [#103](https://github.com/cludden/protoc-gen-go-temporal/pull/103) add support for experimental update with start
1314

1415
### Changed
1516

1617
### Fixed
18+
- [#103](https://github.com/cludden/protoc-gen-go-temporal/pull/103) support parsing files for signals, updates
19+
- [#103](https://github.com/cludden/protoc-gen-go-temporal/pull/103) fix input collision handling for signals, updates
20+
- [#103](https://github.com/cludden/protoc-gen-go-temporal/pull/103) fix race condition in xns activity cancellation
1721

1822

1923
# [1.16.1](https://github.com/cludden/protoc-gen-go-temporal/releases/tag/v1.16.1) - 2025-03-13

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
[![Docs](https://img.shields.io/badge/docs-learn_more-8f63ff)](https://cludden.github.io/protoc-gen-go-temporal/)
1111
[![GoDoc](https://godoc.org/github.com/cludden/protoc-gen-go-temporal?status.svg)](https://pkg.go.dev/github.com/cludden/protoc-gen-go-temporal)
1212
[![Buf](https://img.shields.io/badge/buf-cludden%2Fprotoc--gen--go--temporal-blue)](https://buf.build/cludden/protoc-gen-go-temporal)
13+
[![Static Badge for Temporal Code Exchange](https://img.shields.io/badge/Temporal-Code_Exchange_Featured-blue?style=flat-square&logo=temporal&labelColor=141414&color=444CE7)](https://temporal.io/code-exchange/go-code-generation-with-temporal-and-protobufs)
1314

1415
A protoc plugin for generating typed Temporal clients and workers in Go from protobuf schemas. This plugin allows Workflow authors to configure sensible defaults and guardrails, simplifies the implementation and testing of Temporal workers, and streamlines integration by providing typed client SDKs and a generated CLI application.
1516

@@ -65,7 +66,7 @@ Optional **CLI** with:
6566

6667

6768
Generated [Cross-Namespace (XNS)](#cross-namespace-xns) helpers: **[Experimental]**
68-
- with support for invoking a service's workflows, queries, signals, and updates from workflows in a different temporal namespace
69+
- with support for invoking a service's workflows, queries, signals, and updates from workflows in a different temporal namespace (or cluster)
6970

7071
Generated [Remote Codec Server](#codec) helpers
7172

buf.gen.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
version: v2
22
managed:
33
enabled: true
4+
disable:
5+
- module: buf.build/temporalio/api
46
override:
57
- file_option: go_package_prefix
68
value: github.com/cludden/protoc-gen-go-temporal/gen
@@ -9,13 +11,14 @@ plugins:
911
out: gen
1012
opt:
1113
- paths=source_relative
12-
- local: .omni/bin/protoc-gen-go_temporal
14+
- local: protoc-gen-go_temporal
1315
out: gen
1416
opt:
1517
- cli-categories=true
1618
- cli-enabled=true
1719
- docs-out=./proto/README.md
1820
- enable-codec=true
21+
- enable-debug-logging=true
1922
- enable-patch-support=true
2023
- enable-xns=true
2124
- ignore-acronyms=AWS;URN

buf.local.gen.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
version: v2
2+
managed:
3+
enabled: true
4+
disable:
5+
- module: buf.build/temporalio/api
6+
override:
7+
- file_option: go_package_prefix
8+
value: github.com/cludden/protoc-gen-go-temporal/gen
9+
plugins:
10+
- local: protoc-gen-go
11+
out: gen
12+
opt:
13+
- paths=source_relative
14+
- local: .omni/bin/protoc-gen-go_temporal
15+
out: gen
16+
opt:
17+
- cli-categories=true
18+
- cli-enabled=true
19+
- docs-out=./proto/README.md
20+
- enable-codec=true
21+
- enable-debug-logging=true
22+
- enable-patch-support=true
23+
- enable-xns=true
24+
- ignore-acronyms=AWS;URN
25+
- patches=64_ENABLED
26+
- paths=source_relative
27+
- workflow-update-enabled=true
28+
strategy: all
29+
inputs:
30+
- directory: examples
31+
- directory: proto
32+
- directory: test
33+
exclude_paths:
34+
- test/patch/proto/test/patch

buf.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,9 @@ deps:
1010
- name: buf.build/envoyproxy/protoc-gen-validate
1111
commit: daf171c6cdb54629b5f51e345a79e4dd
1212
digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de
13+
- name: buf.build/googleapis/googleapis
14+
commit: 28151c0d0a1641bf938a7672c500e01d
15+
digest: b5:93b70089baa4fc05a92d3e52db91a4b7812db3b57b9664f6cb301733938cb630e377a938e8a56779388171c749c1d42a2e9a6c6230f2ff45f127a8102a6a27d0
16+
- name: buf.build/temporalio/api
17+
commit: 0ad1e42d1b964db093c44b8a78ef102f
18+
digest: b5:e94b749ebd10ac9b22a8fd6f59fda3226719563cdfa215a5ce32e845a18bfb2714899bb57dd668178c7f6a96509748e980858eb5201b7ccfa0b2d269e5993cd6

buf.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ modules:
55
- path: examples/mutex/proto
66
- path: examples/schedule/proto
77
- path: examples/searchattributes/proto
8+
- path: examples/shoppingcart/proto
89
- path: examples/updatabletimer/proto
910
- path: examples/xns/proto
1011
- path: proto
@@ -22,12 +23,14 @@ modules:
2223
deps:
2324
- buf.build/alta/protopatch
2425
- buf.build/cludden/protoc-gen-go-temporal
26+
- buf.build/temporalio/api
2527
lint:
2628
use:
2729
- BASIC
2830
except:
2931
- FIELD_NOT_REQUIRED
3032
- PACKAGE_NO_IMPORT_CYCLE
33+
- PACKAGE_DIRECTORY_MATCH
3134
breaking:
3235
use:
3336
- FILE

docs/docs/configuration/update.mdx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ import TabItem from '@theme/TabItem';
55

66
[Updates](https://docs.temporal.io/workflows#update) are defined as Protobuf RPCs annotated with the [temporal.v1.update](https://buf.build/cludden/protoc-gen-go-temporal/docs/main:temporal.v1#temporal.v1.UpdateOptions) method option. They're mapped to workflows using the [update workflow option](/docs/configuration/workflow#update). See the [Updates guide](/docs/guides/queries) for more usage details.
77

8-
:::warning
9-
Updates are considered experimental. They can be enabled using the [workflow-update-enabled](/docs/configuration/plugin#options) plugin option. They are disabled by default.
10-
:::
11-
128
:::info
139
Update definitions can omit an input and/or out parameter by specifying the native `google.protobuf.Empty` message type in its place. This requires an additional `google/protobuf/empty.proto` protobuf import.
1410
:::

docs/docs/configuration/workflow.mdx

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -399,41 +399,57 @@ service Example {
399399
}
400400
```
401401

402-
### xns
402+
### wait_for_cancellation
403403

404-
[temporal.v1.XNSActivityOptions](https://buf.build/cludden/protoc-gen-go-temporal/docs/main:temporal.v1#temporal.v1.XNSActivityOptions)
404+
`bool`
405405

406-
Used to configure [cross-namespace](/docs/guides/xns) activity options.
406+
Whether to wait for canceled [child workflow](https://docs.temporal.io/workflows#child-workflow) to be ended (child workflow can be ended as: completed/failed/timedout/terminated/canceled). Defaults to `false`.
407407

408-
:::note
409-
This requires the [enable-xns](/docs/configuration/plugin#enable-xns) plugin option to be enabled.
410-
:::
408+
```protobuf
409+
service Example {
410+
rpc Hello(HelloInput) returns (HelloOutput) {
411+
option (temporal.v1.workflow) = {
412+
wait_for_cancellation: false
413+
};
414+
}
415+
}
416+
```
417+
418+
### workflow_id_conflict_policy
419+
420+
[temporal.api.enums.v1.WorkflowIdConflictPolicy](https://buf.build/temporalio/api/docs/master:temporal.api.enums.v1#temporal.api.enums.v1.WorkflowIdConflictPolicy)
421+
422+
Specifies the [Workflow ID conflict policy](https://docs.temporal.io/workflow-execution/workflowid-runid#workflow-id-conflict-policy) to use when starting a workflow. Defaults to `WORKFLOW_ID_CONFLICT_POLICY_FAIL`.
411423

412424
```protobuf
413425
service Example {
414426
rpc Hello(HelloInput) returns (HelloOutput) {
415427
option (temporal.v1.workflow) = {
416-
xns: {
417-
heartbeat_timeout: { seconds: 30 }
418-
heartbeat_interval: { seconds: 10 }
419-
start_to_close_timeout: { seconds: 300 }
420-
}
428+
workflow_id_conflict_policy: WORKFLOW_ID_CONFLICT_POLICY_FAIL
421429
};
422430
}
423431
}
424432
```
425433

426-
### wait_for_cancellation
434+
### xns
427435

428-
`bool`
436+
[temporal.v1.XNSActivityOptions](https://buf.build/cludden/protoc-gen-go-temporal/docs/main:temporal.v1#temporal.v1.XNSActivityOptions)
429437

430-
Whether to wait for canceled [child workflow](https://docs.temporal.io/workflows#child-workflow) to be ended (child workflow can be ended as: completed/failed/timedout/terminated/canceled). Defaults to `false`.
438+
Used to configure [cross-namespace](/docs/guides/xns) activity options.
439+
440+
:::note
441+
This requires the [enable-xns](/docs/configuration/plugin#enable-xns) plugin option to be enabled.
442+
:::
431443

432444
```protobuf
433445
service Example {
434446
rpc Hello(HelloInput) returns (HelloOutput) {
435447
option (temporal.v1.workflow) = {
436-
wait_for_cancellation: false
448+
xns: {
449+
heartbeat_timeout: { seconds: 30 }
450+
heartbeat_interval: { seconds: 10 }
451+
start_to_close_timeout: { seconds: 300 }
452+
}
437453
};
438454
}
439455
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import CodeBlock from '@theme/CodeBlock';
2+
import Proto from '!!raw-loader!../../../examples/shoppingcart/proto/example/shoppingcart/v1/shoppingcart.proto';
3+
import Implementation from '!!raw-loader!../../../examples/shoppingcart/workflows.go';
4+
import Main from '!!raw-loader!../../../examples/shoppingcart/cmd/shoppingcart/main.go';
5+
6+
7+
# Shopping Cart
8+
9+
A stateful shopping cart example demonstrating workflows with queries, signals, updates, and cross-namespace activities.
10+
11+
This example showcases:
12+
- **Stateful workflows** that maintain cart state across updates
13+
- **Queries** to inspect current cart contents
14+
- **Signals** to trigger checkout
15+
- **Updates** to modify cart contents with validation
16+
- **Cross-namespace execution** with update-with-start patterns
17+
- **Continue-as-new** handling for long-running workflows
18+
19+
<CodeBlock language="protobuf" title="shoppingcart.proto">{Proto}</CodeBlock>
20+
21+
<CodeBlock language="go" title="workflows.go">{Implementation}</CodeBlock>
22+
23+
<CodeBlock language="go" title="main.go">{Main}</CodeBlock>
24+
25+
26+
## Run this example
27+
28+
1. Clone the examples
29+
```sh
30+
git clone https://github.com/cludden/protoc-gen-go-temporal && cd protoc-gen-go-temporal
31+
```
32+
2. Run a local Temporal server
33+
```sh
34+
temporal server start-dev
35+
```
36+
3. Start the example workers
37+
```sh
38+
go run examples/shoppingcart/cmd/shoppingcart/main.go start
39+
```
40+
4. In a different shell, start a shopping cart workflow and add an item
41+
```sh
42+
go run examples/shoppingcart/cmd/shoppingcart/main.go shopping-cart-with-update-cart \
43+
--req='{}' \
44+
--update-cart-input='{"action": "UPDATE_CART_ACTION_ADD", "itemId": "apple"}' \
45+
-d
46+
```
47+
5. Query the cart contents
48+
```sh
49+
go run examples/shoppingcart/cmd/shoppingcart/main.go describe \
50+
-w <workflow-id-from-step-4>
51+
```
52+
6. Add more items using updates
53+
```sh
54+
go run examples/shoppingcart/cmd/shoppingcart/main.go update-cart \
55+
-w <workflow-id-from-step-4> \
56+
--input='{"action": "UPDATE_CART_ACTION_ADD", "itemId": "banana"}'
57+
```
58+
7. Checkout the cart (completes the workflow)
59+
```sh
60+
go run examples/shoppingcart/cmd/shoppingcart/main.go checkout \
61+
-w <workflow-id-from-step-4>
62+
```
63+
64+
## Key Features Demonstrated
65+
66+
### Stateful Workflow
67+
The `ShoppingCart` workflow maintains cart state across its execution, persisting item quantities in a map.
68+
69+
### Query Support
70+
The `Describe` query allows external inspection of the current cart state without affecting workflow execution.
71+
72+
### Signal Handling
73+
The `Checkout` signal triggers workflow completion, demonstrating asynchronous communication patterns.
74+
75+
### Update with Validation
76+
The `UpdateCart` update includes validation logic that prevents invalid operations (e.g., removing items not in the cart).
77+
78+
### Cross-Namespace Activities
79+
The example demonstrates cross-namespace execution patterns using update-with-start, allowing workflows to be initiated from different namespaces.
80+
81+
### Continue-as-New
82+
The workflow monitors for continue-as-new suggestions and handles them gracefully, ensuring long-running cart sessions don't hit history size limits.

0 commit comments

Comments
 (0)