You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bump version to v1.1.0: Adding error handling capabilities for uncaught errors from background jobs. Previously, such uncaught job errors were ignored. Now, they are captured and can be accessed by users.
Copy file name to clipboardExpand all lines: README.md
+78-4Lines changed: 78 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,13 +26,14 @@ npm i zero-backpressure-semaphore-typescript
26
26
## Key Features
27
27
28
28
-__Backpressure Control__: Ideal for job workers and background services. Concurrency control alone isn't sufficient to ensure stability and performance if backpressure control is overlooked.
29
-
-__Graceful Termination__: Achieved via the `waitTillAllExecutingJobsAreSettled` method.
29
+
-__Graceful Termination__: Await the completion of all currently executing jobs via the `waitTillAllExecutingJobsAreSettled` method.
30
30
-__High Efficiency__: All state-altering operations have a constant time complexity, O(1).
31
31
-__Comprehensive documentation__: The class is thoroughly documented, enabling IDEs to provide helpful tooltips that enhance the coding experience.
32
+
-__Robust Error Handling__: Uncaught errors from background jobs triggered by `startExecution` are captured and can be accessed using the `extractUncaughtErrors` method.
32
33
- Fully covered by unit tests.
33
34
- Self-explanatory method names.
34
35
- No external runtime dependencies: Only development dependencies are used.
35
-
-ES2020 Compatibility.
36
+
-ES6 Compatibility.
36
37
- TypeScript support.
37
38
38
39
## 1st use-case: Multiple Jobs Execution
@@ -70,15 +71,71 @@ async function aggregateSensorsData(sensorUIDs: ReadonlyArray<string>) {
70
71
// Note: at this stage, jobs might be still executing, as we did not wait for
71
72
// their completion.
72
73
73
-
// Graceful termination, if desired.
74
+
// Graceful termination: await the completion of all currently executing jobs.
//Business logic for aggregating data from a single sensor.
85
+
//Implementation goes here.
80
86
}
81
87
```
88
+
89
+
If the jobs might throw errors, you don't need to worry about these errors propagating up to the event loop and potentially crashing the application. Uncaught errors from jobs triggered by `startExecution` are captured by the semaphore and can be safely accessed for post-processing purposes (e.g., metrics). See the following adaptation of the above example, now utilizing the semaphore's error handling capabilities:
Please note that in a real-world scenario, sensor UIDs are more likely to be consumed from a message queue (e.g., RabbitMQ, Kafka, AWS SNS) rather than from an in-memory array. This setup **highlights the benefits** of avoiding backpressure:
83
140
We should avoid consuming a message if we cannot start processing it immediately. Working with message queues typically involves acknowledgements, which have timeout mechanisms. Therefore, immediate processing is crucial to ensure efficient and reliable handling of messages.
84
141
@@ -125,6 +182,23 @@ A key use case for this method is ensuring stable unit tests. Each test should s
125
182
126
183
If your component has a termination method (`stop`, `terminate`, or similar), keep that in mind.
127
184
185
+
## Error Handling for Background Jobs
186
+
187
+
Background jobs triggered by `startExecution` may throw errors. Unlike the `waitForCompletion` case, the caller has no reference to the corresponding job promise which executes in the background.
188
+
189
+
Therefore, errors from background jobs are captured by the semaphore and can be extracted using the `extractUncaughtErrors` method. Optionally, you can specify a custom `UncaughtErrorType` as the second generic parameter of the `ZeroBackpressureSemaphore` class. By default, the error type is `Error`.
The number of accumulated uncaught errors can be obtained via the `amountOfUncaughtErrors` getter method. This can be useful, for example, if the user wants to handle uncaught errors only after a certain threshold is reached.
196
+
197
+
Even if the user does not intend to perform error-handling with these uncaught errors, it is **important** to periodically call this method when using `startExecution` to prevent the accumulation of errors in memory.
198
+
However, there are a few exceptional cases where the user can safely avoid extracting uncaught errors:
199
+
- The number of jobs is relatively small and the process is short-lived.
200
+
- The jobs never throw errors, thus no uncaught errors are possible.
201
+
128
202
## Unavoidable / Implicit Backpressure
129
203
130
204
Mitigating backpressure is primarily associated with the `startExecution` method, particularly in scenarios involving multiple jobs. However, the single-job use case may certainly inflict backpressure on the Node.js micro-tasks queue.
0 commit comments