Skip to content

Commit 631f6d8

Browse files
Test daemon mode: StopDaemon lifecycle and crash recovery
- StopDaemon: a search caches a live daemon; StopDaemon clears it (and any in-flight pipe), is idempotent, and a later search respawns cleanly. - Recovery: a GAP refiner callback that errors mid-search leaves the vole process parked (inflight set); the next search warns, reaps it, forks afresh, and still answers correctly. This mirrors a user hitting an error inside vole and quitting the break loop.
1 parent 37e7b61 commit 631f6d8

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

tst/daemon.tst

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#@local boom
2+
gap> START_TEST("daemon.tst");
3+
4+
#
5+
# Daemon mode keeps one vole process alive between searches and reuses it.
6+
# _Vole.daemon caches the live pipe; _Vole.inflight holds the pipe of a search
7+
# in progress (cleared on clean completion, left set if a call escapes).
8+
#
9+
gap> LoadPackage("vole", false);;
10+
gap> _Vole.UseDaemon;
11+
true
12+
13+
#
14+
# StopDaemon lifecycle.
15+
#
16+
gap> _Vole.StopDaemon();;
17+
gap> _Vole.daemon;
18+
fail
19+
20+
# A search leaves a live daemon cached for reuse; nothing left in flight.
21+
gap> Size(VoleFind.Group([VoleRefiner.SetStab([1, 2, 3]), SymmetricGroup(6)]));
22+
36
23+
gap> _Vole.daemon <> fail;
24+
true
25+
gap> _Vole.inflight;
26+
fail
27+
28+
# StopDaemon tears the daemon down; both slots clear.
29+
gap> _Vole.StopDaemon();;
30+
gap> [_Vole.daemon, _Vole.inflight];
31+
[ fail, fail ]
32+
33+
# StopDaemon is idempotent: stopping again when nothing runs is a no-op.
34+
gap> _Vole.StopDaemon();;
35+
gap> _Vole.daemon;
36+
fail
37+
38+
# A search after a stop spawns a fresh daemon and still answers correctly.
39+
gap> Size(VoleFind.Group([VoleRefiner.SetStab([1, 2, 3]), SymmetricGroup(6)]));
40+
36
41+
gap> _Vole.daemon <> fail;
42+
true
43+
44+
#
45+
# Recovery: a GAP refiner callback that crashes mid-search leaves the vole
46+
# process parked (inflight set). The next call must notice, warn, reap it,
47+
# fork a fresh vole, and still answer correctly -- rather than wedging the
48+
# session. This simulates a user hitting an error inside vole and quitting
49+
# the break loop.
50+
#
51+
gap> SetInfoLevel(InfoVole, 1);;
52+
gap> boom := Objectify(BTKitRefinerType, rec(
53+
> name := "Boom",
54+
> largest_required_point := 3,
55+
> constraint := Constraint.Stabilise([1, 2, 3], OnSets),
56+
> refine := rec(
57+
> initialise := function(ps, l) Error("boom from refiner callback"); end)));;
58+
gap> VoleFind.Group([boom, SymmetricGroup(6)]);
59+
Error, boom from refiner callback
60+
gap> _Vole.inflight <> fail;
61+
true
62+
63+
# The next search reaps the crashed process (with a warning) and recovers.
64+
gap> Size(VoleFind.Group([VoleRefiner.SetStab([1, 2, 3]), SymmetricGroup(6)]));
65+
#I Previous vole call didn't exit cleanly, restarting vole
66+
36
67+
gap> _Vole.inflight;
68+
fail
69+
gap> SetInfoLevel(InfoVole, 0);;
70+
gap> _Vole.StopDaemon();;
71+
72+
#
73+
gap> STOP_TEST("daemon.tst");

0 commit comments

Comments
 (0)