The Telegram Listener Stop Handshake
The Telegram listener stop handshake uses durable files to make shutdown visible, coordinated, and safe across processes.
Thesis
A foreground listener is only production-shaped if it can stop cleanly. The Telegram listener stop handshake uses the same durable state and lease files that start the process, so shutdown is visible instead of implied.
The foreground-shell work made listen stay alive. The stop-handshake work made
close coordinate with that foreground process. The result is a stop contract
that works across processes without a hidden supervisor.
The Problem With Silent Cleanup
Many early listeners treat stop as cleanup. A command runs, deletes a pid file, and hopes the process is gone. That is not enough for Matic. The user should be able to inspect the org folder and see what the listener believed about its own lifecycle.
The Telegram stop handshake records shutdown in three places:
lease.yamlchanges from active to inactive.state.yamlchanges tostatus: stopped.history.mdreceives a close event.
Those files are the operational record. They can be checked by tests, by operators, and by the foreground process itself.
How Close Works
The command is:
PYTHONPATH=src python3 -m cli channels telegram close /path/to/org
close loads the listener state and lease. If neither exists, it raises an
error. That is intentional. Closing nothing is not success; it means the caller
is operating on the wrong org or the listener was never started.
If state or lease exists, the server finalizes the listener:
- Pick a stop timestamp.
- Release the active lease if needed.
- Mark state as stopped.
- Set
lease_activeto false. - Set
last_eventtoclose. - Save the state file.
- Append the close event to history when the state actually changed.
The foreground listener sees the inactive lease or close event on its next loop, then finalizes its own return path.
Why The Lease Matters
The lease does two jobs. It blocks duplicate starts, and it gives the foreground process a stop signal that does not depend on an in-memory object.
That second job is the key. The CLI command that starts the listener and the CLI command that stops it are separate processes. They cannot share Python state. They can share files. The lease file is the coordination point between them.
When close releases the lease, the running listener can observe that release.
This keeps the command model honest. close does not need a private channel
into the running process. It uses the same filesystem contract an operator can
inspect.
Idempotence Without Lying
The implementation avoids duplicate history writes when the foreground process finalizes after a close command already wrote the close event. The close event should describe a lifecycle transition, not every code path that noticed the transition.
At the same time, the command refuses to hide missing state. If nothing exists to close, that is surfaced as an error. This is the difference between idempotent finalization and silent success. The system should avoid duplicate records, but it should not pretend an absent listener was stopped.
Tests That Matter
The stop handshake is covered without real Telegram network access. Tests use temporary org roots and deterministic clocks. They prove:
- the listener writes state, lease, and history files;
- duplicate active starts are rejected;
- a foreground listener exits when close updates the files;
closerequires existing state or lease;- and the CLI smoke path can start and stop a foreground listener process.
Those tests are valuable because they exercise the operational contract, not just individual methods. A stop handshake is only useful if separate commands coordinate through durable files.
What This Enables
After the foreground-shell work, the Telegram listener has a trustworthy shell:
- it can stay foreground,
- it can be stopped from another process,
- it blocks duplicate starts,
- it leaves readable lifecycle evidence,
- and it keeps outbound channel behavior unchanged.
That shell is now ready for inbound Telegram work. The inbound-intake work can add polling, normalization, inbox records, and offsets without changing how operators start or stop the listener.
The Design Rule
Stop behavior is part of the product surface. If the only proof of shutdown is that a process disappeared, the system is too opaque. The Telegram listener uses files as the stop handshake because files are what Matic can inspect, test, commit, recover, and explain.