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

Commit

Permalink
Made some fixes in transport-js-builtins.md (#271)
Browse files Browse the repository at this point in the history
* Update memory.md

* Update transport-js-builtins.md

* Update transport-js-builtins.md

* Update transport-js-builtins.md

* Update README.md
  • Loading branch information
pujanm authored and helloshuangzi committed Oct 29, 2018
1 parent ff42fcb commit 02eb70c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 25 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ You can contribute to Napa.js in following ways:
* Contribute to core module compatibility with Node.
* Contribute bug fixes.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [email protected] with any additional questions or comments.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).<br> For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [email protected] with any additional questions or comments.

# License
Copyright (c) Microsoft Corporation. All rights reserved.
Expand Down
2 changes: 1 addition & 1 deletion docs/api/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Memory allocation in C++ addon is tricky. A common pitfall is to allocate memory

There are also advanced scenarios that user want to customize memory allocation. Napa.js provides APIs for customizing memory allocator as well.

### Recommended way of allocate memory.
### Recommended way of allocate memory
TBD

### Customize memory allocation
Expand Down
46 changes: 23 additions & 23 deletions docs/design/transport-js-builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ The abstraction of 'Transportable' lies in the center of Napa.js to efficiently

The incentive of this design is to provide a solution to make JavaScript standard built-in objects transportable with requirements listed in the Goals section.

At the first stage, we will focus on an efficient solution to share data between Napa workers. Basically, it is about making SharedArrayBuffer / TypedArray / DataView transportable.
At the first stage, we will focus on an efficient solution to share data between Napa workers. Basically, it is about making *SharedArrayBuffer / TypedArray / DataView* transportable.

## Goals
Make Javascript standard built-in objects transportable with
- An efficient way to share structured data, like SharedArrayBuffer, among Napa workers
- An efficient way to share structured data, like *SharedArrayBuffer*, among Napa workers
- Consistent APIs with ECMA standards
- No new abstraction layers for the simplest usage
- The least new concepts for advanced usage
- A scalable solution to make all JavaScript standard built-in objects transportable, avoiding to make them transportable one by one.

