125 lines
6.7 KiB
Markdown
125 lines
6.7 KiB
Markdown
# PR#93: The Running Relay Sends the Reaction of matrix react
|
|
|
|
Version: minor
|
|
|
|
> **WARNING:** This document describes only the change applied in this PR.
|
|
> It may already be outdated once the next PR is merged.
|
|
> Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
|
|
|
|
## Related Links
|
|
|
|
- [werkregie PR#91](https://git.javagil.de/mi/werkregie/pulls/91), `matrix react`, which takes `sync.lock` itself.
|
|
- [werkregie PR#92](https://git.javagil.de/mi/werkregie/pulls/92), the refactoring of `MatrixSource` that this PR needs.
|
|
|
|
## Problem
|
|
|
|
`matrix react` takes `sync.lock`, which the running relay holds as long as it runs.
|
|
An agent stops the relay for each batch of reactions, for about 50 s per call;
|
|
meanwhile the dashboard misses the relay's report and says that the connection to the machine is lost.
|
|
|
|
## Non-Goals
|
|
|
|
- No other command through the socket, e.g. a message; only a reaction.
|
|
- No socket in the network: a Unix domain socket of the user only.
|
|
- No change of what `matrix react` does in the room.
|
|
|
|
## Specification
|
|
|
|
### Feature: the process that holds `sync.lock` sends the reaction of `matrix react`
|
|
|
|
#### Scenario#93.01: the running relay sends the reaction
|
|
|
|
… so that the relay keeps running and the dashboard keeps its report.
|
|
|
|
- **Given** the relay of the machine holds `sync.lock` and serves `control.sock`
|
|
- **When** an agent runs `werkregie-dashboard matrix react --room "HSAdmin NG" --contains /pulls/329 ✅️`
|
|
- **Then** the relay sends the reaction with its own client, and the command prints the relay's outcome, e.g. `REACTED`
|
|
|
|
##### Verified by
|
|
|
|
- [MatrixControlTest "the process that serves the socket sends the reaction and answers with its outcome"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
- [MatrixReactorTest "while another process syncs, the command asks it to send the reaction"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixReactorTest.kt)
|
|
- [MatrixReactionsTest "a printed line gives back its outcome; another line ends the command"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixReactionsTest.kt)
|
|
|
|
#### Scenario#93.02: without a running relay the command uses a client of its own
|
|
|
|
… so that a reaction works also on a machine without a relay.
|
|
|
|
- **Given** no process holds `sync.lock`, and a `control.sock` of an ended process may be left
|
|
- **When** the agent runs the command
|
|
- **Then** nobody answers on the socket, and the command takes `sync.lock` and reacts with a client of its own, as before
|
|
|
|
##### Verified by
|
|
|
|
- [MatrixControlTest "without a server nobody answers, also on a socket file that an ended process left"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
- [MatrixControlTest "a server replaces the socket file of an ended process"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
|
|
#### Scenario#93.03: a holder of the lock that does not answer
|
|
|
|
… so that two clients never use the device's store and keys at once.
|
|
|
|
- **Given** a process holds `sync.lock` but does not serve `control.sock`, e.g. a relay of an older version
|
|
- **When** the agent runs the command
|
|
- **Then** nothing is sent, and the command says to restart the relay and ends with exit code 3
|
|
|
|
##### Verified by
|
|
|
|
- [MatrixReactorTest "a process that holds the lock but does not answer gets no second client, and the command says how to restart it"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixReactorTest.kt)
|
|
|
|
#### Scenario#93.04: a failure in the relay
|
|
|
|
… so that the agent sees why no reaction was sent.
|
|
|
|
- **Given** the relay serves `control.sock`, and the room "HSAdmin NG" is not among its rooms
|
|
- **When** the agent runs the command
|
|
- **Then** the command prints the relay's message on stderr and ends with exit code 3
|
|
|
|
##### Verified by
|
|
|
|
- [MatrixControlTest "a failure of the serving process ends the command with its message"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
- [MatrixControlTest "an answer carries the outcome's line or the failure's message"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
|
|
#### Scenario#93.05: the socket takes only a reaction
|
|
|
|
… so that the socket opens no other way into the user's Matrix account.
|
|
|
|
- **Given** the relay serves `control.sock`
|
|
- **When** a process of the user sends another command, or a reaction without room, text or key
|
|
- **Then** the relay sends nothing and answers with an error
|
|
|
|
##### Verified by
|
|
|
|
- [MatrixControlTest "the socket takes only a reaction, with room, text and key"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
- [MatrixControlTest "only the user may use the socket, and it is gone when the server ends"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/MatrixControlTest.kt)
|
|
|
|
## Solution
|
|
|
|
- `MatrixControl`, new: the Unix domain socket `<stateDir>/matrix/control.sock`, one request per connection,
|
|
one line of JSON each way: `{"command":"react","room":…,"contains":…,"key":…}`,
|
|
answered by `{"line":"REACTED …"}` or `{"error":"…"}`.
|
|
`serve` replaces a socket file that an ended process left, sets it to 0600, and answers one request after the other;
|
|
`ask` returns null when nobody serves, so that the command falls back to a client of its own.
|
|
- `MatrixSource.sync` serves the socket with its client while it syncs: the relay as well as the local mode.
|
|
- `MatrixReactor.react(dir, …)` asks the socket first and takes `sync.lock` only when nobody answers;
|
|
`react(client, …)` waits for the first sync and reacts with any client, the relay's or its own.
|
|
- A holder of the lock that does not answer, e.g. a relay of an older version or one in its first seconds,
|
|
makes the command fail with the hint to restart it; the command never opens a second client.
|
|
- `MatrixReactions.outcome` reads the relay's line back into the outcome, so that exit code and output stay as before.
|
|
- The socket needs no secret: the directory of the device's keys is 0700, the socket 0600,
|
|
so only processes of the user reach it, which could run `matrix react` themselves.
|
|
- `pitestPartial mutationCrapCheck` against main: the highest Mutation-CRAP is 13, `MatrixReactor.entry`;
|
|
of `MatrixControl` 5, `request`.
|
|
|
|
## Release Notes
|
|
|
|
- `matrix react` sends its reaction through the running relay or local mode; neither stops for it any more.
|
|
|
|
## Open Questions
|
|
|
|
None.
|
|
|
|
## Prerequisite PRs
|
|
|
|
- [werkregie PR#92](https://git.javagil.de/mi/werkregie/pulls/92): each method of `MatrixSource` at a Mutation-CRAP of at most 15;
|
|
this branch builds on it.
|