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

🚀 Feature Request: add test helper to programmatically hibernate a Durable Object #5423

Open
nvie opened this issue Mar 28, 2024 · 5 comments
Labels
enhancement New feature or request vitest Relating to the Workers Vitest integration

Comments

@nvie
Copy link

nvie commented Mar 28, 2024

Describe the solution

It'd be great to have a test helper to trigger a durable object to hibernate in unit tests, so that the next time a fetch() or Websocket message is received, it will re-run the constructor and restore websockets.

  // Hypothetical new API
import { hibernateDurableObject } from "cloudflare:test";  // ✨🙏✨

test("waking up from hibernation", async () => {
  await SELF.fetch("http://example.com/ws");

  await hibernateDurableObject(stub);

  const numSockets = await runInDurableObject(stub, (instance) => instance.getWebSockets().length);
  expect(numSockets).toBe(1);
});

(Currently, the only option seems to be await sleep(10_000) to trigger hibernation in unit tests?)

Context: https://discord.com/channels/595317990191398933/1218150105777963101/1222851857601531997

@nvie nvie added the enhancement New feature or request label Mar 28, 2024
@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Mar 28, 2024
@mrbbot mrbbot added the vitest Relating to the Workers Vitest integration label Mar 28, 2024
@mrbbot mrbbot moved this from Untriaged to Backlog in workers-sdk Mar 28, 2024
@mrbbot mrbbot self-assigned this Mar 28, 2024
@mrbbot
Copy link
Contributor

mrbbot commented Apr 4, 2024

Recording for posterity, reproduction of segfault when hibernating with 10 second wait: https://github.com/nvie/ws-promise-bug-repro/blob/hibernate/durable-objects/test/illustrate-bug.test.ts#L22-L24.

@nvie
Copy link
Author

nvie commented Apr 11, 2024

cc @MellowYarker

This feature request is very much related to the segfault issue (see cloudflare/workerd#1422 (comment)). Fixing the segfault would make testing hibernation possible at all.

But having this proposed programmatic hibernateDurableObject() API would be really amazing to take it a step further, as it would take testing hibernation related code from theoretically possible to practically feasible. Because once that API exists, we no longer have to rely on actual wall clock time passing in our test suite, which makes them unnecessarily slow. The API that @mrbbot proposed in cloudflare/workerd#904 (comment) would be really really useful to us. (And while at it, maybe it would be possible to also have an explicit way to trigger an evictDurableObject() API?)

To us, this is one of our biggest pain points at the moment, and finding a robust and reliable solution for this would be huge. Happy to discuss details if you have any questions! 🙏

@MellowYarker
Copy link

@nvie I think it would be a lot easier to make the timeout configurable than to provide a new API for forcing hibernation. You could just set the timeout to be 100ms (with the default being 10 sec as in production).

The current hibernation process depends on there being no active requests, and having a request that triggers hibernation would break that model. The Workerd implementation tries to mimic what happens in production, and introducing an API that breaks the fundamental assumption would likely make the implementations deviate and introduce discrepancies/other bugs.

Would you be alright with having the time limit be configurable?

@nvie
Copy link
Author

nvie commented Apr 23, 2024

Would you be alright with having the time limit be configurable?

Yeah, I can see how that will be easier indeed. Do you think it's possible to make it configurable on a per-test basis somehow? We have tests where we don't want to deal with implicit hibernation and some tests where we deliberately want to trigger/test it. Ideally we can control it and not make the behavior under test dependent on timing too much. Finding the exact right timing will be tricky if it's just one global setting.

How you would recommend going about that?

@MellowYarker
Copy link

Do you think it's possible to make it configurable on a per-test basis somehow?

I definitely see the appeal, though I suspect this isn't feasible right now. @petebacondarwin sorry to bug you, but I see you reviewed some of Brendan's PRs related to local dev testing. Do you know if we can configure specific workers/bindings (or even Workerd) for individual tests? If not, do you know who might know?

Part of me thinks it might be possible to set per DO namespace, though I don't know how just yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request vitest Relating to the Workers Vitest integration
Projects
None yet
Development

No branches or pull requests

3 participants