6.7 KiB
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,
matrix react, which takessync.lockitself. - werkregie PR#92, the refactoring of
MatrixSourcethat 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 reactdoes 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.lockand servescontrol.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"
- MatrixReactorTest "while another process syncs, the command asks it to send the reaction"
- MatrixReactionsTest "a printed line gives back its outcome; another line ends the command"
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 acontrol.sockof an ended process may be left - When the agent runs the command
- Then nobody answers on the socket, and the command takes
sync.lockand 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"
- MatrixControlTest "a server replaces the socket file of an ended process"
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.lockbut does not servecontrol.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
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"
- MatrixControlTest "an answer carries the outcome's line or the failure's message"
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"
- MatrixControlTest "only the user may use the socket, and it is gone when the server ends"
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":"…"}.servereplaces a socket file that an ended process left, sets it to 0600, and answers one request after the other;askreturns null when nobody serves, so that the command falls back to a client of its own.MatrixSource.syncserves the socket with its client while it syncs: the relay as well as the local mode.MatrixReactor.react(dir, …)asks the socket first and takessync.lockonly 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.outcomereads 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 reactthemselves. pitestPartial mutationCrapCheckagainst main: the highest Mutation-CRAP is 13,MatrixReactor.entry; ofMatrixControl5,request.
Release Notes
matrix reactsends its reaction through the running relay or local mode; neither stops for it any more.
Open Questions
None.
Prerequisite PRs
- werkregie PR#92: each method of
MatrixSourceat a Mutation-CRAP of at most 15; this branch builds on it.