Skip to content

Commit 98d561d

Browse files
committed
README
1 parent 12071e0 commit 98d561d

File tree

1 file changed

+101
-7
lines changed

1 file changed

+101
-7
lines changed

README.md

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,15 +1312,109 @@ affect calls activity code might make to functions on the `temporalio.activity`
13121312

13131313
### Nexus
13141314

1315-
⚠️ **Nexus support is currently at an experimental release stage. Backwards-incompatible changes are anticipated until a stable release of Nexus support is announced.** ⚠️
1316-
1317-
#### What is Nexus?
1315+
⚠️ **Nexus support is currently at an experimental release stage. Backwards-incompatible changes are anticipated until a stable release is announced.** ⚠️
1316+
1317+
[Nexus](https://github.com/nexus-rpc/) is a synchronous RPC protocol. Arbitrary duration operations that can respond
1318+
asynchronously are modeled on top of a set of pre-defined synchronous RPCs.
1319+
1320+
Temporal supports calling Nexus operations **from a workflow**. See https://docs.temporal.io/nexus. There is no support
1321+
currently for calling a Nexus operation from non-workflow code.
1322+
1323+
To get started quickly using Nexus with Temporal, see the Python Nexus sample:
1324+
https://github.com/temporalio/samples-python/tree/main/hello_nexus.
1325+
1326+
1327+
Two types of Nexus operation are supported, each using a decorator:
1328+
1329+
- `@temporalio.nexus.workflow_run_operation`: a Nexus operation that is backed by a Temporal workflow. The operation
1330+
handler you write will start the handler workflow and then respond with a token indicating that the handler workflow
1331+
is in progress. When the handler workflow completes, Temporal server will automatically deliver the result (success or
1332+
failure) to the caller workflow.
1333+
- `@nexusrpc.handler.sync_operation`: an operation that responds synchronously. It may be `def` or `async def` and it
1334+
may do network I/O, but it must respond within 10 seconds.
1335+
1336+
The following steps are an overview of the [Python Nexus sample](
1337+
https://github.com/temporalio/samples-python/tree/main/hello_nexus).
1338+
1339+
1. Create the caller and handler namespaces, and the Nexus endpoint. For example,
1340+
```
1341+
temporal operator namespace create --namespace my-handler-namespace
1342+
temporal operator namespace create --namespace my-caller-namespace
1343+
1344+
temporal operator nexus endpoint create \
1345+
--name my-nexus-endpoint \
1346+
--target-namespace my-handler-namespace \
1347+
--target-task-queue my-handler-task-queue
1348+
```
1349+
1350+
2. Define your service contract. This specifies the names and input/output types of your operations. You will use this
1351+
to refer to the operations when calling them from a workflow.
1352+
```python
1353+
@nexusrpc.service
1354+
class MyNexusService:
1355+
my_sync_operation: nexusrpc.Operation[MyInput, MyOutput]
1356+
my_workflow_run_operation: nexusrpc.Operation[MyInput, MyOutput]
1357+
```
1358+
1359+
3. Implement your operation handlers in a service handler:
1360+
```python
1361+
@service_handler(service=MyNexusService)
1362+
class MyNexusServiceHandler:
1363+
@sync_operation
1364+
async def my_sync_operation(
1365+
self, ctx: StartOperationContext, input: MyInput
1366+
) -> MyOutput:
1367+
return MyOutput(message=f"Hello {input.name} from sync operation!")
1368+
1369+
@workflow_run_operation
1370+
async def my_workflow_run_operation(
1371+
self, ctx: WorkflowRunOperationContext, input: MyInput
1372+
) -> nexus.WorkflowHandle[MyOutput]:
1373+
return await ctx.start_workflow(
1374+
WorkflowStartedByNexusOperation.run,
1375+
input,
1376+
id=str(uuid.uuid4()),
1377+
)
1378+
```
1379+
1380+
4. Register your service handler with a Temporal worker.
1381+
```python
1382+
client = await Client.connect("localhost:7233", namespace="my-handler-namespace")
1383+
worker = Worker(
1384+
client,
1385+
task_queue="my-handler-task-queue",
1386+
workflows=[WorkflowStartedByNexusOperation],
1387+
nexus_service_handlers=[MyNexusServiceHandler()],
1388+
)
1389+
await worker.run()
1390+
```
1391+
1392+
5. Call your Nexus operations from your caller workflow.
1393+
```python
1394+
@workflow.defn
1395+
class CallerWorkflow:
1396+
def __init__(self):
1397+
self.nexus_client = workflow.create_nexus_client(
1398+
service=MyNexusService, endpoint="my-nexus-endpoint"
1399+
)
13181400
1319-
[Nexus](https://github.com/nexus-rpc/) itself is a synchronous RPC protocol. Arbitrary duration operations that can
1320-
respond asynchronously are modeled on top of a set of pre-defined synchronous RPCs. The Temporal Python SDK supports
1321-
defining Nexus operations that can be called from a workflow.
1401+
@workflow.run
1402+
async def run(self, name: str) -> tuple[MyOutput, MyOutput]:
1403+
# Start the Nexus operation and wait for the result in one go, using execute_operation.
1404+
wf_result = await self.nexus_client.execute_operation(
1405+
MyNexusService.my_workflow_run_operation,
1406+
MyInput(name),
1407+
)
1408+
# Or alternatively, obtain the operation handle using start_operation,
1409+
# and then use it to get the result:
1410+
sync_operation_handle = await self.nexus_client.start_operation(
1411+
MyNexusService.my_sync_operation,
1412+
MyInput(name),
1413+
)
1414+
sync_result = await sync_operation_handle
1415+
return sync_result, wf_result
1416+
```
13221417
1323-
TODO
13241418
13251419
### Workflow Replay
13261420

0 commit comments

Comments
 (0)