-
Notifications
You must be signed in to change notification settings - Fork 465
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This class provides a wrapper for the following custom asynchronous operation APIs. - napi_async_init() - napi_async_destroy() - napi_make_callback()
- Loading branch information
Showing
10 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
# AsyncContext | ||
|
||
The [AsyncWorker](async_worker.md) class may not be appropriate for every scenario, because with | ||
those the async execution still happens on the main event loop. When using any | ||
other async mechanism, introducing a new class `AsyncContext` is necessary to | ||
ensure an async operation is properly tracked by the runtime. | ||
The `AsyncContext` class provides `MakeCallback()` method to properly restore | ||
the correct async execution context. | ||
|
||
## Methods | ||
|
||
### MakeCallback | ||
|
||
This method is used to call from native code back into JavaScript after | ||
returning from an async operation (when there is no other script on the stack). | ||
|
||
```cpp | ||
Value MakeCallback() const | ||
``` | ||
|
||
Returns a `Value` representing the JavaScript object returned. | ||
|
||
### MakeCallback | ||
|
||
This method is used to call from native code back into JavaScript after | ||
returning from an async operation (when there is no other script on the stack). | ||
|
||
```cpp | ||
Value MakeCallback(const Object& receiver) const | ||
``` | ||
- `[in] receiver`: The `this` object passed to the callback. | ||
Returns a `Value` representing the JavaScript object returned. | ||
### MakeCallback | ||
This method is used to call from native code back into JavaScript after | ||
returning from an async operation (when there is no other script on the stack). | ||
```cpp | ||
Value MakeCallback(const std::initializer_list<napi_value>& args) const | ||
``` | ||
|
||
- `[in] args`: Initializer list of JavaScript values as `napi_value` | ||
representing the arguments to the callback. | ||
|
||
Returns a `Value` representing the JavaScript object returned. | ||
|
||
### MakeCallback | ||
|
||
This method is used to call from native code back into JavaScript after | ||
returning from an async operation (when there is no other script on the stack). | ||
|
||
```cpp | ||
Value MakeCallback(const Object& receiver, const std::initializer_list<napi_value>& args) const | ||
``` | ||
- `[in] receiver`: The `this` object passed to the callback. | ||
- `[in] args`: Initializer list of JavaScript values as `napi_value` | ||
representing the arguments to the callback. | ||
Returns a `Value` representing the JavaScript object returned. | ||
### Constructor | ||
Creates a new `AsyncContext`. | ||
```cpp | ||
explicit AsyncContext(const char* resource_name, const Function& callback); | ||
``` | ||
|
||
- `[in] resource_name`: Null-terminated strings that represents the | ||
identifier for the kind of resource that is being provided for diagnostic | ||
information exposed by the async_hooks API. | ||
- `[in] callback`: The function which will be called when an asynchronous | ||
operations ends. | ||
|
||
Returns an AsyncContext instance which can later make the given callback by | ||
`MakeCallback()` method. | ||
|
||
### Constructor | ||
|
||
Creates a new `AsyncContext`. | ||
|
||
```cpp | ||
explicit AsyncContext(const char* resource_name, const Object& resource, const Function& callback); | ||
``` | ||
- `[in] resource_name`: Null-terminated strings that represents the | ||
identifier for the kind of resource that is being provided for diagnostic | ||
information exposed by the async_hooks API. | ||
- `[in] resource`: Object associated with the asynchronous operation that | ||
will be passed to possible async_hooks. | ||
- `[in] callback`: The function which will be called when an asynchronous | ||
operations ends. | ||
Returns an AsyncContext instance which can later make the given callback by | ||
`MakeCallback()` method. | ||
### Destructor | ||
The async context to be destroyed. | ||
```cpp | ||
virtual ~AsyncContext(); | ||
``` | ||
|
||
## Example | ||
|
||
```cpp | ||
#include "napi.h" | ||
#include "uv.h" | ||
|
||
using namespace Napi; | ||
|
||
void HeavyWork(uv_work_t* request) { | ||
... | ||
} | ||
|
||
void DidHeavyWork(uv_work_t* request, int status) { | ||
HandleScope scope; | ||
AsyncContext* context = static_cast<AsyncContext*>(request->data); | ||
|
||
// Run the callback in the async context. | ||
context->MakeCallback(); | ||
|
||
// The async context is destroyed. | ||
delete context; | ||
} | ||
|
||
void RunAsync(const CallbackInfo& info) { | ||
Function callback = info[0].As<Function>(); | ||
|
||
// Creat a new async context instance. | ||
AsyncContext* new AsyncContext("TestResource", callback); | ||
|
||
// You can queue a task with the async context to the custom async mechanism. | ||
// This example is using `libuv` as custom async mechanism but it can be | ||
// anything. | ||
uv_work_t* request = new uv_work_t(); | ||
request->data = context; | ||
uv_queue_work( | ||
uv_default_loop(), | ||
request, | ||
HeavyWork, | ||
reinterpret_cast<uv_after_work_cb>(DidHeavyWork)); | ||
} | ||
|
||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include "napi.h" | ||
|
||
using namespace Napi; | ||
|
||
namespace { | ||
|
||
static AsyncContext* context; | ||
|
||
static void CreateAsyncContext(const CallbackInfo& info) { | ||
Function callback = info[0].As<Function>(); | ||
context = new AsyncContext("TestResource", callback); | ||
} | ||
|
||
static void MakeCallback(const CallbackInfo& info) { | ||
context->MakeCallback(); | ||
delete context; | ||
} | ||
|
||
} // end anonymous namespace | ||
|
||
Object InitAsyncContext(Env env) { | ||
Object exports = Object::New(env); | ||
exports["createAsyncContext"] = Function::New(env, CreateAsyncContext); | ||
exports["makeCallback"] = Function::New(env, MakeCallback); | ||
return exports; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict'; | ||
const buildType = process.config.target_defaults.default_configuration; | ||
const assert = require('assert'); | ||
|
||
test(require(`./build/${buildType}/binding.node`)); | ||
test(require(`./build/${buildType}/binding_noexcept.node`)); | ||
|
||
function test(binding) { | ||
let called = false; | ||
binding.asynccontext.createAsyncContext(function() { | ||
called = true; | ||
}); | ||
assert.strictEqual(called, false); | ||
binding.asynccontext.makeCallback(); | ||
assert.strictEqual(called, true); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters