Make delete-role idempotent

This commit is contained in:
Tony Garnock-Jones 2012-03-24 15:59:52 -04:00
parent c278e10673
commit 523446fa71
1 changed files with 27 additions and 24 deletions

51
os2.rkt
View File

@ -193,30 +193,33 @@
hs))]))
(define (do-unsubscribe pid eid reason state)
(define endpoint-to-remove (hash-ref (vm-endpoints state) eid))
(define removed-topic (endpoint-topic endpoint-to-remove))
(define old-process (hash-ref (vm-processes state) pid))
(define new-process (struct-copy process old-process
[endpoints (set-remove (process-endpoints old-process) eid)]))
(let ((state (struct-copy vm state
[endpoints (hash-remove (vm-endpoints state) eid)]
[processes (if (set-empty? (process-endpoints new-process))
(hash-remove (vm-processes state) pid)
(hash-set (vm-processes state) pid new-process))])))
(for*/fold ([state state])
([(matching-pid p) (in-hash (vm-processes state))]
[matching-eid (in-set (process-endpoints p))]
[e (in-value (hash-ref (vm-endpoints state) matching-eid))]
[matching-topic (in-value (endpoint-topic e))]
[flow-pattern (in-value (topic-intersection removed-topic matching-topic))]
#:when flow-pattern)
(define outbound-flow (refine-topic removed-topic flow-pattern))
(run-trapk state
matching-pid
(handlers-absence (endpoint-handlers e))
matching-eid
outbound-flow
reason))))
(cond
[(hash-has-key? (vm-endpoints state) eid)
(define endpoint-to-remove (hash-ref (vm-endpoints state) eid))
(define removed-topic (endpoint-topic endpoint-to-remove))
(define old-process (hash-ref (vm-processes state) pid))
(define new-process (struct-copy process old-process
[endpoints (set-remove (process-endpoints old-process) eid)]))
(let ((state (struct-copy vm state
[endpoints (hash-remove (vm-endpoints state) eid)]
[processes (if (set-empty? (process-endpoints new-process))
(hash-remove (vm-processes state) pid)
(hash-set (vm-processes state) pid new-process))])))
(for*/fold ([state state])
([(matching-pid p) (in-hash (vm-processes state))]
[matching-eid (in-set (process-endpoints p))]
[e (in-value (hash-ref (vm-endpoints state) matching-eid))]
[matching-topic (in-value (endpoint-topic e))]
[flow-pattern (in-value (topic-intersection removed-topic matching-topic))]
#:when flow-pattern)
(define outbound-flow (refine-topic removed-topic flow-pattern))
(run-trapk state
matching-pid
(handlers-absence (endpoint-handlers e))
matching-eid
outbound-flow
reason)))]
[else state]))
(define (route-and-deliver message-topic body state)
(define pids-and-endpoints