зеркало из 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:
|
||||
* [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)
|
||||
* [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
|
||||
- Multi-threaded JavaScript runtime
|
||||
|
|
|
@ -35,6 +35,9 @@ catch(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>
|
||||
|
||||
|
|
|
@ -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();
|
Загрузка…
Ссылка в новой задаче