Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

API tuning: two minor changes for usability. #29

Merged
merged 2 commits into from
Aug 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# API References

## Core modules
- Napa.js specific [`global`](./napa-globals.md) variables
- Namespace [`zone`](./zone.md): Multi-thread JavaScript runtime
- Namespace [`transport`](./transport.md): Passing JavaScript values across threads
- Namespace [`store`](./store.md): Sharing JavaScript values across threads
Expand Down
20 changes: 20 additions & 0 deletions docs/api/napa-globals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Napa.js specific global variables

This file describes Napa.js specific globals, please refer to [this documentation](./node-api.md#globals) for Node.js globals.

## `global.napa`
Shortcut to access `napajs` module in all Napa enabled isolates. This is helpful to avoid extra `require` when using `napajs` module in anonymous function during `broadcast` or `execute`.

Example:
```js
var napa = require('napajs');

var zone = napa.zone.create('zone1');

function test() {
global.napa.log('hi');
}

zone.execute(test);

```
12 changes: 6 additions & 6 deletions docs/api/zone.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
- Interface [`Zone`](#zone)
- [`zone.id: string`](#zone-id)
- [`zone.broadcast(code: string): Promise<void>`](#broadcast-code)
- [`zone.broadcast(function: (...args: any[]) => void, args: any[]): Promise<void>`](#broadcast-function)
- [`zone.execute(moduleName: string, functionName: string, args: any[], options?: CallOptions): Promise<Result>`](#execute-by-name)
- [`zone.execute(function: (...args[]) => any, args: any[], options?: CallOptions): Promise<Result>`](#execute-anonymous-function)
- [`zone.broadcast(function: (...args: any[]) => void, args?: any[]): Promise<void>`](#broadcast-function)
- [`zone.execute(moduleName: string, functionName: string, args?: any[], options?: CallOptions): Promise<Result>`](#execute-by-name)
- [`zone.execute(function: (...args[]) => any, args?: any[], options?: CallOptions): Promise<Result>`](#execute-anonymous-function)
- Interface [`CallOptions`](#call-options)
- [`options.timeout: number`](#call-options-timeout)
- Interface [`Result`](#result)
Expand Down Expand Up @@ -119,7 +119,7 @@ zone.broadcast('var state = 0;')
console.log('broadcast failed.')
});
```
### <a name="broadcast-function"></a> zone.broadcast(function: (...args: any[]) => void, args: any[]): Promise\<void\>
### <a name="broadcast-function"></a> zone.broadcast(function: (...args: any[]) => void, args?: any[]): Promise\<void\>
It asynchronously broadcasts an anonymous function with its arguments to all workers, which returns a Promise of void. If any of the workers failed to execute the code, promise will be rejected with an error message.

*Please note that Napa doesn't support closure in 'function' during broadcast.
Expand All @@ -137,7 +137,7 @@ zone.broadcast((state) => {
console.log('broadcast failed:', error)
});
```
### <a name="execute-by-name"></a> zone.execute(moduleName: string, functionName: string, args: any[], options?: CallOptions): Promise\<any\>
### <a name="execute-by-name"></a> zone.execute(moduleName: string, functionName: string, args?: any[], options?: CallOptions): Promise\<any\>
Execute a function asynchronously on arbitrary worker via module name and function name. Arguments can be of any JavaScript type that is [transportable](transport.md#transportable-types). It returns a Promise of [`Result`](#result). If error happens, either bad code, user exception, or timeout is reached, promise will be rejected.

Example: Execute function 'bar' in module 'foo', with arguments [1, 'hello', { field1: 1 }]. 300ms timeout is applied.
Expand All @@ -156,7 +156,7 @@ zone.execute(

```

### <a name="execute-anonymous-function"></a> zone.execute(function: (...args: any[]) => any, args: any[], options?: CallOptions): Promise\<any\>
### <a name="execute-anonymous-function"></a> zone.execute(function: (...args: any[]) => any, args?: any[], options?: CallOptions): Promise\<any\>

Execute an anonymous function asynchronously on arbitrary worker. Arguments can be of any JavaScript type that is [transportable](transport.md#transportable-types). It returns a Promise of [`Result`](#result). If error happens, either bad code, user exception, or timeout is reached, promise will be rejected.

Expand Down
5 changes: 4 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ export { log, memory, metric, runtime, store, transport, zone };

// Add execute proxy to global context.
import { call } from './zone/function-call';
(<any>(global))["__napa_zone_call__"] = call;
(<any>(global))["__napa_zone_call__"] = call;

// Export 'napa' in global for all isolates that require napajs.
(<any>(global))["napa"] = exports;
10 changes: 7 additions & 3 deletions lib/zone/zone-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface FunctionSpec {
transportContext: transport.TransportContext;
}

class ExecuteResult implements zone.Result{
class Result implements zone.Result{

constructor(payload: string, transportContext: transport.TransportContext) {
this._payload = payload;
Expand Down Expand Up @@ -70,13 +70,13 @@ export class ZoneImpl implements zone.Zone {
});
}

public execute(arg1: any, arg2: any, arg3?: any, arg4?: any) : Promise<zone.Result> {
public execute(arg1: any, arg2?: any, arg3?: any, arg4?: any) : Promise<zone.Result> {
let spec : FunctionSpec = this.createExecuteRequest(arg1, arg2, arg3, arg4);

return new Promise<zone.Result>((resolve, reject) => {
this._nativeZone.execute(spec, (result: any) => {
if (result.code === 0) {
resolve(new ExecuteResult(
resolve(new Result(
result.returnValue,
transport.createTransportContext(true, result.contextHandle)));
} else {
Expand Down Expand Up @@ -136,6 +136,10 @@ export class ZoneImpl implements zone.Zone {
options = arg4;
}

if (args == null) {
args = [];
}

// Create a non-owning transport context which will be passed to execute call.
let transportContext: transport.TransportContext = transport.createTransportContext(false);
return {
Expand Down
6 changes: 3 additions & 3 deletions lib/zone/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,21 @@ export interface Zone {
/// <param name="func"> The JS function. </param>
/// <param name="args"> The arguments that will pass to the function. </param>
/// <returns> A promise which is resolved when broadcast completes and rejected when failed. </returns>
broadcast(func: (...args: any[]) => void, args: any[]) : Promise<void>;
broadcast(func: (...args: any[]) => void, args?: any[]) : Promise<void>;

/// <summary> Executes the function on one of the zone workers. </summary>
/// <param name="module"> The module name that contains the function to execute. </param>
/// <param name="func"> The function name to execute. </param>
/// <param name="args"> The arguments that will pass to the function. </param>
/// <param name="options"> Call options, defaults to DEFAULT_CALL_OPTIONS. </param>
/// <returns> A promise of result which is resolved when execute completes, and rejected when failed. </returns>
execute(module: string, func: string, args: any[], options?: CallOptions) : Promise<Result>;
execute(module: string, func: string, args?: any[], options?: CallOptions) : Promise<Result>;

/// <summary> Executes the function on one of the zone workers. </summary>
/// <param name="func"> The JS function to execute. </param>
/// <param name="args"> The arguments that will pass to the function. </param>
/// <param name="options"> Call options, defaults to DEFAULT_CALL_OPTIONS. </param>
/// <returns> A promise of result which is resolved when execute completes, and rejected when failed. </returns>
execute(func: (...args: any[]) => any, args: any[], options?: CallOptions) : Promise<Result>;
execute(func: (...args: any[]) => any, args?: any[], options?: CallOptions) : Promise<Result>;
}

6 changes: 3 additions & 3 deletions test/memory-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('napajs/memory', function() {
});

it('@napa: crtAllocator', () => {
napaZone.execute(NAPA_ZONE_TEST_MODULE, "crtAllocatorTest", []);
napaZone.execute(NAPA_ZONE_TEST_MODULE, "crtAllocatorTest");
});

it('@node: defaultAllocator', () => {
Expand All @@ -45,7 +45,7 @@ describe('napajs/memory', function() {
});

it('@napa: defaultAllocator', () => {
napaZone.execute(NAPA_ZONE_TEST_MODULE, "defaultAllocatorTest", []);
napaZone.execute(NAPA_ZONE_TEST_MODULE, "defaultAllocatorTest");
});

it('@node: debugAllocator', () => {
Expand All @@ -63,7 +63,7 @@ describe('napajs/memory', function() {
});

it('@napa: debugAllocator', () => {
napaZone.execute(NAPA_ZONE_TEST_MODULE, "debugAllocatorTest", []);
napaZone.execute(NAPA_ZONE_TEST_MODULE, "debugAllocatorTest");
});
});
});
36 changes: 18 additions & 18 deletions test/module-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('napajs/module', function () {
describe('resolve', function () {
// TODO: support correct __dirname in anonymous function and move tests from 'resolution-tests.js' here.
it('require.resolve', () => {
return napaZone.execute(__dirname + "/module/resolution-tests.js", "run", []);
return napaZone.execute(__dirname + "/module/resolution-tests.js", "run");
});
});

Expand All @@ -83,15 +83,15 @@ describe('napajs/module', function () {

assert(process.argv.length > 0);
assert(process.argv[0].includes('node'));
}, []);
});
});

it('execPath', () => {
return napaZone.execute(() => {
var assert = require("assert");

assert(process.execPath.includes('node'));
}, []);
});
});

it('env', () => {
Expand All @@ -100,7 +100,7 @@ describe('napajs/module', function () {

process.env.test = "napa-test";
assert.equal(process.env.test, "napa-test");
}, []);
});
});

it('platform', () => {
Expand All @@ -111,7 +111,7 @@ describe('napajs/module', function () {
process.platform == 'darwin' ||
process.platform == 'linux' ||
process.platform == 'freebsd');
}, []);
});
});

it('umask', () => {
Expand All @@ -120,7 +120,7 @@ describe('napajs/module', function () {

var old = process.umask(0);
assert.equal(process.umask(old), 0);
}, []);
});
});

it('chdir', () => {
Expand All @@ -133,7 +133,7 @@ describe('napajs/module', function () {
assert(cwd.includes(process.cwd()));
process.chdir(cwd);
assert.equal(cwd, process.cwd());
}, []);
});
});

it('pid', () => {
Expand All @@ -142,7 +142,7 @@ describe('napajs/module', function () {

assert.notEqual(typeof process.pid, undefined);
assert(!isNaN(process.pid));
}, []);
});
});
});

Expand Down Expand Up @@ -234,7 +234,7 @@ describe('napajs/module', function () {
} else {
assert.equal(path.normalize('a\\b\\..\\c/./d/././.'), "a/c/d");
}
}, []);
});
});

it('resolve', () => {
Expand All @@ -253,7 +253,7 @@ describe('napajs/module', function () {
assert.equal(path.resolve("abc", "efg", "../hij", "./xyz.txt"), process.cwd() + "/abc/hij/xyz.txt");
assert.equal(path.resolve("abc", "/a.txt"), "/a.txt");
}
}, []);
});
});

it('join', () => {
Expand All @@ -266,7 +266,7 @@ describe('napajs/module', function () {
} else {
assert.equal(path.join("/foo", "bar", "baz/asdf", "quux", ".."), "/foo/bar/baz/asdf");
}
}, []);
});
});

// TODO: fix bugs
Expand All @@ -286,7 +286,7 @@ describe('napajs/module', function () {
assert.equal(path.dirname("/etc"), "/");
assert.equal(path.dirname("/etc/passwd"), "/etc");
}
}, []);
});
});

it('basename', () => {
Expand All @@ -305,7 +305,7 @@ describe('napajs/module', function () {
assert.equal(path.basename("/test/abc.txt", ".txt"), "abc");
assert.equal(path.basename("/windows/abc.txt", ".Txt"), "abc.txt");
}
}, []);
});
});

// TODO: fix bugs
Expand All @@ -324,7 +324,7 @@ describe('napajs/module', function () {
assert.equal(path.extname("/test/a.json.txt"), ".txt");
assert.equal(path.extname("/test/a."), ".");
}
}, []);
});
});

it('isAbsolute', () => {
Expand All @@ -345,7 +345,7 @@ describe('napajs/module', function () {
assert.equal(path.isAbsolute("./abc"), false);
assert.equal(path.isAbsolute("abc"), false);
}
}, []);
});
});

it('relative', () => {
Expand All @@ -364,7 +364,7 @@ describe('napajs/module', function () {
assert.equal(path.relative("/test/a", "a.txt"), "../.." + process.cwd() + "/a.txt");
assert.equal(path.relative("/test/a", "/test/"), "..");
}
}, []);
});
});

it('sep', () => {
Expand All @@ -377,7 +377,7 @@ describe('napajs/module', function () {
} else {
assert.equal(path.sep, "/");
}
}, []);
});
});
});

Expand All @@ -388,7 +388,7 @@ describe('napajs/module', function () {
var os = require("os");

assert(os.type() == "Windows_NT" || os.type() == "Darwin" || os.type() == "Linux");
}, []);
});
});
});
});
Expand Down
8 changes: 3 additions & 5 deletions test/napa-zone/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import * as assert from 'assert';
import * as path from "path";
import * as napa from '../../lib/index';
let napaDir: string = path.resolve(__dirname, '../..');

export function bar(input: any) {
return input;
Expand Down Expand Up @@ -95,12 +94,11 @@ export function executeTestFunctionWithTimeout(id: string, waitTimeInMS: number,
export function executeWithTransportableArgs(id: string): Promise<any> {
let zone = napa.zone.get(id);
return new Promise((resolve, reject) => {
zone.execute((allocator: napa.memory.Allocator, napaDir: string) => {
zone.execute((allocator: napa.memory.Allocator) => {
var assert = require("assert");
var napa = require(napaDir);
assert.deepEqual(allocator.handle, napa.memory.crtAllocator.handle);
assert.deepEqual(allocator.handle, (<any>global).napa.memory.crtAllocator.handle);
return 1;
}, [napa.memory.crtAllocator, napaDir])
}, [napa.memory.crtAllocator])
.then ((result: napa.zone.Result) => resolve(result.value))
.catch((error: any) => reject(error));
});
Expand Down
4 changes: 2 additions & 2 deletions test/store-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('napajs/store', function () {
let store2CreationComplete: Promise<napa.zone.Result>;

it('@napa: store.getOrCreate', () => {
store2CreationComplete = napaZone.execute(NAPA_ZONE_TEST_MODULE, "getOrCreateStoreTest", []);
store2CreationComplete = napaZone.execute(NAPA_ZONE_TEST_MODULE, "getOrCreateStoreTest");
});

it('@node: store.get', async () => {
Expand All @@ -46,7 +46,7 @@ describe('napajs/store', function () {
});

it('@napa: store.get', () => {
napaZone.execute(NAPA_ZONE_TEST_MODULE, "getStoreTest", []);
napaZone.execute(NAPA_ZONE_TEST_MODULE, "getStoreTest");
});

it('simple types: set in node, get in node', () => {
Expand Down
Loading