v0.19 more porting: basics of actor system and postgres driver #1483
No reviewers
Labels
No labels
UX
active development
backlog
blocker
bootstrap
bounty
bug
dependencies
discussion
documentation
duplicate
enhancement
flaky test
help wanted
invalid
javascript
question
release
tendentious
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
mighty-gerbils/gerbil!1483
Loading…
Reference in a new issue
No description provided.
Delete branch "v0.19-std-more-porting"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
assisted by ds4 flash on the spark and chatgpt sol.
WIP: v0.19 more porting: postgres driverto WIP: v0.19 more porting: basics of actor system and postgres driverWIP: v0.19 more porting: basics of actor system and postgres driverto v0.19 more porting: basics of actor system and postgres driverthis is ready for review now.
I'll give a manual look, but here's what GPT 5.6 Sol (High) says:
I reviewed the current head,
d9da644e79. This is a fairly large PR—61 commits and 82 files—so I concentrated on the newly ported actor machinery, connection pool and time/date code, and skimmed the PostgreSQL changes. (cons.io git)I would request changes. I see four fairly serious bugs and two lesser ones:
[P1] Expired actor messages are never removed from the mailbox. In
generate-receive-envelope-e, the expired case is just(loop), whereas a successfully matched envelope callsthread-mailbox-extract-and-rewind. (cons.io git) Gambit's semantics matter here:thread-mailbox-nextexplicitly leaves the message in the mailbox; onlythread-mailbox-extract-and-rewindremoves the last examined message. (Gambit Scheme)So a late reply to a timed-out interaction becomes permanent garbage. Every later selective receive can encounter it again after the cursor is rewound. Repeated timeouts can therefore cause unbounded mailbox growth and progressively slower receives.
I think the expired arm needs roughly:
plus a regression test with a late reply.
[P1] Direct numeric
<-/<<timeouts appear broken by a typo.reaction-timeoutsays:i.e.
timeois being passed to##current-time-point, rather than added to its result. This looks like it simply wants:The generated receive path feeds real-valued
timeout:arguments through this function. (cons.io git)The tests don't catch this because the
->>tests ultimately pass an already-constructed time object to<-; there is no direct(<- timeout: 0.5 ...)test. (cons.io git)[P1]
->>>computes relative deadlines incorrectly, especially for fractional timeouts. It currently does:but
current-time-secondsitself isfloor(##current-time-point). (cons.io git)Thus, at time
100.9, a timeout of0.5expires at101, i.e. only 0.1 seconds later. A timeout of 5 seconds actually lasts between roughly 4 and 5 seconds. The new0.5test merely checks that it eventually times out, so it cannot catch this. (cons.io git)I think there should be a precise local deadline based on
##current-time-point, distinct from the integer Unix-second expiration carried in the envelope. If the protocol requires integer expiry, doingceilingshould happen after adding the precise current time, not separately.[P1] A closed connection pool can be resurrected by a late
put.connection-pool-closecloses both idle and checked-out connections, replacescp.connectwith an erroring procedure, and emptiesconns/out. Butconnection-pool-putunconditionally puts its connection back intocp.conns. Andconnection-pool-getcheckscp.connsbefore invokingcp.connect. (cons.io git)So:
The new close test gets very close to this case—it deliberately closes a pool with a checked-out connection—but never returns that connection after closing. (cons.io git)
I'd give the pool an explicit
closed?state.getshould check it first, andputafter closure should at least drop/close the returned connection rather than enqueue it.[P2]
envelope-expired?assumes everyOptionshas an expiration, although the type explicitly says otherwise.Options.expireis optional with default#f, alongside independentcontinueandauthfields, but:compares
#fnumerically whenever an envelope has options but no expiration. (cons.io git)At minimum:
This may not be exercised much while ensemble support is back in TODO state, but the data model explicitly permits such envelopes.
[P2]
string->datesilently ignoresstrptimefailure. The C wrapper deliberately throws awaystrptime's return value, thenstring->datereturns theDatestructure unconditionally. (cons.io git) That means malformed input—or possibly partially consumed input—produces whateverstruct tmhappens to contain instead of reporting a parse failure.I would have the wrapper preserve whether
strptimereturned NULL and probably also require complete input consumption forstring->date.The first one is the nastiest to me: it's a subtle selective-receive leak that could survive ordinary testing for a long time. The pool-close race is also a definite lifecycle bug. The two timeout calculations deserve direct timing tests rather than merely checking that a
Timeout?is eventually raised.I didn't spot anything comparably alarming in the PostgreSQL query port itself from this pass.
ok i shall fix with the help of my friend sol max.
My admittedly cursory review didn't find much.
But in general, I think the tests should include more tests about failure cases and recovery from them.
@ -40,6 +40,12 @@ If you want to run all the tests in a directory andit's subdirectory recursively, do `./build.sh test your-directory/...`.If you want to run all tests in the stdlib do `./build.sh test std/...`## Runing a build-local gxiRunning
sol addressed all the issues, assisted by gerbilosaurus rex who takes credit for the O(1) mailbox-extract-and-next idea.
i'll fix the typo.
all fixed
48ace8fa9bto7e79fde5df