Skip to content

Make Importable as Library#14

Open
j4n wants to merge 4 commits intomainfrom
j4n/make-importable
Open

Make Importable as Library#14
j4n wants to merge 4 commits intomainfrom
j4n/make-importable

Conversation

@j4n
Copy link

@j4n j4n commented Mar 10, 2026

Fix several roadblocks preventing usage of cmping as library:

Changes:

  • Add CMPingError exception, replace sys.exit(1) with raise CMPingError()
  • Add collection of result tuples in Pinger.results
  • Return times of account setup, group join and message time from Pinger
  • Add accounts_dir parameter to perform_ping() to allow callers to
    isolate concurrent probes in separate DB directories, avoiding the
    deltachat-rpc-server exclusive lock
  • Add timeout support to Pinger

Fix several roadblocks preventing usage of cmping as library:

Changes:
- Add CMPingError exception, replace sys.exit(1) with raise CMPingError()
- Add collection of result tuples in Pinger.results
- Return times of account setup, group join and message time from Pinger
- Add accounts_dir parameter to perform_ping() to allow callers to
  isolate concurrent probes in separate DB directories, avoiding the
  deltachat-rpc-server exclusive lock
- Add timeout support to Pinger
@j4n j4n requested a review from hpk42 March 10, 2026 16:41
@j4n j4n changed the title Add deadline support to Pinger Make Importable as Library Mar 10, 2026
@j4n
Copy link
Author

j4n commented Mar 10, 2026

Title got mixed up. This is for the chatmail prober, which is almost ready.

j4n added 3 commits March 11, 2026 18:02
Previously wait_all_online blocked indefinitely on wait_for_event(), making
it impossible to enforce a timeout from the caller. Now it accepts a timeout
parameter and polls the account event queue with a 1s granularity, raising
CMPingError if the deadline is exceeded. The timeout is propagated throughout.

Thread cleanup improvements:
- Store Pinger._send_thread so it can be joined after the ping loop
  preventing the thread from running orphaned after the deadline
- Wrap receiver thread joins in a try/finally block in Pinger.receive()
  (cmping.py:985) so threads are always cleaned up even if the deadline
  fires or an exception occurs
receiver_thread previously called receiver.wait_for_event(), which
internally blocks on queue.Queue.get() with no timeout.  After
Rpc.close() terminates the rpc-server subprocess and stops the
events_loop, nothing puts a sentinel in the account event queues, so
every receiver_thread blocked indefinitely.

With N^2 pairs and multiple probe rounds, these daemon threads
accumulated in threading._dangling.  When a new probe tried to fork
deltachat-rpc-server, _after_fork called threads.update(_dangling) in
the child, which OOM'd because the set had grown to thousands of
entries.  Symptoms: MemoryError + "can't start new thread" mid-round.

Fix: replace the blocking wait_for_event() call with a
account_queue.get(timeout=1.0) loop that checks stop_event.  The
finally block in receive() sets stop_event before joining, so threads
exit within ~1s instead of blocking until process exit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant