Repository navigation
Nexus V2 Documentation - don't review or merge!! #5068
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
Open
Evanthx
wants to merge
23
commits into
main
Choose a base branch
from
nexus-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
f03a571
Adding documentation for Nexus Client library code generation
Evanthx 0e5d395
Some proposed documentation. Do not merge, this is just for review.
Evanthx d556713
Updating links
Evanthx fe742db
Updating docs
Evanthx ad53b29
Unlisted the developer experience files
Evanthx 81a4993
Updated code generation doc page
Evanthx af31aaa
Updating
Evanthx 975116a
Wording change
Evanthx 3135daf
IDL doc update
Evanthx ff9cc15
Renaming from V2, working on SAA doc
Evanthx 48f7965
Working on operation handler doc
Evanthx ad1ba76
Working on docs
Evanthx e94962b
Update docs/encyclopedia/nexus/nexus.mdx
Evanthx d34a599
Update docs/encyclopedia/nexus/temporal-operation-handler.mdx
Evanthx a79be76
Responding to PR comments
Evanthx 4e54ed2
Updated walkthrough doc with sample Java code
Evanthx 02fae05
Updated some things
Evanthx c364ad4
moving pages
jsundai 319c604
change multipage to single page with tabbed component and highlightin…
jsundai c451fca
fix links
jsundai 75fe925
Updating after feedback
Evanthx 87488bd
Paring down to just the development walkthrough
Evanthx 7a10eb2
Updating the walkthrough
Evanthx 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
174 changes: 174 additions & 0 deletions
174
...develop/java/nexus/development-walkthrough/_steps/add-a-standalone-activity.mdx
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,174 @@ | ||
| import { RunThis } from '@site/src/components/elements/NexusMicroserviceWalkthrough'; | ||
|
|
||
| :::note Keep these running | ||
|
|
||
| This step uses the processes started earlier. Leave them running: | ||
|
|
||
| - The development server, from [step 4](/develop/java/nexus/development-walkthrough?step=implement#start-the-development-server). It must have been started with `activity.enableCallbacks=true`, or `notifyRequester` fails with `completion callbacks are not enabled for this namespace`. | ||
| - The handler Worker, from [step 4](/develop/java/nexus/development-walkthrough?step=implement#run-the-worker). | ||
| - The caller Worker, from [step 6](/develop/java/nexus/development-walkthrough?step=call#call-the-operations-from-a-caller-workflow). | ||
|
|
||
| ::: | ||
|
|
||
| The last Operation, `notifyRequester`, tells the requester whether their approval was `APPROVED` or `DENIED`. It is a single outbound notification with no state and nothing to wait for, so it is backed by a [Standalone Activity](/nexus/standalone-activity), as chosen in [step 3](/develop/java/nexus/development-walkthrough?step=backing). | ||
|
|
||
| ## Write the Activity | ||
|
|
||
| The Activity is ordinary and has nothing Nexus-specific in it; a Workflow could call the same Activity unchanged. In this walkthrough it is a placeholder that sends no email. Real logic would call an email provider, push to a notification service, or write to an outbox. | ||
|
|
||
| <!--SNIPSTART samples-java-nexus-walkthrough-activities--> | ||
|
|
||
| [core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/ApprovalActivities.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/ApprovalActivities.java) | ||
|
|
||
| ```java | ||
| public interface ApprovalActivities { | ||
|
|
||
| /** STEP 4 placeholder - real logic would apply policy, check limits, or call a risk service. */ | ||
| @ActivityMethod | ||
| void evaluateAutoDecision(String itemId, double amount); | ||
|
|
||
| /** STEP 4 placeholder - real logic would page an approver or open a ticket. */ | ||
| @ActivityMethod | ||
| void notifyApproverOfPendingRequest(String itemId, String requester); | ||
|
|
||
| /** | ||
| * STEP 9 - The Standalone Activity behind the notifyRequester Operation. One outbound | ||
| * notification, no state, nothing to wait for. In this sample it only logs; real logic would call | ||
| * an email provider, push to a notification service, or write to an outbox. | ||
| */ | ||
| @ActivityMethod | ||
| NotifyRequesterOutput notifyRequester(String requester, NotifyRequesterInput.Decision decision); | ||
| } | ||
| ``` | ||
|
|
||
| <!--SNIPEND--> | ||
|
|
||
| ## Back the Operation with it | ||
|
|
||
| Use `TemporalOperationHandler`, but start an Activity on the [Client](/nexus/temporal-operation-handler#the-nexus-aware-client) instead of a Workflow. The Operation starts an Activity Execution with no parent Workflow and completes when the Activity returns. | ||
|
|
||
| The Activity provides retries, timeouts, and a record of every attempt. The Operation provides the contract, so other teams can trigger the notification without sharing your code or your Namespace. | ||
|
|
||
| <!--SNIPSTART samples-java-nexus-walkthrough-notify-requester--> | ||
|
|
||
| [core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/ApprovalServiceImpl.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/ApprovalServiceImpl.java) | ||
|
|
||
| ```java | ||
| @OperationImpl | ||
| public OperationHandler<NotifyRequesterInput, NotifyRequesterOutput> notifyRequester() { | ||
| return TemporalOperationHandler.create( | ||
| (ctx, client, input) -> | ||
| client.startActivity( | ||
| ApprovalActivities.class, | ||
| ApprovalActivities::notifyRequester, | ||
| input.getRequester(), | ||
| input.getDecision(), | ||
| StartActivityOptions.newBuilder() | ||
| // Deriving the Activity Id from the request Id keeps a retried Nexus start | ||
| // request targeting the same Activity Execution instead of sending a second | ||
| // notification. | ||
| .setId("notify-" + ctx.getRequestId()) | ||
| .setTaskQueue(HandlerWorker.DEFAULT_TASK_QUEUE_NAME) | ||
| .setStartToCloseTimeout(Duration.ofSeconds(10)) | ||
| .setScheduleToCloseTimeout(Duration.ofMinutes(5)) | ||
| .setRetryOptions(RetryOptions.newBuilder().setMaximumAttempts(3).build()) | ||
| .build())); | ||
| } | ||
| ``` | ||
|
|
||
| <!--SNIPEND--> | ||
|
|
||
| ### Options an Activity-backed Operation requires | ||
|
|
||
| `StartActivityOptions` needs an **Activity Id**, unique within the Namespace, because there is no parent Workflow to scope it. | ||
|
|
||
| The Task Queue is optional and defaults to the one the Operation runs on. Set it to run notifications on their own Worker fleet. | ||
|
|
||
| **Derive the Activity Id from the Nexus request Id so that server retries don't send a second email.** Retried Nexus start requests carry the same request Id, so every retry lands on the same Activity Id and the notification goes out once. Use the same pattern for any externally visible side effect that can't be undone, such as charging a card, posting to a webhook, or creating a ticket. | ||
|
|
||
| To make several Operations share one Activity Execution and all receive its result, derive the Id from the Operation *input* instead. See [Nexus Standalone Activity](/nexus/standalone-activity#required-options). | ||
|
|
||
| ## Register the Activity on the Worker | ||
|
|
||
| Register the Activity implementation on the Worker that hosts the Nexus Service. An Activity-backed Operation needs no Workflow registration. | ||
|
|
||
| <!--SNIPSTART samples-java-nexus-walkthrough-handler-worker--> | ||
|
|
||
| [core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/HandlerWorker.java](https://github.com/temporalio/samples-java/blob/main/core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/HandlerWorker.java) | ||
|
|
||
| ```java | ||
| public static void main(String[] args) { | ||
| WorkflowClient client = ClientOptions.getWorkflowClient(args); | ||
|
|
||
| WorkerFactory factory = WorkerFactory.newInstance(client); | ||
| Worker worker = factory.newWorker(DEFAULT_TASK_QUEUE_NAME); | ||
|
|
||
| worker.registerWorkflowImplementationTypes(ApprovalWorkflowImpl.class); | ||
| worker.registerActivitiesImplementations(new ApprovalActivitiesImpl()); | ||
| worker.registerNexusServiceImplementation(new ApprovalServiceImpl()); | ||
|
|
||
| factory.start(); | ||
| } | ||
| ``` | ||
|
|
||
| <!--SNIPEND--> | ||
|
|
||
| ## Cancellation needs heartbeating | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is good information, but not useful to the guide. The guide should stay a bit tighter to How-to-Guide, move this content to Reference. |
||
|
|
||
| This notification finishes immediately, so cancellation doesn't matter here. For a longer Activity-backed Operation it does: a cancellation request doesn't interrupt an Activity, so an Activity that never heartbeats runs until it completes or times out. Before shipping a long-running Activity-backed Operation, read [Activity cancellation](/activity-execution#cancellation). | ||
|
|
||
| ## Run it | ||
|
|
||
| From the command line, this Operation looks like every other one: | ||
|
|
||
| <RunThis> | ||
|
|
||
| ```bash title="Run 1 of 2: notify the requester" | ||
| temporal nexus operation execute \ | ||
| --namespace approval-caller-namespace \ | ||
| --endpoint approval-endpoint \ | ||
| --service temporal.samples.approval.v1.ApprovalService \ | ||
| --operation NotifyRequester \ | ||
| --operation-id notify-1 \ | ||
| --input '{"requester":"tao@example.com","decision":"APPROVED"}' | ||
| ``` | ||
|
|
||
| </RunThis> | ||
|
|
||
| ``` | ||
| Results: | ||
| Status COMPLETED | ||
| Result {"deliveredTo":"tao@example.com"} | ||
| ``` | ||
|
|
||
| On the handler side there is no Workflow, only an Activity Execution with no parent: | ||
|
|
||
| <RunThis> | ||
|
|
||
| ```bash title="Run 2 of 2: list the Standalone Activity" | ||
| temporal activity list --namespace approval-handler-namespace | ||
| ``` | ||
|
|
||
| </RunThis> | ||
|
|
||
| ``` | ||
| Status ActivityId Type StartTime | ||
| Completed notify-0f816331-6b85-404d-9dfa-dd249041c1ea NotifyRequester now | ||
| ``` | ||
|
|
||
| The handler derived the Activity Id from the Nexus request Id. Running the command again with a new | ||
| `--operation-id` creates a second Activity Execution, but a server retry of the *same* request reuses | ||
| the first. | ||
|
|
||
| If this fails with `completion callbacks are not enabled for this namespace`, the development | ||
| server was started without `activity.enableCallbacks=true`. See | ||
| [step 4](/develop/java/nexus/development-walkthrough?step=implement#start-the-development-server). | ||
|
|
||
|
|
||
| :::tip RESOURCES | ||
|
|
||
| - [Nexus Standalone Activity](/nexus/standalone-activity) for the full concept and options. | ||
| - [Standalone Activity](/standalone-activity) for Activity Executions outside a Workflow. | ||
| - [Java: Standalone Activities](/develop/java/activities/standalone-activities) for the SDK API. | ||
|
|
||
| ::: | ||
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think we can remove this from all the code since it is not needed