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

external Durable Objects #221

Closed
konsumer opened this issue Mar 17, 2022 · 2 comments
Closed

external Durable Objects #221

konsumer opened this issue Mar 17, 2022 · 2 comments
Labels
error message Error message should be improved
Milestone

Comments

@konsumer
Copy link

konsumer commented Mar 17, 2022

Hi, I am using a DO defined in another worker.

The way I do that is like this:

[[durable_objects.bindings]]
name = "DO_STORE"
class_name = "StoreDurableObject"
script_name = "store-production"

where store-production is the external worker that has the DO.

I realize that miniflare is all local, and that is fine (the DO is actually exposed as a http graphql server on the worker, too, so locally I can hit that, and it will be the same data.) My issue is that if I uncomment that, I get an error locally, and if I comment that, it won't be defined when I deploy this on wrangler, so it won't be bound to the real DO. I tried using cli options to force miniflare to use a separate class, instead of what is defined there, but that didn't work (I am using remix, and it had an error about using addEventListener, as DO needs ES6 modules.)

I also tried making store-production and store-production.js, because I realized that miniflare only does local DO files for script_name, not remote-worker DO like wrangler does, hoping it would do that, but I get this error:

[mf:err] DurableObjectError [ERR_SCRIPT_NOT_FOUND]: Script "store-production" for Durable Object "DO_STORE" not found
    at DurableObjectsPlugin.reload (PROJECT_DIR/node_modules/@miniflare/durable-objects/src/plugin.ts:201:17)
    at EventTarget.#runAllReloads (PROJECT_DIR/node_modules/@miniflare/core/src/index.ts:656:24)
    at EventTarget.#reload (PROJECT_DIR/node_modules/@miniflare/core/src/index.ts:797:13)
    at EventTarget.getPlugins (PROJECT_DIR/node_modules/@miniflare/core/src/index.ts:970:5)
    at createServer (PROJECT_DIR/node_modules/@miniflare/http-server/src/index.ts:332:19)
    at startServer (PROJECT_DIR/node_modules/@miniflare/http-server/src/index.ts:418:18)
    at main (PROJECT_DIR/node_modules/miniflare/src/cli.ts:96:5)

Is there a better way to make it use a mock DO class locally, but use the real DO, remotely? Do I need to give up on remix + miniflare?

@mrbbot
Copy link
Contributor

mrbbot commented Mar 17, 2022

Hey! 👋 I think you're looking for Miniflare's mounting feature that lets you run mutliple worker scripts in the same instance and share their Durable Object classes. See https://miniflare.dev/storage/durable-objects#using-a-class-exported-by-another-script for more details.

In your case, you'd want to mount the directory containing the store-production worker, then script_name should work as you've configured it.

That error message should probably mention mounting.

@mrbbot mrbbot added the error message Error message should be improved label Mar 17, 2022
@konsumer
Copy link
Author

konsumer commented Mar 18, 2022

I sort of tried that, but could't get it to work. That is a good tip about script_name being the name of the dir that has the worker, though. Also, that worker might not necessarily be available on the dev's system (it's a seperate repo, etc.)

I ended up solving it by using 2 wrangler.toml files. 1 is minimal, without DO, for dev, and 1 has it. Then in my code I pick the right way to get to the graphql data (DO vs HTTP query)

/* global DO_STORE, fetch, Request */
export function graphql (request, query, variables) {
  let fetchWrapped = fetch
  if (typeof DO_STORE !== 'undefined') {
    const store = DO_STORE.get(DO_STORE.idFromName(request.cf?.colo || 'PDX'))
    fetchWrapped = (url, opts) => store.fetch(new Request(new URL(url)), opts)
  }
  return fetchWrapped(URL_GRAPHQL, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ query, variables }) }).then(r => r.json())
}

I kinda like it better because it's really clear that each config handles a specific use-case, so it all worked out for me. I appreciate the help and miniflare, in general. This is issue is totally closable.

@mrbbot mrbbot added this to the 2.6.0 milestone Jun 9, 2022
@mrbbot mrbbot closed this as completed in 20b7159 Jun 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error message Error message should be improved
Projects
None yet
Development

No branches or pull requests

2 participants