Demonstrate the general insufficiency of the approach of commit 2a0197b
This commit is contained in:
parent
e0dc583f51
commit
0acd504d05
|
@ -6,12 +6,24 @@
|
|||
;; demand for port 5999. This causes connections to be accepted on
|
||||
;; port 6000 going nowhere.
|
||||
;;
|
||||
;; One fix is to use #:assertions to give the TCP listener actor some
|
||||
;; initial interests, thus transferring responsibility atomically.
|
||||
;; Another is to modify the demand-matcher to do something like
|
||||
;; `during/spawn` is doing, using an auxiliary protocol to centralise
|
||||
;; tracking of demand and supply at the demand-matcher rather than
|
||||
;; delegating it to the services.
|
||||
;; One "fix" is to use #:assertions to give the TCP listener actor
|
||||
;; some initial interests, thus transferring responsibility
|
||||
;; atomically. This has been implemented (in commit 2a0197b). However,
|
||||
;; this doesn't completely eliminate all possible instances where
|
||||
;; demand may change too quickly. See example-demand-matcher-glitch-bug2.rkt.
|
||||
;;
|
||||
;; A speculative idea is to use a kind of contract-monitor to enforce
|
||||
;; the invariant that demand *cannot* fluctuate too rapidly. One might
|
||||
;; write that "if (listen 6000) is asserted, then if (listen 6000) is
|
||||
;; retracted, (observe (listen 6000)) must have been asserted in the
|
||||
;; causal history of the retraction", but what does "causal history"
|
||||
;; mean, precisely? And how can it be soundly and efficiently tracked?
|
||||
;;
|
||||
;; The only "fix" that both solves the problem and is currently
|
||||
;; implementable that I have thought of is to modify the
|
||||
;; demand-matcher to do something like `during/spawn` is doing, using
|
||||
;; an auxiliary protocol to centralise tracking of demand and supply
|
||||
;; at the demand-matcher rather than delegating it to the services.
|
||||
|
||||
(require syndicate/protocol/advertise)
|
||||
(require/activate syndicate/drivers/tcp)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
(#f #f name-summary ((() . "'ground")))
|
||||
(#f #s(spacetime (meta) 0) actions-produced 1)
|
||||
(#f #s(spacetime (0) 1) spawn "drivers/tcp:dm:listener")
|
||||
(#s(spacetime (0) 1) #s(spacetime (0) 2) actions-produced 1)
|
||||
(#f #s(spacetime (1) 3) spawn "drivers/tcp:dm:connect")
|
||||
(#s(spacetime (1) 3) #s(spacetime (1) 4) actions-produced 1)
|
||||
(#f #s(spacetime (2) 5) spawn "strobe")
|
||||
(#s(spacetime (2) 5) #s(spacetime (2) 6) exit "#f")
|
||||
(#s(spacetime (2) 5) #s(spacetime (2) 7) actions-produced 2)
|
||||
(#s(spacetime (meta) 0) #s(spacetime () 8) action-interpreted patch "- ::: nothing\n+ <s:observe/1 <s:outbound/1 ★ {#t}\n+ <s:observe/1 <s:observe/1 <s:inbound/1 ★ {#t}\n")
|
||||
(#s(spacetime (1) 9) #s(spacetime (1) 10) turn-begin)
|
||||
(#s(spacetime (1) 10) #s(spacetime (1) 11) turn-end)
|
||||
(#s(spacetime (0) 12) #s(spacetime (0) 13) turn-begin)
|
||||
(#s(spacetime (0) 13) #s(spacetime (0) 14) turn-end)
|
||||
(#f #s(spacetime () 15) turn-end)
|
||||
(#s(spacetime () 17) #s(spacetime () 18) turn-begin)
|
||||
(#s(spacetime (0) 2) #s(spacetime () 19) action-interpreted patch "- ::: nothing\n+ <s:observe/1 <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 ★ ★ {#t}\n+ <s:observe/1 <s:advertise/1 <s:advertise/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 ★ ★ {#t}\n+ <s:advertise/1 <s:advertise/1 <s:advertise/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 ★ ★ {#t}\n")
|
||||
(#s(spacetime (1) 4) #s(spacetime () 20) action-interpreted patch "- ::: nothing\n+ <s:observe/1 <s:observe/1 <s:tcp-channel/3 <s:tcp-handle/1 ★ <s:tcp-address/2 ★ ★ ★ {#t}\n+ <s:observe/1 <s:advertise/1 <s:tcp-channel/3 <s:tcp-handle/1 ★ <s:tcp-address/2 ★ ★ ★ {#t}\n+ <s:advertise/1 <s:observe/1 <s:tcp-channel/3 <s:tcp-handle/1 ★ <s:tcp-address/2 ★ ★ ★ {#t}\n")
|
||||
(#s(spacetime (2) 7) #s(spacetime () 21) action-interpreted patch "- ::: nothing\n+ <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {#t}\n")
|
||||
(#s(spacetime () 21) #s(spacetime (0) 22) event patch "- ::: nothing\n+ <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {2}\n" #s(spacetime (2) 7) ((2)))
|
||||
(#s(spacetime (0) 22) #s(spacetime (0) 23) turn-begin)
|
||||
(#s(spacetime (0) 23) #s(spacetime (0) 24) turn-end)
|
||||
(#s(spacetime (0) 24) #s(spacetime (0) 25) actions-produced 1)
|
||||
(#s(spacetime (2) 7) #s(spacetime () 26) action-interpreted patch "- <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {#t}\n+ ::: nothing\n")
|
||||
(#s(spacetime () 26) #s(spacetime (0) 27) event patch "- <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {2}\n+ ::: nothing\n" #s(spacetime (2) 7) ((2)))
|
||||
(#s(spacetime (0) 27) #s(spacetime (0) 28) turn-begin)
|
||||
(#s(spacetime (0) 28) #s(spacetime (0) 29) turn-end)
|
||||
(#s(spacetime (2) 7) #s(spacetime () 31) quit)
|
||||
(#s(spacetime (0) 32) #s(spacetime (0) 33) turn-begin)
|
||||
(#s(spacetime (0) 33) #s(spacetime (0) 34) turn-end)
|
||||
(#s(spacetime () 18) #s(spacetime () 35) turn-end)
|
||||
(#s(spacetime () 37) #s(spacetime () 38) turn-begin)
|
||||
(#s(spacetime (0) 25) #s(spacetime (3) 39) spawn "(drivers/tcp:listen 6000)")
|
||||
(#s(spacetime (3) 39) #s(spacetime (3) 40) actions-produced 1)
|
||||
(#s(spacetime (3) 40) #s(spacetime () 42) action-interpreted patch "- ::: nothing\n+ <s:observe/1 <s:inbound/1 <s:tcp-accepted/4 ★ <s:tcp-listener/1 6000 ★ ★ {#t}\n+ <s:observe/1 <s:advertise/1 <s:observe/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {#t}\n+ <s:advertise/1 <s:advertise/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {#t}\n")
|
||||
(#s(spacetime () 42) #s(spacetime (0) 43) event patch "- ::: nothing\n+ <s:advertise/1 <s:advertise/1 <s:tcp-channel/3 ★ <s:tcp-listener/1 6000 ★ {3}\n" #s(spacetime (3) 40) ((3)))
|
||||
(#s(spacetime (0) 43) #s(spacetime (0) 44) turn-begin)
|
||||
(#s(spacetime (0) 44) #s(spacetime (0) 45) turn-end)
|
||||
(#s(spacetime (3) 47) #s(spacetime (3) 48) turn-begin)
|
||||
(#s(spacetime (3) 48) #s(spacetime (3) 49) turn-end)
|
||||
(#s(spacetime (0) 50) #s(spacetime (0) 51) turn-begin)
|
||||
(#s(spacetime (0) 51) #s(spacetime (0) 52) turn-end)
|
||||
(#s(spacetime () 38) #s(spacetime () 53) turn-end)
|
||||
(#s(spacetime () 55) #s(spacetime () 56) turn-begin)
|
||||
(#s(spacetime () 56) #s(spacetime () 57) turn-end)
|
Binary file not shown.
After Width: | Height: | Size: 116 KiB |
|
@ -0,0 +1,23 @@
|
|||
#lang syndicate/actor
|
||||
;; Example showing an interesting design flaw (?) (bug?) in the
|
||||
;; old-school LLL demand-matcher when demand changes too quickly. The
|
||||
;; port 6000 server is started, but by the time it starts monitoring
|
||||
;; demand for its services, the demand is already gone, replaced with
|
||||
;; demand for port 5999. This causes connections to be accepted on
|
||||
;; port 6000 going nowhere.
|
||||
;;
|
||||
;; Demonstrates that the fix in commit 2a0197b isn't in general
|
||||
;; sufficient.
|
||||
|
||||
(require syndicate/protocol/advertise)
|
||||
(require/activate syndicate/drivers/tcp)
|
||||
|
||||
(define X (advertise (observe (tcp-channel ? (tcp-listener 6000) ?))))
|
||||
|
||||
(spawn* #:name 'strobe
|
||||
(assert! X)
|
||||
(printf "Asserted ~v\n" X)
|
||||
;; (begin (send! 'dummy)
|
||||
;; (retract! X)
|
||||
;; (printf "Retracted ~v\n" X))
|
||||
(printf "Terminating.\n"))
|
Loading…
Reference in New Issue