RPC, `using`, Experimental Wrangler and Observability

When making RPC calls through a Service Binding, it's recommended (https://developers.cloudflare.com/workers/runtime-apis/rpc/lifecycle/#how-to-use-the-using-declaration-in-your-worker) that we employ the using keyword to enable automatic cleanup. To use this, we're forced to use the wrangler@using-keyword-experimental version so that the using keyword is transpiled properly upon deployment. Unfortunately, this version of wrangler seems to be incompatible with the new observability setting that's available to us in wrangler 3.78.6. Is there another way to handle RPC call cleanup without using the using keyword so that we can not bump into incompatibility with new features that are released?
6 Replies
Murder Chicken
Murder ChickenOP2mo ago
I'm attempting to solve this without the experimental wrangler using the following code:
/**
* Executes an RPC call and ensures proper cleanup.
* @param {Function} rpcCall - A function that performs the RPC call.
* @returns {Promise<any>} - The result of the RPC call.
*/
export async function executeRpcWithCleanup(rpcCall) {
let rpcResult = null;
try {
rpcResult = await rpcCall();
return rpcResult;
} finally {
if (rpcResult && typeof rpcResult[Symbol.dispose] === 'function') {
console.info('Disposing RPC result');
rpcResult[Symbol.dispose]();
} else {
console.info('No Symbol.dispose method on rpcResult');
}
}
}
/**
* Executes an RPC call and ensures proper cleanup.
* @param {Function} rpcCall - A function that performs the RPC call.
* @returns {Promise<any>} - The result of the RPC call.
*/
export async function executeRpcWithCleanup(rpcCall) {
let rpcResult = null;
try {
rpcResult = await rpcCall();
return rpcResult;
} finally {
if (rpcResult && typeof rpcResult[Symbol.dispose] === 'function') {
console.info('Disposing RPC result');
rpcResult[Symbol.dispose]();
} else {
console.info('No Symbol.dispose method on rpcResult');
}
}
}
... and executing the method like this:
const response = await executeRpcWithCleanup(() => env.SERVICE.myRpcMethod());
const response = await executeRpcWithCleanup(() => env.SERVICE.myRpcMethod());
However, I'm seeing odd behavior in that the RPC methods seem to be being called twice when I view the SERVICE worker's logs. When I tried an implementation of the using method, I did not see this. Not sure what's happening but anything that might cause RPC methods to be called multiple times using a single invocation of the method?
Radoš
Radoš2mo ago
Does [Symbol.dispose]() works for you as it is also part of the TC39? https://github.com/cloudflare/js-rpc-and-entrypoints-demo In this repo, they are using it without using even with RpcTarget
GitHub
GitHub - cloudflare/js-rpc-and-entrypoints-demo
Contribute to cloudflare/js-rpc-and-entrypoints-demo development by creating an account on GitHub.
Murder Chicken
Murder ChickenOP2mo ago
Unclear but it seems to deploy and work whereas use of usingrequires a different wrangler so it understands how to transpile using statements into Symbol.dispose statements. So far, the approach I used above seems to work. The only odd behavior I'm seeing is duplicate log entries on the Service Worker housing the RPC methods. In my use-case, I'm using Service Bindings from within a scheduled worker... IIRC they mention something about being limited to fetch handlers but it seems to work for me 🤷‍♂️
Radoš
Radoš2mo ago
I have gone thru rabbit hole of sharing types between Service and Caller, but trying to call function from AuthService class thats extends RpcTarget resulted in undefined every time. I am going to play with it in next few days, so if I stumble up on something I will let you know.
Murder Chicken
Murder ChickenOP2mo ago
Are you awaiting the method call?
Radoš
Radoš2mo ago
Yes, when I log the call result, it shows ProxyObject, but then when I tried to call result.someFunction it was always undefined. Like it closed connection already. But maybe I was too tired and I did some rookie mistake 😄
Want results from more Discord servers?
Add your server