You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit de706ed
Browse filesBrowse the repository at this point in the historyBrowse files
feat(cloudflare): Add trace propagation for RPC method calls (#20343)
closes#19327
closes
[JS-1715](https://linear.app/getsentry/issue/JS-1715/sentrycloudflare-durable-object-rpc-spans-are-not-linked-to-worker)
closes#16898
closes
[JS-680](https://linear.app/getsentry/issue/JS-680/instrument-cloudflare-worker-rpc-methods)
closes#16760
closes
[JS-622](https://linear.app/getsentry/issue/JS-622/trace-propagation-in-cloudflare-workers-not-working-as-expected)
## Summary
> Most of the additions are tests, the main implementation is rather
small
Adds trace propagation for Cloudflare Workers RPC method calls to
Durable Objects.
This is admittedly a bit of a hack: [Cap'n
Proto](https://capnproto.org/) ([which powers Cloudflare
RPC](https://blog.cloudflare.com/capnweb-javascript-rpc-library/)) has
no native support for headers or metadata. To work around this, we
append our trace data (sentry-trace + baggage) as a trailing argument
object `{ __sentry: { trace, baggage } }` to every RPC call. On the
receiving DO side, we strip this argument before the user's method is
invoked, so it's completely transparent.
**Caveat:** If the Durable Object is not instrumented with Sentry, the
trailing `__sentry` argument will remain in the args array and be passed
to the user's method. I would count this as ok since:
- Users opting into RPC instrumentation are expected to instrument both
sides
- The extra argument is easy to ignore in most cases, unless users use
`...args` to retrieve all arguments
Otherwise, trace propagation should be seamless across Worker → DO and
Worker → Worker → DO call chains.
### How it works
As mentioned above a Sentry trace object is appended on each call
```ts
const id = env.MY_DURABLE_OBJECT.idFromName('test');
const stub = env.MY_DURABLE_OBJECT.get(id);
// User's RPC call
const result = await stub.sayHello('World');
// What is actually sent (transparent to user)
const result = await stub.sayHello('World', { __sentry: { trace, baggage } });
```
0 commit comments