workers-sdk icon indicating copy to clipboard operation
workers-sdk copied to clipboard

🐛 BUG: Service bindings don't work for scheduled workers

Open mrmcpowned opened this issue 2 years ago • 3 comments

What version of Wrangler are you using?

2.0.24

What operating system are you using?

Windows 10 (21H2) Build 19044.1826

Describe the Bug

  1. Create a Scheduled worker
  2. Create another Fetch worker
  3. Bind the Fetch worker to the Scheduled worker
  4. Inside the Scheduled worker, invoke the binding's fetch
  5. Trigger the Scheduled worker

Expected Result The fetch succeeds and we get the response from the binded fetch worker

Actual Result The execution errors out with the binding being 'undefined'

mrmcpowned avatar Aug 04 '22 02:08 mrmcpowned

I'm not entirely sure if this is necessarily a bug or by design but I couldn't find any information about this kind of scenario.

@threepointone I noticed you've been making commits regarding bindings for wrangler, would you happen to have any insight on this?

mrmcpowned avatar Aug 04 '22 02:08 mrmcpowned

I'm not entirely sure if this is necessarily a bug or by design but I couldn't find any information about this kind of scenario.

@threepointone I noticed you've been making commits regarding bindings for wrangler, would you happen to have any insight on this?

Sunil is on vacation (still might respond) however I will take a look into this and discuss it with the team. The local multi worker story is still new so this is likely a bug or necessary feature.

JacobMGEvans avatar Aug 04 '22 16:08 JacobMGEvans

Good catch, the facade should include scheduled worker as well. I'll take this on.

threepointone avatar Aug 22 '22 13:08 threepointone

@mrmcpowned Would you be able to check whether this reproduces in the latest version of Wrangler? We've made some changes to the middleware facades that may have fixed this.

penalosa avatar Mar 13 '23 11:03 penalosa

Funny enough, I encountered the same situation today. Binding is shown on startup, but when trying to call within the scheduled function I receive GET /__scheduled?cron=0+7+1+*+*: TypeError: Cannot read properties of undefined (reading 'fetch'). (Wrangler 2.13)

See also https://discord.com/channels/595317990191398933/779390076219686943/1089599022869786665.

So for now it would be recommended to keep the scheduling within the worker supposed to be called?

tsteckenborn avatar Mar 26 '23 18:03 tsteckenborn

I'm encountering this as well with Wrangler 3.0.1 as well.

code-poel avatar Jun 02 '23 12:06 code-poel

Looks like the facade is not still binding to scheduled events?

service-bindings-module-facade.js

code-poel avatar Jun 03 '23 11:06 code-poel

Just a note for people dealing with this who are totally blocked because their scheduledEvent worker needs data from another worker. You can work around this by making a fetch request from within your scheduled method so that you gain access to the binding and can communicate with the other worker.

To be clear... this solution, while it works, suuuuuucks and makes your entry point vastly more complicated than it needs to be.

Here's a code snippet describing how you can bypass this issue until this ticket is resolved. This code would reside in the worker that needs access to the binding and assumes your other worker exists and is configured in your wrangler.toml which might look like this:

services = [
  { binding = "YOUR_BINDING", service = "<worker-name-here>" }
]
export default {
  async scheduled(event, env, ctx) {
    try {
      // Pass this to the fetch method which has access to the binding
      // The URL for the request can be anything... everything before the /api/path/needed part is ignored
      const responseData = await this.fetch(new Request('https://null/api/path/needed', {
        method: 'GET'
      }), env, ctx)
      // Handle the response promise (in m y case, I wanted JSON, you might need .text() or whatever)
      data = await responseData.json()
      // Do stuff with your data here
      console.log(data)
    }
    catch (error) {
      console.log(error.cause)
    }
  },
  async fetch (request, env, context) {
    try {
      // Deal with favicon requests
      if (request.url.endsWith('/favicon.ico')) {
        return new Response(null, {
          status: 204,
        })
      }
      // Your binding should work here within the fetch method
      return await env.YOUR_BINDING.fetch(request.clone())
    }
    catch (error) {
      console.log(error.cause)
    }
  }
}

Note: If doing this locally, the order in which you start your workers is important.

code-poel avatar Jun 03 '23 14:06 code-poel

This should be fixed in the next version of Wrangler

penalosa avatar Jun 15 '23 20:06 penalosa