Skip to content
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

V6: When updating the Cloudflare template, show RPC usage #458

Open
ngbrown opened this issue Aug 29, 2024 · 4 comments
Open

V6: When updating the Cloudflare template, show RPC usage #458

ngbrown opened this issue Aug 29, 2024 · 4 comments
Assignees

Comments

@ngbrown
Copy link
Contributor

ngbrown commented Aug 29, 2024

With Cloudflare, it is common to deploy the web application via Cloudflare Pages so that static resources aren't part of the worker's code size limit. But ravendb-nodejs-client can't live in a Pages function so it has to be deployed to a separate Cloudflare service workers instance.

The reason RavenDB can't be deployed to Cloudflare Pages is because Pages functions doesn't currently have the ability to bind to a mTLS certificate.

The size of the RavenDB library would also encroach on the 1MiB code size limit for a Pages function. A service worker with just the RavenDB client and almost nothing else deploys with a size of 1,044 KiB / gzip: 191 KiB.

I think I've seen Cloudflare advocate for splitting the application between workers along the layers of an application. (I can't find a reference for this right now, but it might have been in their Discord channel, for example). A approach would be to then use RPC service bindings between the two parts of the application. With an RPC binding, the two parts actually run together in the same isolate (and thread) on the server.

When using RavenDB with RPC bindings, returning a RavenDB entity as is causes an exception because the @metadata can't be structured cloned. So in my application, I have to "pre-clone" the entities and strip the @metadata field before returning it from the RPC method.

Another change I made from the RavenDB documentation is store the documentStore at the module level so it doesn't get re-initialized on every function call or request. Even though the workers aren't long-lived, this helped reduce the number of new connection being made per-second and eliminated a warning that was being raised in the RavenDB console.

I think that the RavenDB Cloudflare template should cover these concerns, so that's why I'm bringing it up. It would be a little more complicated than just using a single worker as there would be two projects, one pages functions and one service worker, or two service workers. This would be fairly approachable with npm workspaces.

@ayende
Copy link
Member

ayende commented Aug 29, 2024

Can you give some more context on what you suggest?
Is there a need to make changes to the client to support it? Or are we talking about guidance docs?

@ngbrown
Copy link
Contributor Author

ngbrown commented Aug 29, 2024

When trying to deploy an application to Cloudflare Pages, I got the RavenDB client working with my application so no change in the client is strictly necessary. Like I outlined above, I had to setup a separate Workers application with RPC service bindings and then strip the @metadata field (because it's a class) from returned objects.

So this could be just an updated template (https://github.com/ravendb/template-cloudflare-worker) and documentation guidance. Including how to properly avoid the too many connections warning when Cloudflare passes the components of the DocumentStore constructor separately on each request.

Or during the process of setting up a Cloudflare pages application, you'll find other changes you would like to make to the client library. I would like to know if using a class for the @metadata object is strictly necessary, or is there something that can be done to make the client-fetched entities compatible with Cloudflare's variation of structured clone (throws on classes).

@ayende
Copy link
Member

ayende commented Aug 30, 2024

For the class vs object - I'll let @ml054 answer

For the rest - given that you are currently going through that, you are likely our best source of information.
Would you be able to post your notes on what is required here?

We are trying to get more technical articles on RavenDB and would love to publish this here: https://ravendb.net/posts

@ml054
Copy link
Member

ml054 commented Oct 17, 2024

@ngbrown you are right, since metadata is proxy object is isn't structed cloneable.

I opened ticket for that: https://issues.hibernatingrhinos.com/issue/RDBC-879/Consider-session-objects-to-be-structured-clonable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants