Integrate Resonate into an existing project
How to integrate Resonate into an existing project.
You can integrate Resonate into an existing project by just adding the Resonate SDK as a dependency and initializing it in your Worker or Application Node. You don't need to run a Resonate Server to get started — Resonate will store all promises in local memory, until you are ready to add remote invocations and long term durability to your application.
Add the SDK to your project
Add the Resonate SDK to your project as a dependency.
- Python
- TypeScript
- uv
- pip
- poetry
uv add resonate-sdk
pip install resonate-sdk
poetry add resonate-sdk
- Bun
- npm
- Yarn
bun add @resonatehq/sdk
npm install @resonatehq/sdk
yarn add @resonatehq/sdk
Initialize Resonate
Then, initialize Resonate in your script, worker, or application.
You can intialize Resonate in local memory, which does not require any additional dependencies (such as a Resonate Server). This is a great way to get started and test the integration.
When you are ready to add long term durability and remote invocations, you can switch to a remote store and message source (Resonate Server).
- Python
- TypeScript
from resonate import Resonate
# Initialize Resonate with a local promise store
# Great for local development.
resonate = Resonate.local()
# Initialize Resonate with a remote promise store
# Great for building production grade distributed applications.
resonate = Resonate.remote()
import { Resonate } from "@resonatehq/sdk";
// Initialize Resonate with a local promise store
// Great for local development.
const resonate = Resonate.local();
// Initialize Resonate with a remote promise store
// Great for building production grade distributed applications.
const resonate = Resonate.remote();
Make sure you run a Resonate Server prior to initializing Resonate with .remote()
brew install resonatehq/tap/resonate
resonate serve
If you don't have brew, see the Server installation guide for more installation options.
Register a function
Next, register a function with Resonate. Functions registered and invoked with Resonate gain durable qualities and can be awaited on remotely.
- Python
- TypeScript
Register a function with Resonate using the register
decorator or the register
method.
All functions registered with Resonate or called from a Resonate function must define Context as the first argument.
# Register a function with the decorator
@resonate.register
def foo(ctx: Context, arg: str) -> str:
# Your function logic here
return result
# Register a function with the register method
def foo(ctx: Context, arg: str) -> str:
# Your function logic here
return result
resonate.register(foo)
# ...
resonate.start()
Calling resonate.start()
explicitly starts Resonate instance threads.
It is not needed in scripts, workers, or application nodes that call resonate.run()
, but we recommend doing so with all instances of Resonate.
You can register a function with Resonate using the register
method.
All functions registered with Resonate or called from a Resonate function must define Context
as the first argument.
function foo(ctx: Context, arg: string): string {
// Your function logic here
return result;
}
fooR = resonate.register("foo", foo);
Invoke a function
You can invoke a function that is defined locally in the script, worker, or application node, or you can invoke a function that is defined remotely in a different worker or application . Invoking a function locally does not require the Resonate Server, but invoking one remotely does.
- Python
- TypeScript
If the function is in the same Worker or Application Node, you can invoke it directly with the Resonate Client's Run API.
result = foo.run(promise_id, arg=arg)
# or using the Resonate Client
result = resonate.run(promise_id, func="foo", arg=arg)
If the function is in a different Worker or Application Node, you can invoke it with the rpc method on the Resonate instance. To do this, your worker must be connected to a remote store and message source (Resonate Server).
result = resonate
.options(target="<transport_plugin>://<unique_id>@<group>/<id>")
.rpc(promise_id, func="foo", arg=arg)
If the function is in the same Worker or Application Node, you can invoke it directly with the Resonate Client's Run API.
const result = fooR(promiseId, arg);
// or using the Resonate Client
const result = resonate.run("foo", promiseId, arg);
If the function is in a different Worker or Application Node, you can invoke it with the rpc method on the Resonate instance. To do this, your worker must be connected to a remote store and message source (Resonate Server).
const result = await resonate.rpc(
promiseId,
"foo",
arg,
resonate.options({
target: "process-group-b",
})
);
Extend the Call Graph
You can extend your Call Graph by invoking other functions from within a function.
- Python
- TypeScript
@resonate.register
def foo(ctx: Context, arg: str) -> str:
# ...
r1 = yield ctx.run(bar, arg)
r2 = yield ctx.run(baz, r1)
return r2
function* factorial(ctx: Context, arg): Generator<any, string, any> {
// ...
r1 = yield* ctx.run(bar, arg);
r2 = yield* ctx.run(baz, r1);
return r2;
}