From 93371894a0155e0a4e90dbb2b7da5a172f856664 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 4 Nov 2018 13:43:17 +0000 Subject: [PATCH] Repair longstanding, subtle bug in both old- and new-syndicate. during/spawn used not to add linkage assertions to its initial-assertion set. In addition, if a spawned actor died in its initial boot procedure, its initial assertions would never be visible. These two problems interlocked to cause a space leak in during/spawn, where monitoring facets would never be cleaned up. This change does two things: - adds linkage assertions to the initial-assertion set in during/spawn - properly briefly signals initial-assertions even when a new actor immediately crashes. Together, these repair the space leak in during/spawn with a crashy child startup procedure. --- syndicate/syntax.rkt | 4 ++- syndicate/test/core/death-during-startup.rkt | 31 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 syndicate/test/core/death-during-startup.rkt diff --git a/syndicate/syntax.rkt b/syndicate/syntax.rkt index 88b21f3..e4c562e 100644 --- a/syndicate/syntax.rkt +++ b/syndicate/syntax.rkt @@ -434,7 +434,9 @@ (w.wrapper #:linkage [(assert inst) (stop-when (retracted (observe inst)))] #:name name.N - #:assertions [assertions.exprs ...] + #:assertions [inst + (observe (observe inst)) + assertions.exprs ...] O ...)))))])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/syndicate/test/core/death-during-startup.rkt b/syndicate/test/core/death-during-startup.rkt new file mode 100644 index 0000000..0bbd144 --- /dev/null +++ b/syndicate/test/core/death-during-startup.rkt @@ -0,0 +1,31 @@ +#lang imperative-syndicate/test-implementation +;; An error signalled during setup of a new actor's root facet must +;; cause previous actions to be discarded, but must also cause any +;; initial-assertions, including specifically linkage assertions from +;; during/spawn, to be briefly visible. + +(test-case + [(assertion-struct request (id)) + (assertion-struct response (value)) + + (spawn (during/spawn (request $id) + (printf "starting request handler\n") + (assert (response 'the-answer)) ;; must not be visible + (printf "asserted response, shouldn't be visible\n") + (error 'aieee "oh no") + (printf "NOTREACHED\n"))) + + (spawn (stop-when (asserted (observe (request _))) + (printf "service listening\n") + (react + (assert (request 101)) + (stop-when (retracted (observe (request _))) + (printf "whole service vanished\n")) + (stop-when (retracted (observe (request 101))) + (printf "specific instance vanished\n")) + (stop-when (asserted (response $v)) + (printf "response ~v\n" v)))))] + (expected-output (list "service listening" + "starting request handler" + "asserted response, shouldn't be visible" + "specific instance vanished")))