Files
bun.sh/test/js/node/worker_threads/worker-async-dispose.test.ts
robobun b2351bbb4e Add Symbol.asyncDispose to Worker in worker_threads (#22064)
## Summary

- Implement `Symbol.asyncDispose` for the `Worker` class in
`worker_threads` module
- Enables automatic resource cleanup with `await using` syntax
- Calls `await this.terminate()` to properly shut down workers when they
go out of scope

## Implementation Details

The implementation adds a simple async method to the Worker class:

```typescript
async [Symbol.asyncDispose]() {
  await this.terminate();
}
```

This allows workers to be used with the new `await using` syntax for
automatic cleanup:

```javascript
{
  await using worker = new Worker('./worker.js');
  // worker automatically terminates when leaving this scope
}
```

## Test Plan

- [x] Added comprehensive tests for `Symbol.asyncDispose` functionality
- [x] Tests verify the method exists and returns undefined
- [x] Tests verify `await using` syntax works correctly for automatic
worker cleanup
- [x] All new tests pass
- [x] Existing worker_threads functionality remains intact

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-08-22 19:59:15 -07:00

59 lines
1.5 KiB
TypeScript

import { expect, test } from "bun:test";
import { Worker } from "worker_threads";
test("Worker implements Symbol.asyncDispose", async () => {
const worker = new Worker(
`
const { parentPort } = require("worker_threads");
parentPort?.postMessage("ready");
`,
{ eval: true },
);
// Wait for the worker to be ready
await new Promise(resolve => {
worker.on("message", msg => {
if (msg === "ready") {
resolve(msg);
}
});
});
// Test that Symbol.asyncDispose exists and is a function
expect(typeof worker[Symbol.asyncDispose]).toBe("function");
// Test that calling Symbol.asyncDispose terminates the worker
const disposeResult = await worker[Symbol.asyncDispose]();
expect(disposeResult).toBeUndefined();
});
test("Worker can be used with await using", async () => {
let workerTerminated = false;
{
await using worker = new Worker(
`
const { parentPort } = require("worker_threads");
parentPort?.postMessage("hello from worker");
`,
{ eval: true },
);
// Listen for worker exit to confirm termination
worker.on("exit", () => {
workerTerminated = true;
});
// Wait for the worker message to ensure it's running
await new Promise(resolve => {
worker.on("message", resolve);
});
// Worker should automatically terminate when leaving this block via Symbol.asyncDispose
}
// Give a moment for the exit event to be emitted
await new Promise(resolve => setTimeout(resolve, 100));
expect(workerTerminated).toBe(true);
});