@procedures/peer 0.22.1 → 0.24.0
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/CHANGELOG.md +76 -0
- package/README.md +9 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +1 -0
- package/dist/host/index.js.map +1 -1
- package/dist/host/local-face.d.ts +42 -0
- package/dist/host/local-face.d.ts.map +1 -0
- package/dist/host/local-face.js +160 -0
- package/dist/host/local-face.js.map +1 -0
- package/dist/host/tracking.d.ts.map +1 -1
- package/dist/host/tracking.js +2 -0
- package/dist/host/tracking.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/host/index.ts +1 -0
- package/src/host/local-face.ts +183 -0
- package/src/host/tracking.ts +2 -0
- package/src/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,81 @@
|
|
|
1
1
|
# @procedures/peer
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4261f65: Breaking: each `mark` command starts under `run()` of `@mark1russell7/service` (CLI-26, decision D17). The cold mode runs the procedures host of the CLI server in its own process. The runner owns the signals, the stop in stages and the exit. Thus the exit codes of a signal change. The release before this one marked the old behaviors as deprecated.
|
|
8
|
+
|
|
9
|
+
The new behavior:
|
|
10
|
+
|
|
11
|
+
- Each `mark` command that runs a procedure is a service of one request, with the profile `ephemeral`. `mark` has no signal handler and no `process.exit` of its own in this path. `interruptSignal()` is gone.
|
|
12
|
+
- The cold mode (no CLI server in this folder, or `--local`): the host has the same registry and policy as `mark --server` (`markHostOptions()`), and no listener, port, token or lockfile. The client sends each call through the local face of the host.
|
|
13
|
+
- `localFace()` of `@procedures/peer` is new. It gives a face factory and a transport of `@procedures/client`. A `Client` on the transport sends its calls to the host of the same process, through the request tracking of the service, with `LOCAL_CREDENTIALS`.
|
|
14
|
+
- A first Ctrl-C starts the stop, and the drain aborts the call at once.
|
|
15
|
+
- The warm mode: the call to the CLI server gets the abort signal. A Ctrl-C aborts the call on the server too. Before, the signal ended `mark`, and the server continued the call.
|
|
16
|
+
- After the command, the runner ends the process with the exit code of the command. A timer or a socket that a procedure left open does not keep the process alive.
|
|
17
|
+
- `run()` and `main()` of `@procedures/mark` get the optional options `run` (the options of `run()`: the process port and the clock) and `ownsProcess`. The bin gives `ownsProcess: true`. Without it, a program keeps its process: no signal handler, and the exit code goes to `process.exitCode`.
|
|
18
|
+
- `CliContext` gets the optional field `registry`. `executeArgs()` does not use `ctx.client` for a command any more.
|
|
19
|
+
- A program that calls `run()` or `executeArgs()` without a port, and the REPL (`mark -i`), get no signal handler for a command.
|
|
20
|
+
|
|
21
|
+
The exit codes, in the cold mode and in the warm mode:
|
|
22
|
+
|
|
23
|
+
| Event | Before | From this release |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| The command ends without a failure | 0 | 0 |
|
|
26
|
+
| The command fails | 1 | 1 |
|
|
27
|
+
| The first Ctrl-C, cold mode | 1 | 130 |
|
|
28
|
+
| The first Ctrl-C, warm mode | the signal ended the process (the shell showed 130) | 130 |
|
|
29
|
+
| `SIGTERM` | the signal ended the process (the shell showed 143) | 143 |
|
|
30
|
+
| A second signal during the stop, cold mode | 130 | 1 |
|
|
31
|
+
|
|
32
|
+
A cold `mark server create` keeps its peer only until the end of the command. Before, the peer kept the process alive after the command.
|
|
33
|
+
|
|
34
|
+
Migration:
|
|
35
|
+
|
|
36
|
+
- A script that reads the exit code of an interrupted `mark` command: read 130 for a Ctrl-C, also in the cold mode. Read 1 for a second signal.
|
|
37
|
+
- A script that starts `mark server create` as a server in the foreground: start `mark --server` or `procedure-server` in its place.
|
|
38
|
+
- A program that calls `run()`, `main()` or `executeArgs()` of `@procedures/mark`: no change. It keeps its process. Give `ownsProcess: true` to give the process to the runner, as the bin does.
|
|
39
|
+
- The site: no change. It does not start `mark`.
|
|
40
|
+
- MiniMongo: no change. Its dev host starts through `runProcedureHost()`, not through `mark`.
|
|
41
|
+
- Graph: no change. It does not start `mark`.
|
|
42
|
+
- jarvis: no change, unless a script of jarvis reads the exit code of an interrupted `mark` command. Then apply the first step.
|
|
43
|
+
- @procedures/client@0.24.0
|
|
44
|
+
|
|
45
|
+
## 0.23.0
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- f20beb1: The task store of an MCP host gives each client a fair share of its tasks (CLI-69). Before, the sessions of one client could fill the store (CLI-51). Then each other client got `TASKS_FULL` until those tasks ended their time.
|
|
50
|
+
|
|
51
|
+
MINOR: a breaking change before 1.0. Near the limit, the store refuses a client with its share or more, also when the store has free slots. Before, the store refused a task only when it was full (decision D13).
|
|
52
|
+
|
|
53
|
+
Changed:
|
|
54
|
+
|
|
55
|
+
- The key of a task (`shareKey`) tells its client. The default `mcpTaskShareKey` gives the principal of the request, else the session. The principal of the host token is the same for each caller, so a request with only the token gets the key of its session.
|
|
56
|
+
- The share of a client is `maxStored / (k + 1)`. `k` is the number of clients with tasks in the store, the new client included.
|
|
57
|
+
- When `reserve` slots or fewer are free, a client with its share or more gets no more tasks. Its new task replaces the oldest task of its session that ended. Without such a task, the request gets the error `-32600` with the code `TASKS_FULL`, as for a full store.
|
|
58
|
+
- A client below its share gets a task while the store has a free slot. Thus one client keeps at most `maxStored - reserve` tasks, also with many sessions.
|
|
59
|
+
- The total limit (`maxStored`, 1000 by default) and the limit of 100 tasks of a session stay as they are.
|
|
60
|
+
|
|
61
|
+
Added:
|
|
62
|
+
|
|
63
|
+
- The options `reserve`, `shareKey` and `clock` of `McpTaskStore`, and of `tasks` of `createMcpHost()` and `mcpFace()`. The default `reserve` is a tenth of `maxStored`, rounded down: 100 of 1000. `reserve: 0` turns the fair share off.
|
|
64
|
+
- `mcpTaskShareKey`, and the types `McpTaskShareContext` and `McpTaskCaller`. `createTask` of the store takes the caller as its fifth argument.
|
|
65
|
+
- `MCP_TASK_LIMITS.reserveDivisor`: 10.
|
|
66
|
+
- `identify(credentials)` of `ProcedureServer`, and the optional `identify` of `RequestHandler`. It gives the principal of a request before a call, from the checks of each call. The face handler of the procedures host and the narrowed handler of `mcpFace()` give it too. The MCP face uses it for the key of a task. Thus the request hook and the authenticate function run one more time for each new task.
|
|
67
|
+
|
|
68
|
+
Migration:
|
|
69
|
+
|
|
70
|
+
- The site and MiniMongo: no change. They have no MCP host.
|
|
71
|
+
- Graph: no change. Its MCP hosts have no task store.
|
|
72
|
+
- jarvis: no change. Its MCP host has no tasks.
|
|
73
|
+
- polite-crawler-mcp: no change. Each request has the host token, so each session is one client. A session with 100 tasks gets fewer tasks only when ten or more sessions are near the limit. To keep the rule of CLI-51, give `new McpTaskStore({ reserve: 0 })`.
|
|
74
|
+
- A host whose clients each have many sessions under one principal: each client keeps at most `maxStored - reserve` tasks. To keep the rule of CLI-51, give `reserve: 0` in `tasks` of the host or in `new McpTaskStore()`.
|
|
75
|
+
- Updated dependencies [f20beb1]
|
|
76
|
+
- Updated dependencies [71091a5]
|
|
77
|
+
- @procedures/client@0.23.0
|
|
78
|
+
|
|
3
79
|
## 0.22.1
|
|
4
80
|
|
|
5
81
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -138,6 +138,15 @@ await svc.run();
|
|
|
138
138
|
|
|
139
139
|
- **The parts.** `host.parts` are the transports: the procedure server, the stop parts of each face, and an `httpTransport` for each listener. `host.dependencies` has one dependency handle for each storage. `host.controllers` has one route pattern for each face.
|
|
140
140
|
- **The faces.** `http` and `ws` are the faces of this package (`httpFace()`, `wsFace()`). `mcp` takes `mcpFace()` of `@procedures/mcp-server`. A face of another package is a function with the same shape.
|
|
141
|
+
- **The local face.** `localFace()` gives a face factory and a transport of `@procedures/client` (CLI-26). A `Client` on the transport sends its calls to the host from the same process, through the request tracking of the service. Each call has `LOCAL_CREDENTIALS`, and the drain aborts its signal. The cold mode of `mark` uses it.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const local = localFace();
|
|
145
|
+
const host = createProcedureHost({ registry, faces: { local: local.face } });
|
|
146
|
+
const life = await host.declare(service("tool").profile(ephemeral)).run();
|
|
147
|
+
const client = new Client({ transport: local.transport });
|
|
148
|
+
```
|
|
149
|
+
|
|
141
150
|
- **The listeners.** The faces of a listener mount on its mount list, so they share one port. Without `listen`, the app mounts `host.handler` and `host.upgrade` on its own listener.
|
|
142
151
|
- **The request tracking.** Each call goes through `life.request`, with the route `<face> <procedure>`. The function of the pattern gives the idempotency of each call: a repeatable procedure, a keyed call, or a call that runs one time (decision D3).
|
|
143
152
|
- **The readiness of the calls.** The option `controller.requires` names the dependencies of the service that each call needs. While a check of one of them fails readiness, the service refuses each call with `UNAVAILABLE` (CLI-45).
|