@hardlydifficult/daemon 1.0.0 → 1.0.1
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.
- package/README.md +58 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,123 +1,114 @@
|
|
|
1
|
-
# @hardlydifficult/
|
|
1
|
+
# @hardlydifficult/daemon
|
|
2
2
|
|
|
3
|
-
Idempotent resource teardown with signal trapping
|
|
3
|
+
Idempotent resource teardown with signal trapping and LIFO cleanup ordering.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @hardlydifficult/
|
|
8
|
+
npm install @hardlydifficult/daemon
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { createTeardown } from "@hardlydifficult/
|
|
14
|
+
import { createTeardown, runContinuousLoop } from "@hardlydifficult/daemon";
|
|
15
15
|
|
|
16
|
+
// Register cleanup functions
|
|
16
17
|
const teardown = createTeardown();
|
|
17
|
-
teardown.add(() =>
|
|
18
|
-
teardown.add(() =>
|
|
18
|
+
teardown.add(() => console.log("Closing server"));
|
|
19
|
+
teardown.add(() => console.log("Closing database"));
|
|
19
20
|
teardown.trapSignals();
|
|
20
21
|
|
|
21
|
-
//
|
|
22
|
+
// Run teardown when ready
|
|
22
23
|
await teardown.run();
|
|
24
|
+
// Logs:
|
|
25
|
+
// Closing database
|
|
26
|
+
// Closing server
|
|
23
27
|
```
|
|
24
28
|
|
|
25
|
-
##
|
|
29
|
+
## Teardown Management
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
Resource cleanup registry with idempotent execution and LIFO ordering.
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
import { createTeardown } from "@hardlydifficult/teardown";
|
|
33
|
+
### `createTeardown()`
|
|
31
34
|
|
|
35
|
+
Creates a teardown registry for managing resource cleanup.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
32
38
|
const teardown = createTeardown();
|
|
33
39
|
```
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
#### `.add(fn: () => void | Promise<void>): () => void`
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
Registers a teardown function. Returns an unregister function.
|
|
38
44
|
|
|
39
45
|
```typescript
|
|
40
46
|
const teardown = createTeardown();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
teardown.add(() => {
|
|
44
|
-
console.log("Closing server");
|
|
45
|
-
server.stop();
|
|
47
|
+
const unregister = teardown.add(async () => {
|
|
48
|
+
await server.close();
|
|
46
49
|
});
|
|
47
50
|
|
|
48
|
-
//
|
|
49
|
-
teardown.add(async () => {
|
|
50
|
-
console.log("Closing database");
|
|
51
|
-
await db.close();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Unregister a specific function
|
|
55
|
-
const unregister = teardown.add(() => {
|
|
56
|
-
console.log("This won't run");
|
|
57
|
-
});
|
|
51
|
+
// Unregister before teardown if needed
|
|
58
52
|
unregister();
|
|
59
|
-
|
|
60
|
-
await teardown.run();
|
|
61
|
-
// Output:
|
|
62
|
-
// Closing database
|
|
63
|
-
// Closing server
|
|
64
53
|
```
|
|
65
54
|
|
|
66
|
-
|
|
55
|
+
#### `.run(): Promise<void>`
|
|
67
56
|
|
|
68
|
-
|
|
57
|
+
Runs all teardown functions in LIFO order. Idempotent — subsequent calls are no-ops.
|
|
69
58
|
|
|
70
59
|
```typescript
|
|
71
60
|
const teardown = createTeardown();
|
|
72
|
-
teardown.add(() => console.log("
|
|
73
|
-
|
|
74
|
-
await teardown.run();
|
|
75
|
-
// Output: cleanup
|
|
61
|
+
teardown.add(() => console.log("First"));
|
|
62
|
+
teardown.add(() => console.log("Second"));
|
|
76
63
|
|
|
77
64
|
await teardown.run();
|
|
78
|
-
//
|
|
65
|
+
// Logs:
|
|
66
|
+
// Second
|
|
67
|
+
// First
|
|
79
68
|
```
|
|
80
69
|
|
|
81
|
-
|
|
70
|
+
#### `.trapSignals(): () => void`
|
|
82
71
|
|
|
83
|
-
|
|
72
|
+
Wires SIGTERM/SIGINT handlers to run teardown and exit. Returns an untrap function to remove handlers.
|
|
84
73
|
|
|
85
74
|
```typescript
|
|
86
75
|
const teardown = createTeardown();
|
|
87
|
-
teardown.add(() => server.stop());
|
|
88
|
-
|
|
89
|
-
// Wire SIGTERM/SIGINT to run() then process.exit(0)
|
|
90
76
|
const untrap = teardown.trapSignals();
|
|
91
77
|
|
|
92
|
-
// Later,
|
|
78
|
+
// Later, to stop trapping signals
|
|
93
79
|
untrap();
|
|
94
80
|
```
|
|
95
81
|
|
|
96
|
-
##
|
|
82
|
+
## Continuous Loop Execution
|
|
97
83
|
|
|
98
|
-
|
|
84
|
+
Runs cyclic tasks with graceful shutdown support.
|
|
99
85
|
|
|
100
|
-
|
|
101
|
-
const teardown = createTeardown();
|
|
86
|
+
### `runContinuousLoop(options: ContinuousLoopOptions): Promise<void>`
|
|
102
87
|
|
|
103
|
-
|
|
104
|
-
throw new Error("First cleanup fails");
|
|
105
|
-
});
|
|
106
|
-
teardown.add(() => {
|
|
107
|
-
console.log("Second cleanup still runs");
|
|
108
|
-
});
|
|
88
|
+
Executes a cycle function repeatedly with interruptible sleep and signal handling.
|
|
109
89
|
|
|
110
|
-
|
|
111
|
-
|
|
90
|
+
```typescript
|
|
91
|
+
import { runContinuousLoop } from "@hardlydifficult/daemon";
|
|
92
|
+
|
|
93
|
+
await runContinuousLoop({
|
|
94
|
+
intervalSeconds: 5,
|
|
95
|
+
runCycle: async (isShutdownRequested) => {
|
|
96
|
+
if (isShutdownRequested()) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Perform work here
|
|
100
|
+
console.log("Running cycle...");
|
|
101
|
+
},
|
|
102
|
+
onShutdown: async () => {
|
|
103
|
+
console.log("Shutdown complete");
|
|
104
|
+
}
|
|
105
|
+
});
|
|
112
106
|
```
|
|
113
107
|
|
|
114
|
-
|
|
108
|
+
#### Options
|
|
115
109
|
|
|
116
|
-
|
|
|
117
|
-
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
| **Safe unregister** | `add()` returns an unregister function; safe to call multiple times |
|
|
122
|
-
| **Post-run add** | `add()` after `run()` is a silent no-op |
|
|
123
|
-
| **Duplicate safe** | Same function added twice runs twice; unregister only removes its own registration |
|
|
110
|
+
| Name | Type | Description |
|
|
111
|
+
|-------------------|---------------------------------|------------------------------------------------|
|
|
112
|
+
| `intervalSeconds` | `number` | Interval between cycles in seconds |
|
|
113
|
+
| `runCycle` | `(isShutdownRequested: () => boolean) => Promise<unknown>` | Callback to run each cycle (shutdown check provided) |
|
|
114
|
+
| `onShutdown?` | `() => Promise<void>` | Optional cleanup callback after shutdown |
|