From 8624047ecde338308023875879a427aa52229563 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 25 Apr 2018 20:43:25 +0100 Subject: [PATCH] The failing test now passes. The reasons for this are subtle: The patch here removes a terminated facet from its parent's `facet-children` set only in a script, and only after all other scripts enqueued as part of facet termination have executed without an uncaught exception. This means that, if (say) a stop script raises an uncaught exception, it might have happened after some *but not all* scripts resulting from calls to `retract-facet-assertions-and-subscriptions!` have already executed. So some endpoints' assertions and subscriptions will have been removed. When the uncaught exception is caught by the handler in `with-current-facet`, a call to `abandon-queued-work!` is made, which discards queued scripts, including the remaining assertion-cleanup scripts as well as the scripts for removing dead facets from their parents' `facet-children` sets. It also (crucially) discards queued patch actions, including those resulting from already-executed assertion-cleanup scripts. At this point, we have a facet tree with some dead facets still in it, and no queued outbound patches. The assertions for the still-present dead facets are still logically asserted. Then, a call to `terminate-actor!` happens, which traverses the whole tree enqueueing assertion-cleanup scripts. No user code is enqueued, so (in principle) no exceptions can be signalled. Once these `terminate-actor!`-enqueued scripts execute, a pending patch exists that will remove all remaining endpoint assertions. The remaining sticky point is the calls to `dataspace-unsubscribe!`. Happily, these are idempotent because of the implementation in `skeleton.rkt`. Prior to this patch, terminating facets were removed early from their parents' `facet-children` sets, meaning there was no way to find them again to clean up if a failure occurred during a stop script. Ideally, it'd be easy to see that the code is correct in this respect. We're not there yet. --- syndicate/dataspace.rkt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/syndicate/dataspace.rkt b/syndicate/dataspace.rkt index 99fe148..98b242a 100644 --- a/syndicate/dataspace.rkt +++ b/syndicate/dataspace.rkt @@ -427,9 +427,6 @@ (when (facet-live? f) (define ac (facet-actor f)) (define parent (facet-parent f)) - (if parent - (set-facet-children! parent (set-remove (facet-children parent) f)) - (set-actor-root-facet! ac #f)) (set-facet-live?! f #f) @@ -446,9 +443,13 @@ (push-script! #:priority *gc-priority* ds ac (lambda () - (if parent - (when (facet-inert? ds parent) (terminate-facet! ds parent)) - (terminate-actor! ds ac)))))) + (cond + [parent + (set-facet-children! parent (set-remove (facet-children parent) f)) + (when (facet-inert? ds parent) (terminate-facet! ds parent))] + [else + (set-actor-root-facet! ac #f) + (terminate-actor! ds ac)]))))) (define (stop-facet! ds f stop-script) (define ac (facet-actor f))