Invocations
An invocation is a request to execute a handler that is part of either a service, or a virtual object.
There are three ways to invoke a handler:
HTTP requests
Send a request to the Restate Server (port 8080
), with the handler name in the path, and the payload body.
Learn more
Programmatically
Use the SDK to send requests within Restate handlers. Or use generated HTTP clients anywhere else.
Learn more
Kafka events
Restate subscribes to a Kafka topic, and invokes a handler should for each message that arrives.
Learn more
All invocations are proxied through the Restate Server, which registers the request, routes the request to the correct handler, and drives the execution of the handler.
Invocations get a unique identifier. This identifier is used to track the progress of the invocation, and lets you correlate logs and metrics.
Invocation types
- TypeScript
- Java
- Go
- Python
- Shell
Request-response invocations allow you to wait on a response from the handler.
One-way invocations allow you to trigger an asynchronous action.
Delayed invocations allow you to schedule an invocation for a later point in time.
- restate_service.ts
- plain_node_app.ts
async function myRestateHandler(ctx: restate.Context) {const greet = await ctx.serviceClient(greeter).greet({ greeting: "Hi" });}
const myPlainTSFunction = async () => {const rs = restate.connect({ url: "http://localhost:8080" });const greet = await rs.serviceClient(greeter).greet({ greeting: "Hi" });};
Learn more about service communication and the SDK clients in the TypeScript SDK.
Request-response invocations allow you to wait on a response from the handler.
One-way invocations allow you to trigger an asynchronous action. This returns an invocation ID with which you can retrieve the result of the invocation later, if desired.
Delayed invocations allow you to schedule an invocation for a later point in time.
- RestateService.java
- PlainJavaService.java
@Handlerpublic void myRestateHandler(Context ctx) {String greet =GreeterServiceClient.fromContext(ctx).greet("Hi").await();}
public void myJavaHandler() {Client restate = Client.connect("http://localhost:8080");String greet =GreeterServiceClient.fromClient(restate).greet("Hi");}
Learn more about service communication and the SDK clients in the TypeScript SDK.
Request-response invocations allow you to wait on a response from the handler.
One-way invocations allow you to trigger an asynchronous action.
Delayed invocations allow you to schedule an invocation for a later point in time.
func (MyService) MyRestateHandler(ctx restate.Context) error {greet, err := restate.Service[string](ctx, "Greeter", "Greet").Request("Hi")return err}
Learn more about service communication in the Go SDK.
Request-response invocations allow you to wait on a response from the handler.
One-way invocations allow you to trigger an asynchronous action.
Delayed invocations allow you to schedule an invocation for a later point in time.
@my_service.handler()async def my_handler(ctx: Context, arg):greeting = await ctx.service_call(greet, arg="Hi")
Learn more about service communication and the SDK clients in the TypeScript SDK.
Request-response invocations allow you to wait on a response from the handler.
One-way invocations allow you to trigger an asynchronous action. This returns an invocation ID with which you can retrieve the result of the invocation later, if desired.
Delayed invocations allow you to schedule an invocation for a later point in time.
curl localhost:8080/GreeterService/greet \-H 'content-type: application/json' \-d '"Hi"'
Learn more about invoking services over HTTP.
Idempotent invocations
For HTTP requests, you can add an idempotency key to the header to make the invocation idempotent. Restate will then deduplicate requests with the same idempotency key, and will only execute the handler once. Duplicate requests will get the same response as the first request, or will latch on to the first invocation if it's still running.
curl localhost:8080/GreeterService/greet \-H 'idempotency-key: ad5472esg4dsg525dssdfa5loi' \-H 'content-type: application/json' \-d '"Hi"'
Note that, you don't need idempotency tokens for invocations that are invoked programmatically or via Kafka, as Restate will make sure that they are executed only once.
Inspecting invocations
Restate proxies and manages inbound as well as service-to-service invocations. This makes it a great source of observability data for your application. You can inspect invocations via the CLI.
restate services list
Output
NAME REVISION FLAVOR DEPLOYMENT TYPE DEPLOYMENT IDπ CartObject 1 β¬ οΈ πΆπΆπΆ HTTP 2 dp_11pXug0mWsff2NOoRBZbOcVπ CheckoutService 1 HTTP 2 dp_11pXug0mWsff2NOoRBZbOcVπ TicketObject 1 β¬ οΈ πΆπΆπΆ HTTP 2 dp_11pXug0mWsff2NOoRBZbOcV`,`$ restate services describe CartObjectπ Service Information:βββββββββββββββββββββββName: CartObjectService type: VirtualObjectRevision: 1Public: trueDeployment ID: dp_11pXug0mWsff2NOoRBZbOcVDeployment Type: HTTP 2Protocol Style: StreamingEndpoint: http://localhost:9080/Created at: 2024-04-23T12:32:16.691000000Zπ Handlers:ββββββββββββHANDLER INPUT TYPE OUTPUT TYPEaddTicket one of "empty or value of value with content-type "application/json"content-type */*"checkout one of "empty or value of value with content-type "application/json"content-type */*"expireTicket one of "empty or value of value with content-type "application/json"content-type */*"
restate invocations list
Output
β― [2024-04-23 14:41:59.365 +02:00] inv_1fmRNvSNVxNp5PTqHI4HLJ17HpxzhB3MEVTarget: CartObject/Mary/addTicketStatus: backing-off (18 seconds and 284 ms. Retried 9 time(s). Nextretry in in 8 seconds and 220 ms))Deployment: dp_11pXug0mWsff2NOoRBZbOcV [required]Error: [2024-04-23 14:42:13.706 +02:00][500] FailingCaused by: UNKNOWN
restate invocations describe inv_1fmRNvSNVxNp5PTqHI4HLJ17HpxzhB3MEV
Output
π Invocation Information:ββββββββββββββββββββββββββCreated at: 2024-04-23 14:41:59.365 +02:00 (a minute ago)Target: CartObject/Mary/addTicketStatus: backing-off (1 minute, 23 seconds and 937 ms. Retried 14time(s). Next retry in in 991 ms))Deployment: dp_11pXug0mWsff2NOoRBZbOcV [required]Error: [2024-04-23 14:43:13.248 +02:00][500] FailingCaused by: UNKNOWNModified at: 2024-04-23 14:41:59.388 +02:00π‘ This invocation is bound to run on deployment 'dp_11pXug0mWsff2NOoRBZbOcV'. To guaranteesafety and correctness, invocations that made progress on a deploymentcannot move to newer deployments automatically.π Invocation Progress:βββββββββββββββββββββββ[Ingress]βββ(this)β> CartObject/Mary/addTicketβΈβββββ βοΈ #1 Call TicketObject/seat2B/reserve inv_19maBIcE9uRD1CrHgpGXZ7FcXPsz4bzkbLβββββ>> backing-off
restate invocations cancel --kill inv_1fmRNvSNVxNp5PTqHI4HLJ17HpxzhB3MEV
Output
β― [2024-04-23 14:41:59.365 +02:00] inv_1fmRNvSNVxNp5PTqHI4HLJ17HpxzhB3MEVTarget: CartObject/Mary/addTicketStatus: backing-off (25 minutes, 29 seconds and 200 ms. Retried 141time(s). Next retry in in 12 seconds and 94 ms))Deployment: dp_11pXug0mWsff2NOoRBZbOcV [required]Error: [2024-04-23 15:07:27.860 +02:00][500] FailingCaused by: UNKNOWNβ Are you sure you want to kill this invocation Β· yesβ Request was sent successfully
Restate also exposes traces via OpenTelemetry, which can be sent to your observability platform of choice (e.g. Jaeger). Have a look at the tracing documentation for more information.
Cancelling and killing invocations
The Restate CLI allows you to cancel or kill invocations. If necessary, you can register compensating actions in your handlers to ensure that the system remains consistent amid cancellations (blog post on graceful cancellations).
For cancellations, Restate will gracefully stop the handler by executing all compensation actions. For kills, Restate will immediately stop the handler without executing any compensation actions.