- Notifications
You must be signed in to change notification settings - Fork 1k
Support JSRPC for remote bindings #10249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: ccbb30d The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| constructor(ctx: ExecutionContext, env: Env) { | ||
| const url = new URL(env.remoteProxyConnectionString); | ||
| url.protocol = "ws:"; | ||
| url.searchParams.set("MF-Binding", env.binding); | ||
| const session = rpcOverWebSocket(url.href); | ||
| const stub = session.getStub(); | ||
| | ||
| super(ctx, env); | ||
| | ||
| return new Proxy(this, { | ||
| get(target, prop) { | ||
| if (Reflect.has(target, prop)) { | ||
| return Reflect.get(target, prop); | ||
| } | ||
| | ||
| const value = Reflect.get(stub, prop); | ||
| return value; | ||
| }, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This proxy code is inspired by that written for rpc in local dev with the router worker—thanks @CarmenPopoviciu!
f729c29 to 70ce62e Compare There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me! 😄
I just left a few comments (some just asking info so that I can understand the implementation better 🙂)
However one thing I'd like to ask however is, I can see you'd chosen to use rpcOverWebSocket, have you considered generally using rpcOverHttp instead?
It would likely be slightly slower and more noisy but since we're not talking about something that needs to handle live traffic that could be acceptable. Using non-persistent http could help us avoid persistence issues that can happen for different reasons (such as sessions restarts, weird remote preview bugs and vite environments reloads).
I am by no means saying that I think rpcOverHttp would be more appropriate/better, I'm just curious if you've considered or tested using that instead of the permanent websocket connection 🙂
I was hoping to be able to use that, yes! Unfortunately it requires an explicit |
Couldn't we do that as part of the proxy objects? 🤔 as in, when we return a function in a Proxy getter, we could wrap that function so that after its execution it runs For example something like: new Proxy(this, { get(target, prop) { if (Reflect.has(target, prop)) { return Reflect.get(target, prop); } const stubProp = Reflect.get(stub, prop); if (typeof stubProp === 'function') { return async (...args) => { const resPromise = stubProp(...args); batch.send(); return resPromise; }; } return stubProp; } }); |
There are lots of edge cases here:
|
Yeah good points 🤔👍 |
a0bfd7b to 76f2038 Compare create-cloudflare
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-editor-shared
wrangler
commit: |
This comment was marked as off-topic.
This comment was marked as off-topic.
Create yellow-kangaroos-bathe.md fix checks fix checks Increase timeouts more logging static workers static workers pre-compile proxy server worker
87b55c2 to 5bab92a Compare | sourcemap: process.env.SOURCEMAPS !== "false", | ||
| sourcesContent: false, | ||
| metafile: true, | ||
| external: ["cloudflare:email", "cloudflare:workers"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: this can take regular expressions. So maybe?
| external: ["cloudflare:email", "cloudflare:workers"], | |
| external: /^cloudflare:/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's type seems to be BuildOptions.external?: string[] | undefined?
| "@cloudflare/cli": "workspace:*", | ||
| "@cloudflare/containers-shared": "workspace:*", | ||
| "@cloudflare/eslint-config-worker": "workspace:*", | ||
| "@cloudflare/jsrpc": "link:../../vendor/jsrpc", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder, wouldn't it be cleaner adding `"vendor/*" directory to the packages list in "pnpm-workspace.yaml" and treat jsrpc as any other workspace package? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially? But I wanted to draw a clear difference between this and other packages—e.g. we're not running JSRPC's tests, and we're just including the built output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would the benefit of treating it as a workspace package be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just wondering it that'd be cleaner, pnpm could also optimize something... but it is not a huge deal I'm happy with the current approach I was just wondering 🙂
packages/wrangler/templates/remoteBindings/ProxyServerWorker.ts Outdated Show resolved Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing stuff! 😄 🚀
Fixes https://jira.cfdata.org/browse/DEVX-2042, https://jira.cfdata.org/browse/DEVX-1929, https://jira.cfdata.org/browse/DEVX-1933
Support JSRPC bindings! This uses a vendored version of the upcoming
@cloudflare/jsrpclibrary. See code for detailed comments.