## Example
The below example shows how SharedArrayBuffer object is transported across multiple Napa workers. It will print the TypedArray 'ta' created from a SharedArrayBuffer, with all its elements set to 100 from different Napa workers.
The below example shows how *SharedArrayBuffer* object is transported across multiple Napa workers. It will print the TypedArray 'ta' created from a *SharedArrayBuffer*, with all its elements set to 100 from different Napa workers.
```js
var napa = require("napajs");
var zone = napa.zone.create('zone', { workers: 4 });
Expand Down Expand Up @@ -48,25 +48,25 @@ run();
Here we just give a high-level description of the solution. Its API will go to [docs/api/transport](https://github.com/Microsoft/napajs/blob/master/docs/api/transport.md).
- V8 provides its value-serialization mechanism by ValueSerializer and ValueDeserializer, which is compatible with the HTML structured clone algorithm. It is a horizontal solution to serialize / deserialize JavaScript objects. ValueSerializer::Delegate and ValueDeserializer::Delegate are their inner class. They work as base classes from which developers can deprive to customize some special handling of external / shared resources, like memory used by a SharedArrayBuffer object.

- napa::v8_extensions::ExternalizedContents
- It holds the externalized contents (memory) of a SharedArrayBuffer instance once it is serialized via napa::v8_extensions::Utils::SerializeValue().
- Only 1 instance of ExternalizedContents will be generated for each SharedArrayBuffer. If a SharedArrayBuffer had been externalized, it will reuse the ExternalizedContents instance created before in napa::v8_extensions::Utils::SerializeValue()
- **napa::v8_extensions::ExternalizedContents**
- It holds the externalized contents (memory) of a SharedArrayBuffer instance once it is serialized via *napa::v8_extensions::Utils::SerializeValue()*.
- Only 1 instance of ExternalizedContents will be generated for each SharedArrayBuffer. If a SharedArrayBuffer had been externalized, it will reuse the ExternalizedContents instance created before in *napa::v8_extensions::Utils::SerializeValue()*.

- napa::v8_extensions::SerializedData
- It is generated by napa::v8_extensions::Utils::SerializeValue(). It holds the serialized data of a JavaScript object, which is required during its deserialization.
- **napa::v8_extensions::SerializedData**
- It is generated by *napa::v8_extensions::Utils::SerializeValue()*. It holds the serialized data of a JavaScript object, which is required during its deserialization.

- BuiltInObjectTransporter
- napa::v8_extensions::Serializer, derived from v8::ValueSerializer::Delegate
- napa::v8_extensions::Deserializer, derived from v8::ValueDeserializer::Delegate
- static std::shared_ptr<SerializedData> v8_extensions::Utils::SerializeValue(Isolate* isolate, Local<Value> value)
- Generate the SerializedData instance given an input value.
- If any SharedArrayBuffer instances exist in the input value, their ExternalizedContents instances will be generated and attached to the ShareArrayBuffer instances respectively.
- static MaybeLocal<Value> v8_extensions::Utils::DeserializeValue(Isolate* isolate, std::shared_ptr<SerializedData> data);
- Restore a JavaScript value from its SerializedData instance generated by v8_extensions::Utils::SerializeValue() before.
- **BuiltInObjectTransporter**
- **napa::v8_extensions::Serializer, derived from v8::ValueSerializer::Delegate**
- **napa::v8_extensions::Deserializer, derived from v8::ValueDeserializer::Delegate**
- **static std::shared_ptr\<SerializedData> v8_extensions::Utils::SerializeValue(Isolate\* isolate, Local\<Value> value);**
- Generate the *SerializedData* instance given an input value.
- If any *SharedArrayBuffer* instances exist in the input value, their *ExternalizedContents* instances will be generated and attached to the *ShareArrayBuffer* instances respectively.
- **static MaybeLocal\<Value> v8_extensions::Utils::DeserializeValue(Isolate\* isolate, std::shared_ptr\<SerializedData> data);**
- Restore a JavaScript value from its SerializedData instance generated by *v8_extensions::Utils::SerializeValue()* before.

- Currently, Napa relies on Transportable API and a registered constructor to make an object transportable. In [marshallTransform](https://github.com/Microsoft/napajs/blob/master/lib/transport/transport.ts), when a JavaScript object is detected to have a registered constructor, it will go with Napa way to marshall this object with the help of a TransportContext object, otherwise a non-transportable error is thrown.
- Currently, Napa relies on Transportable API and a registered constructor to make an object transportable. In [marshallTransform](https://github.com/Microsoft/napajs/blob/master/lib/transport/transport.ts), when a JavaScript object is detected to have a registered constructor, it will go with Napa way to marshall this object with the help of a **TransportContext** object, otherwise a non-transportable error is thrown.

- Instead of throwing an error when no registered constructor is detected, the BuiltInObjectTransporter can help handle this object. We can use a whitelist of object types to restrict this solution to those verified types at first.
- Instead of throwing an error when no registered constructor is detected, the **BuiltInObjectTransporter** can help handle this object. We can use a whitelist of object types to restrict this solution to those verified types at first.
```js
export function marshallTransform(jsValue: any, context: transportable.TransportContext): any {
if (jsValue != null && typeof jsValue === 'object' && !Array.isArray(jsValue)) {
Expand Down Expand Up @@ -117,14 +117,14 @@ function unmarshallTransform(payload: any, context: transportable.TransportConte
- Received SAB transported from another Napa workers, including node zone of Napa.
- TypedArray or DataView created from the original SAB or a received SAB.

- The life cycle extension during transportation is achieved through the ExternalizedContents SharedPtrWrap of the SAB.
- When a SAB is transported for the first time, it will be externalized and its ExternalizedContents will be stored in its SerializedData. At the same time, the SharedPtrWrap of the ExternalizedContents will be set to the '_externalized' property of the original SAB.
- The life cycle extension during transportation is achieved through the *ExternalizedContents* *SharedPtrWrap* of the SAB.
- When a SAB is transported for the first time, it will be externalized and its ExternalizedContents will be stored in its *SerializedData*. At the same time, the *SharedPtrWrap* of the *ExternalizedContents* will be set to the '_externalized' property of the original SAB.

- When a SAB is transported for the second time or later, it will skip externalization and find its ExternalizedContents from its '_externalized' property, and store it to its SerializedData.
- When a SAB is transported for the second time or later, it will skip externalization and find its *ExternalizedContents* from its '_externalized' property, and store it to its *SerializedData*.

- When a Napa worker tries to restore a transported SAB, it will find the pre-stored ExternalizedContents, and create a SharedPtrWrap for it, then set it to the to-be-restored SAB.
- When a Napa worker tries to restore a transported SAB, it will find the pre-stored *ExternalizedContents*, and create a *SharedPtrWrap* for it, then set it to the to-be-restored SAB.

- The life cycle of the SharedArrayBuffer is extended by the SharedPtrWrap of its ExternalizedContents.
- The life cycle of the *SharedArrayBuffer* is extended by the *SharedPtrWrap* of its *ExternalizedContents*.


## Constraints
Expand Down

0 comments on commit 02eb70c

Please sign in to comment.