ciorent 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +83 -73
  2. package/index.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,53 +1,42 @@
1
1
  A low-overhead, cross-runtime concurrency library.
2
2
 
3
- # Usage
4
- Pausing to prioritize an asynchronous task:
3
+ # Examples
4
+ ## Semaphore
5
+ Semaphore is a concurrency primitive used to control access to a common resource by multiple processes.
6
+
5
7
  ```ts
8
+ import * as semaphore from 'ciorent/semaphore';
6
9
  import * as cio from 'ciorent';
7
10
 
8
- // Expensive sync task
9
- const task1 = async () => {
10
- let x = 0;
11
- for (let i = 0; i < (Math.random() + 15) * 1e7; i++) {
12
- // Occasional pausing
13
- if (i % 2e6 === 0)
11
+ // Only allow 2 of these tasks to run concurrently
12
+ const task = semaphore.task(
13
+ semaphore.init(2),
14
+ async (task: number) => {
15
+ for (let i = 1; i <= 5; i++) {
16
+ console.log('Task', task, 'iteration', i);
14
17
  await cio.pause;
18
+ }
15
19
 
16
- x += Math.random() * 32 + i * Math.round(Math.random() * 16);
20
+ console.log('Task', task, 'end');
17
21
  }
18
- console.log('Finish task 1:', x);
19
- };
20
-
21
- // Short async task
22
- const task2 = async () => {
23
- console.log('Fetch start', performance.now().toFixed(2) + 'ms');
24
- const txt = await fetch('http://example.com');
25
- console.log('Fetch status', txt.status);
26
- };
22
+ );
27
23
 
28
- // Task 2 will not get blocked by task 1
29
- task1();
30
- task2();
24
+ // Try to run 6 tasks with 4 tasks running concurrently
25
+ cio.concurrent(6, task, 4);
31
26
  ```
32
27
 
33
- Sleep for a duration:
34
- ```ts
35
- import * as cio from 'ciorent';
36
-
37
- await cio.sleep(1000);
38
- console.log('Slept for about 1s');
39
- ```
28
+ ## Channel
29
+ Channel is a synchronization primitive via message passing. A message may be sent over a channel, and another process is able to receive messages sent over a channel it has a reference to.
40
30
 
41
- Go-like channels for synchronizations:
42
31
  ```ts
43
32
  import * as channel from 'ciorent/channel';
44
- import * as cio from 'ciorent';
45
33
 
46
34
  const c = channel.init<number>();
35
+ const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
47
36
 
48
37
  const run = async () => {
49
38
  for (let i = 0; i < 10; i++) {
50
- await cio.sleep(10);
39
+ await sleep(10);
51
40
  channel.send(c, i);
52
41
  console.log('Sent', i);
53
42
  }
@@ -77,7 +66,7 @@ console.log('Starting...');
77
66
  ```
78
67
 
79
68
  ## Latch
80
- A latch is a synchronization tool that allows one or more threads to wait until a specific condition is met.
69
+ Latch is a synchronization primitive that allows one process to wait until another completes an operation before continuing execution.
81
70
 
82
71
  ```ts
83
72
  import * as latch from 'ciorent/latch';
@@ -119,62 +108,83 @@ await main();
119
108
  await main();
120
109
  ```
121
110
 
122
- If you don't need to close the latch again:
111
+ ## Utilities
112
+ ### Pausing
113
+ Delay the execution of a function for other asynchronous tasks to run.
123
114
  ```ts
124
- import * as latch from 'ciorent/latch';
125
115
  import * as cio from 'ciorent';
126
116
 
127
- const [pauseFetch, startFetch] = latch.init();
128
-
129
- const task = async () => {
130
- // Blocks until the latch is open
131
- await pauseFetch;
132
-
133
- const res = await fetch('http://example.com');
134
- console.log('Fetch status:', res.status);
135
- }
117
+ // Expensive sync task
118
+ const task1 = async () => {
119
+ let x = 0;
120
+ for (let i = 0; i < (Math.random() + 15) * 1e7; i++) {
121
+ // Frequent pausing
122
+ if (i % 2e6 === 0)
123
+ await cio.pause;
136
124
 
137
- const prepare = () => {
138
- console.log('Run before fetch:', performance.now().toFixed(2));
125
+ x += Math.random() * 32 + i * Math.round(Math.random() * 16);
126
+ }
127
+ console.log('Finish task 1:', x);
128
+ };
139
129
 
140
- // Unblock the latch
141
- startFetch();
142
- }
130
+ // Short async task
131
+ const task2 = async () => {
132
+ console.log('Fetch start', performance.now().toFixed(2) + 'ms');
133
+ const txt = await fetch('http://example.com');
134
+ console.log('Fetch status', txt.status);
135
+ };
143
136
 
144
- const main = async () => {
145
- const p = task();
146
- await cio.sleep(500);
147
- prepare();
137
+ // Task 2 will not get blocked by task 1
138
+ task1();
139
+ task2();
140
+ ```
148
141
 
