From 37af1e8726e6e94321a7319cabc5ed5d76428c72 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 25 Oct 2016 16:59:00 -0400 Subject: [PATCH] Cope with transient pulses of demand in during/actor --- racket/syndicate/actor.rkt | 27 +++++++++++++++++-- .../actor/example-assertion-spike.rkt | 27 +++++++++++++++++++ racket/syndicate/protocol/instance.rkt | 13 +++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 racket/syndicate/protocol/instance.rkt diff --git a/racket/syndicate/actor.rkt b/racket/syndicate/actor.rkt index a1f3d3f..c067e4f 100644 --- a/racket/syndicate/actor.rkt +++ b/racket/syndicate/actor.rkt @@ -92,6 +92,7 @@ (require "support/hash.rkt") (require "pretty.rkt") (require "functional-queue.rkt") +(require "protocol/instance.rkt") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data Definitions and Structures @@ -443,9 +444,31 @@ (analyze-pattern E-stx #'P)) (quasisyntax/loc stx (on #,E-stx - (let ((p #,instantiated)) + (let* ((id (gensym 'during/actor)) + (p #,instantiated) ;; this is the concrete assertion corresponding to demand + (inst (instance id p))) ;; this is the assertion representing supply + (react (stop-when (asserted inst) + ;; Supply (inst) appeared before demand (p) retracted. + ;; Transition to a state where we monitor demand, but also + ;; express interest in supply: this latter acts as a signal + ;; to the supply that it should stick around. We could, if + ;; we liked, react to retraction of supply before + ;; retraction of demand, interpreting it perhaps as a crash + ;; of some kind. Once demand is retracted, this facet + ;; terminates, retracting its interest in supply, thereby + ;; signalling to the supply that it is no longer wanted. + (react (stop-when (retracted inst)) ;; NOT OPTIONAL + (stop-when (retracted p)))) + (stop-when (retracted p) + ;; Demand (p) retracted before supply (inst) appeared. We + ;; MUST wait for the supply to fully appear so that we can + ;; reliably tell it to shut down. We must maintain interest + ;; in supply until we see supply, and then terminate, thus + ;; signalling to supply that it is no longer wanted. + (react (stop-when (asserted inst))))) (w.wrapper #:name name.N - (stop-when (retracted p)) + (assert inst) + (stop-when (retracted (observe inst))) O ...))))])) (define-syntax (begin/dataflow stx) diff --git a/racket/syndicate/examples/actor/example-assertion-spike.rkt b/racket/syndicate/examples/actor/example-assertion-spike.rkt index 693a17d..d892682 100644 --- a/racket/syndicate/examples/actor/example-assertion-spike.rkt +++ b/racket/syndicate/examples/actor/example-assertion-spike.rkt @@ -1,4 +1,31 @@ #lang syndicate/actor +;; +;; Test case for a problem written up on 25 Oct 2016 in my research +;; journal. +;; +;; When the problem exists, we see only "starting", and not +;; "stopping", because by the time the spawn action producing the 'up +;; actor is processed, 'up has already been retracted (by the +;; termination of 'asserter). +;; +;; This is an expectation/operation mismatch. +;; +;; The approach I've chosen is to *label* each instance of a +;; `during/actor` using the new syndicate/protocol/instance, and to +;; change the lifetime-control protocol between the spawner and +;; spawnee to match. +;; +;; PROBLEM OUTPUT: +;; +;; got done +;; starting +;; +;; EXPECTED OUTPUT: +;; +;; got done +;; starting +;; stopping +;; (require/activate syndicate/drivers/timer) diff --git a/racket/syndicate/protocol/instance.rkt b/racket/syndicate/protocol/instance.rkt new file mode 100644 index 0000000..91e815e --- /dev/null +++ b/racket/syndicate/protocol/instance.rkt @@ -0,0 +1,13 @@ +#lang racket/base +;; "Instance" protocol for discriminating among +;; otherwise-indistinguishable entities. + +(provide (struct-out instance)) + +;; (instance Any Any), assertion or message +;; +;; In cases where `spec` can have multiple instantiations, serves to +;; distinguish between them. Each `id` should be unique within its +;; scope. +;; +(struct instance (id spec) #:prefab)