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

alarm shorter than 30s #290

Closed
wighawag opened this issue Jun 20, 2022 · 12 comments
Closed

alarm shorter than 30s #290

wighawag opened this issue Jun 20, 2022 · 12 comments
Labels
behaviour mismatch Different behaviour to Workers runtime
Milestone

Comments

@wighawag
Copy link

I am replacing my scheduled event with alarm to allow call every second but miniflare seems to cap the minimum at 30s

@CraigglesO
Copy link
Contributor

Hey @wighawag, this is very much intentional. This is the same design pattern used by cloudflare's DO workers. They check every 30 seconds for alarms. One solution is that if you need to do more work within a 30second span, you can do a SetTimeout style promise. However, talking with devs, you're not guaranteed results using this method as you are with alarms.

@wighawag
Copy link
Author

Thanks for the quick reply

I used to do exactly that (setTimeout) with the scheduled callback, so I could have a call every 6 seconds.

But I guess the CRON job are more reliable since I have access to ctx.waitUntil ?

Or are they equivalent and both method have issues if you try to have more frequent calls ?

@CraigglesO
Copy link
Contributor

If you know for a fact that you will be making a call every 6 seconds, a CRON job is guaranteed to spawn a worker.

The issue with running every 6 seconds on a DO is that at eventually this WILL fail as somewhere down the line cloudflare may evict the DO from memory losing the timeout.

For best results, I recommend bundled-worker (only pay for what CPU time you're using) + CRON.

@wighawag
Copy link
Author

wighawag commented Jun 20, 2022

Thanks for the info!

Re worker, is it best to scheduled the timeout in the worker script or in the Durable Object itself ?

Like should I execute the various setTimeout in the scheduled handler in the worker script
or should I do that in the receiving fetch handler in the DO ?

@CraigglesO
Copy link
Contributor

Ah, no, cron jobs exist outside workers.

You can learn more here. It can only trigger standard issue workers, not DOs directly, although it seems like you don't even need DOs for your use case.

@wighawag
Copy link
Author

wighawag commented Jun 20, 2022

Sorry, I was not very clear.

So I got a DO because I have some state to store and need DO storage properties

The process running in the DO needs to be executed 10 times per minute roughly

I would like to know if I should execute the setTimeout calls (needed to call the process 9 times at intervals of 6 seconds each)

  • in the worker script (which will then fetch the DO, 10 times per minutes)
  • or instead do these setTimeout calls in the DO fetch handler (which would only be called once a minute from the CRON job) and would be responsible to the setTimeout to make the process run 10 times

Hopefully this is more clear

@xortive
Copy link

xortive commented Jun 20, 2022

Hey @CraigglesO! Alarms do in fact support setting times less than 30 seconds in the future, there should not be a restriction in miniflare to limit alarms to at least 30seconds in the future -- the only input restriction is an alarm time of 0 cannot be set. Setting a time in the past will run the alarm as soon as the time is written to disk.

@wighawag Alarms are used to guarantee execution of the alarm handler, even if your DO is evicted. You can definitely set alarms at 6 second intervals, but if you are OK with waiting longer for the alarm to trigger and start the DO again if it is evicted, you could run your alarm at a longer interval up to 60 seconds to keep the DO pinned, and then use setTimeout within the DO to schedule your task to run at a 6 second interval. This would reduce the amount of billable invocations and storage writes, since setTimeout is free :)

If you were to use workers + cron triggers, you'd want to do setTimeout inside of the DO to reduce the amount of DO requests you are billed for. Alarms are easier to use though and seem more suitable for your use case, since they can be scheduled from within your DO.

@xortive xortive added the behaviour mismatch Different behaviour to Workers runtime label Jun 20, 2022
@CraigglesO
Copy link
Contributor

Thanks @xortive for the update! This is HUGE! I'll make a PR for this immediately.
@wighawag - I recommend sticking with DO alarms then for your use case. Xortive gave a great writeup that I think you can use. The fix to have your alarms triggered exactly as scheduled should be up by next week.

@CraigglesO CraigglesO mentioned this issue Jun 21, 2022
2 tasks
@wighawag
Copy link
Author

Thanks @CraigglesO and @xortive !

@CraigglesO
Copy link
Contributor

@xortive - Can you explain how the worker response to a setAlarm(0)? Does it throw an error (and if it does can you give the exact error message) or does it silently fail?

@xortive
Copy link

xortive commented Jun 21, 2022

@CraigglesO It throws TypeError: setAlarm() cannot be called with an alarm time <= 0

@mrbbot
Copy link
Contributor

mrbbot commented Jul 2, 2022

Fixed by #294, will be fixed in the next release. 👍

@mrbbot mrbbot closed this as completed Jul 2, 2022
@mrbbot mrbbot added this to the 2.6.0 milestone Jul 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behaviour mismatch Different behaviour to Workers runtime
Projects
None yet
Development

No branches or pull requests

4 participants