Skip to content

Commit 3719bd3

Browse files
authored
Remove AsyncTask (#8)
We can revisit AsyncTask after the AsyncLocal is accepted.
1 parent 5be86f9 commit 3719bd3

File tree

1 file changed

+0
-122
lines changed

1 file changed

+0
-122
lines changed

README.md

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -371,120 +371,6 @@ export function queryDatabase(query) {
371371
In this way, we can have a context value propagated across the async execution
372372
flow and keep track of the value without any other efforts.
373373
374-
## AsyncTask
375-
376-
<!--
377-
TODO: how do we determine a task is not going to be used anymore?
378-
379-
Fundamentally if an object is going to be finalized, it can not be used afterward.
380-
If an async task says it is disposed, `runInAsyncScope` throws once disposed.
381-
-->
382-
383-
While multiplexing platform provided async resources is not a rare case,
384-
how does the async locals get properly propagated?
385-
386-
For library owners, `AsyncTask`s are preferred to indicate new synthetic async
387-
tasks' schedule.
388-
389-
```js
390-
class AsyncTask {
391-
constructor();
392-
runInAsyncScope(callback[, thisArg, ...args]);
393-
}
394-
```
395-
396-
`AsyncTask.runInAsyncScope` calls the provided function with the provided
397-
arguments in the async context of the async task. This will establish
398-
the async context, call the function, and then restore the original async
399-
context.
400-
401-
### Using `AsyncTask`
402-
403-
```js
404-
// Callback based arbitrary asynchronous API.
405-
function connect(port, host) {
406-
let nextId = 0;
407-
const requestResponseMap = new Map();
408-
409-
// Establish the connection, the client is linked to the current async context.
410-
const client = net.createConnection({ host, port });
411-
client.on('connect', () => {
412-
console.log('connected to server');
413-
});
414-
client.on('end', () => {
415-
console.log('disconnected from server');
416-
});
417-
418-
// the client is created at the async context of `connect`,
419-
// the listeners will be triggered at the async context of the
420-
// client initiating async context.
421-
client.on('data', (res) => {
422-
const { id, data } = JSON.parse(res.toString('utf8'));
423-
const req = requestResponseMap.get(id);
424-
if (req == null) {
425-
console.log('unknown response with id(%s)', id);
426-
return;
427-
}
428-
429-
// The req.handler callback is called under the async context of client
430-
// listeners.
431-
req.handler(data);
432-
});
433-
return {
434-
send: (data, handler) => {
435-
const id = nextId++;
436-
client.write(JSON.stringify({ id, data }));
437-
requestResponseMap.set(id, { handler });
438-
}
439-
}
440-
}
441-
442-
// AsyncTask & Promise based connection wrapper.
443-
class DatabaseConnection {
444-
constructor(port, host) {
445-
// Initialize connection, possibly in root async context.
446-
this.socket = connect(port, host);
447-
}
448-
449-
async query(search) {
450-
const task = new QueryTask(search)
451-
return new Promise((resolve, reject) => {
452-
this.socket.send(query, (result) => {
453-
// This async context is triggered by `DatabaseConnection` which is
454-
// not linked to initiator of `DatabaseConnection.query`.
455-
task.runInAsyncScope(() => {
456-
// This async context linked to the initiator of
457-
// `DatabaseConnection.query`.
458-
// PromiseResolution -> QueryTask -> `DatabaseConnection.query`
459-
resolve(result)
460-
});
461-
});
462-
});
463-
}
464-
}
465-
466-
// A simple task that extends AsyncTask.
467-
class QueryTask extends AsyncTask {
468-
constructor(search) {
469-
// link async task to current execution async context
470-
super();
471-
this.search = search;
472-
}
473-
}
474-
```
475-
476-
In the example above, `DatabaseConnection` can be established at root async
477-
context (or any other context). With `AsyncTask`, each call to
478-
`DatabaseConnection.query` will schedule an async task, which will be linked
479-
to its initiator async context (may not be the one establishing
480-
`DatabaseConnection`). And at the resolution of socket, the contexts are
481-
propagated by the `DatabaseConnection`, which is linked to its initiating
482-
async context, so the async context has to be re-established by
483-
`AsyncTask.runInAsyncScope`.
484-
485-
In this way, we can propagate correct async context flows on multiplexing
486-
single host platform provided async resource.
487-
488374
# Prior Arts
489375
490376
## zones.js
@@ -525,14 +411,6 @@ window.onload = loadZone.wrap(e => { ... });
525411
526412
then at all those sites, `Zone.current` would be equal to `loadZone`.
527413
528-
Compared to this proposal, `Zone` acts similar to the `AsyncTask` object in
529-
this proposal. However, there are differences of the basic concept between
530-
those two definitions. The major motivation of `AsyncTask` is to declare a
531-
logical connection between multiple asynchronously executions. With these
532-
connections, the only use case in this proposal is to propagate the values of
533-
AsyncLocal correctly. However, many features still can be built on top of the
534-
connections built by `AsyncTask`.
535-
536414
## Node.js `domain` module
537415
538416
Domain's global central active domain can be consumed by multiple endpoints

0 commit comments

Comments
 (0)