зеркало из https://github.com/microsoft/napajs.git
Add an example that uses napa.sync.Lock (#179)
* Add example for napa/sync/Lock * Update link to sync.md * Update example and rename to 'synchronized-loading' * Update README and API docs: add synchronized loading example * Resolve comments * fix grammer
This commit is contained in:
Родитель
0f699c541b
Коммит
f152547def
|
@ -31,9 +31,10 @@ zone1.execute(
|
||||||
```
|
```
|
||||||
More examples:
|
More examples:
|
||||||
* [Estimate PI in parallel](./examples/tutorial/estimate-pi-in-parallel)
|
* [Estimate PI in parallel](./examples/tutorial/estimate-pi-in-parallel)
|
||||||
|
* [Max sub-matrix of 1s with layered parallelism](./examples/tutorial/max-square-sub-matrix)
|
||||||
* [Parallel Quick Sort](./examples/tutorial/parallel-quick-sort)
|
* [Parallel Quick Sort](./examples/tutorial/parallel-quick-sort)
|
||||||
* [Recursive Fibonacci with multiple JavaScript threads](./examples/tutorial/recursive-fibonacci)
|
* [Recursive Fibonacci with multiple JavaScript threads](./examples/tutorial/recursive-fibonacci)
|
||||||
* [Max sub-matrix of 1s with layered parallelism](./examples/tutorial/max-square-sub-matrix)
|
* [Synchronized loading](./examples/tutorial/synchronized-loading)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Multi-threaded JavaScript runtime
|
- Multi-threaded JavaScript runtime
|
||||||
|
|
|
@ -35,6 +35,9 @@ catch(error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
An example [Synchronized Loading](./../../examples/tutorial/synchronized-loading) demonstrated how to implement a shared, lazy-loading phone book.
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
### <a name="lock-guard-func-promise-any-promise-any"></a> lock.guard(func: () => Promise\<any>): Promise\<any>
|
### <a name="lock-guard-func-promise-any-promise-any"></a> lock.guard(func: () => Promise\<any>): Promise\<any>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Synchronized loading
|
||||||
|
This example implements a shared phone book component. The component will not load data until the first lookup request happens. When it starts to load data, it ensures the loading will run only once.
|
||||||
|
|
||||||
|
The component is implemented using lazy-loading pattern with the use of [`napa.sync.Lock`](./../../../docs/api/sync.md#interface-lock).
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
1. Go to directory of "examples/tutorial/synchronized-loading"
|
||||||
|
2. Run "npm install" to install napajs
|
||||||
|
3. Run "node synchronized-loading.js"
|
||||||
|
|
||||||
|
## Program output
|
||||||
|
The output below shows one possible result. The sequence of the output may be different but the data loading will always run once only.
|
||||||
|
```
|
||||||
|
[lookupPhoneNumber] Start to lookup phone number of david.
|
||||||
|
[lookupPhoneNumber] Start to lookup phone number of wade.
|
||||||
|
[load_data] loading...
|
||||||
|
[lookupPhoneNumber] Start to lookup phone number of lisa.
|
||||||
|
[lookupPhoneNumber] wade : <not found>.
|
||||||
|
[lookupPhoneNumber] lisa : 567-888-9999.
|
||||||
|
[lookupPhoneNumber] david : 123-444-5555.
|
||||||
|
[run] All operations are completed.
|
||||||
|
```
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "napajs-tutorial",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"author": "napajs",
|
||||||
|
"main": "./synchronized-loading.js",
|
||||||
|
"dependencies": {
|
||||||
|
"napajs": ">= 0.1.8"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"ashley": "123-456-7890",
|
||||||
|
"david": "123-444-5555",
|
||||||
|
"lisa": "567-888-9999",
|
||||||
|
"tony": "456-789-0000"
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
const napa = require("napajs");
|
||||||
|
const store = napa.store.getOrCreate('my-phone-book');
|
||||||
|
|
||||||
|
const initialize = function () {
|
||||||
|
store.set('_loadLock', napa.sync.createLock());
|
||||||
|
}
|
||||||
|
|
||||||
|
const load_data = function () {
|
||||||
|
// load data. This function should run only once.
|
||||||
|
console.log('[load_data] loading...');
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
let phoneBookData = JSON.parse(fs.readFileSync('./phone-book-data.json').toString());
|
||||||
|
|
||||||
|
for (let name in phoneBookData) {
|
||||||
|
store.set(name, phoneBookData[name]);
|
||||||
|
}
|
||||||
|
store.set('_loaded', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let loaded = false;
|
||||||
|
const lookup = function (name) {
|
||||||
|
if (!loaded) {
|
||||||
|
const lock = store.get('_loadLock');
|
||||||
|
lock.guardSync(function() {
|
||||||
|
if (!store.get('_loaded')) {
|
||||||
|
load_data();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return store.get(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.initialize = initialize;
|
||||||
|
module.exports.lookup = lookup;
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
const napa = require("napajs");
|
||||||
|
|
||||||
|
// Change this value to control number of napa workers initialized.
|
||||||
|
const NUMBER_OF_WORKERS = 4;
|
||||||
|
|
||||||
|
// Create a napa zone with number_of_workers napa workers.
|
||||||
|
const zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
// Initialize the phone book component
|
||||||
|
const phoneBook = require('./phone-book');
|
||||||
|
phoneBook.initialize();
|
||||||
|
|
||||||
|
// Setup all workers with functions to be executed.
|
||||||
|
zone.broadcast(' \
|
||||||
|
var napa = require("napajs"); \
|
||||||
|
var zone = napa.zone.get("zone"); \
|
||||||
|
var phoneBook = require("./phone-book"); \
|
||||||
|
');
|
||||||
|
zone.broadcast(lookupPhoneNumber.toString());
|
||||||
|
|
||||||
|
var tasks = [];
|
||||||
|
tasks.push(zone.execute('', 'lookupPhoneNumber', ['david']));
|
||||||
|
tasks.push(zone.execute('', 'lookupPhoneNumber', ['lisa']));
|
||||||
|
tasks.push(zone.execute('', 'lookupPhoneNumber', ['wade']));
|
||||||
|
|
||||||
|
Promise.all(tasks).then(function () {
|
||||||
|
console.log('[run] All operations are completed.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function lookupPhoneNumber(name) {
|
||||||
|
console.log(`[lookupPhoneNumber] Start to lookup phone number of ${name}.`);
|
||||||
|
var n = phoneBook.lookup(name);
|
||||||
|
console.log(`[lookupPhoneNumber] ${name} : ${n ? n : '<not found>'}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run program.
|
||||||
|
run();
|
Загрузка…
Ссылка в новой задаче