149
- return p;
150
- }
142
+ ### Sleep
143
+ A cross-runtime sleep function.
144
+ ```ts
145
+ import { sleep } from 'ciorent';
151
146
 
152
- // Run fetch after 500ms
153
- await main();
147
+ await sleep(500);
148
+ console.log('Hi');
154
149
  ```
155
150
 
156
- ## Semaphore
157
- A semaphore is a synchronization tool to control access to shared resources.
151
+ ### Concurrency
152
+ Control how many tasks can be executed concurrently.
153
+ ```ts
154
+ import concurrent from 'ciorent/concurrent';
155
+ import * as cio from 'ciorent';
156
+
157
+ // Allow 3 tasks to run at the same time
158
+ const run = concurrent(3);
158
159
 
159
- It's essentially a counter that regulates how many threads or processes can access a particular resource or section of code.
160
+ for (let id = 1; id <= 6; id++)
161
+ run(async () => {
162
+ await cio.sleep(Math.random() * 20 + 50);
163
+ console.log('Task', id, 'done');
164
+ });
165
+ ```
160
166
 
167
+ ### Spawning tasks
168
+ Creating new tasks with controlled concurrency.
161
169
  ```ts
162
- import * as semaphore from 'ciorent/semaphore';
163
170
  import * as cio from 'ciorent';
164
171
 
165
- // Only allow 2 of these tasks to run concurrently
166
- const task = semaphore.task(
167
- semaphore.init(2),
168
- async (task: number) => {
169
- for (let i = 1; i <= 5; i++) {
170
- console.log('Task', task, 'iteration', i);
171
- await cio.pause;
172
- }
172
+ const task = async (id: number) => {
173
+ await cio.sleep(Math.random() * 20 + 50);
174
+ console.log('Task', id, 'done');
175
+ }
173
176
 
174
- console.log('Task', task, 'end');
175
- }
176
- );
177
+ // Spawn and run 5 tasks sequentially
178
+ console.log('Running sequentially:');
179
+ cio.sequential(5, task);
177
180
 
178
- // Try to run 6 tasks with 4 tasks running concurrently
179
- cio.concurrent(6, task, 4);
181
+ // Spawn and run 5 tasks concurrently
182
+ console.log('Running concurrently:');
183
+ cio.concurrent(5, task);
184
+
185
+ // Spawn and run 5 tasks, with the maximum
186
+ // tasks running concurrently set to 3
187
+ console.log('Running each 3 tasks concurrently:');
188
+ cio.concurrent(5, task, 3);
180
189
  ```
190
+
package/index.js CHANGED
@@ -1 +1 @@
1
- export let pause=Promise.resolve();export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.("timers/promises").setTimeout??((ms)=>new Promise((res)=>{setTimeout(res,ms)}));export let sequential=async(n,task)=>{for(let i=1;i<=n;i++)await task(i)};export let concurrent=async(n,task,concurrency)=>{if(concurrency==null){let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(i+1);return Promise.all(arr)}let arr=new Array(concurrency);let pre=1;for(let block=n/concurrency>>>0;block>0;block--){for(let j=0;j<concurrency;j++)arr[j]=task(pre+j);await Promise.all(arr);pre+=concurrency}n-=pre;for(let i=0;i<=n;i++)arr[i]=task(pre+i);return Promise.all(arr)};
1
+ export let pause=Promise.resolve();export let sleep=globalThis.Bun?.sleep??globalThis.process?.getBuiltinModule?.("timers/promises").setTimeout??((ms)=>new Promise((res)=>{setTimeout(res,ms)}));export let sequential=async(n,task)=>{for(let i=0;i<n;i++)await task(i)};export let concurrent=async(n,task,concurrency)=>{if(concurrency==null){let arr=new Array(n);for(let i=0;i<n;i++)arr[i]=task(i);return Promise.all(arr)}let arr=new Array(concurrency);let pre=0;for(let block=n/concurrency>>>0;block>0;block--){for(let j=0;j<concurrency;j++)arr[j]=task(pre+j);await Promise.all(arr);pre+=concurrency}n-=pre;for(let i=0;i<n;i++)arr[i]=task(pre+i);return Promise.all(arr)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciorent",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "A low-overhead, lightweight concurrency library",
5
5
  "homepage": "https://ciorent.netlify.app",
6
6
  "repository": {