To send a message to another Restate handler without waiting for a response:
// To message a Service:restate.ServiceSend(ctx, "MyService", "MyHandler").Send("Hi")// To message a Virtual Object:restate.ObjectSend(ctx, "MyObject", "Mary", "MyHandler").Send("Hi")// To message a Workflow:// `run` handler — can only be called once per workflow IDrestate.WorkflowSend(ctx, "MyWorkflow", "my-workflow-id", "Run"). Send("Hi")// Other handlers can be called anytime within workflow retentionrestate.WorkflowSend(ctx, "MyWorkflow", "my-workflow-id", "InteractWithWorkflow"). Send("Hi again")
Restate handles message delivery and retries, so the handler can complete and return without waiting for the message to be processed.
Calls to a Virtual Object execute in order of arrival, serially.
Example:
// To message a Service with a delay:restate.ServiceSend(ctx, "MyService", "MyHandler"). Send("Hi", restate.WithDelay(5*time.Hour))// To message a Virtual Object with a delay:restate.ObjectSend(ctx, "MyObject", "Mary", "MyHandler"). Send("Hi", restate.WithDelay(5*time.Hour))// To message a Workflow with a delay:restate.WorkflowSend(ctx, "MyWorkflow", "my-workflow-id", "Run"). Send("Hi", restate.WithDelay(5*time.Hour))
Restate automatically deduplicates calls made during the same handler execution, so there’s no need to provide an idempotency key in that case.
However, if multiple handlers might call the same service independently, you can use an idempotency key to ensure deduplication across those calls.
// Execute the request and retrieve the invocation idinvocationId := restate. ServiceSend(ctx, "MyService", "MyHandler"). Send("Hi"). GetInvocationId()// I don't need this invocation anymore, let me just cancel itrestate.CancelInvocation(ctx, invocationId)