Use with-handlers in hub actor instead of actor* for fault isolation

This commit is contained in:
Tony Garnock-Jones 2016-10-25 17:06:45 -04:00
parent f2f8fda62e
commit f16b0884f0
1 changed files with 49 additions and 43 deletions

View File

@ -124,49 +124,55 @@
(actor #:name 'hub (actor #:name 'hub
(on (web-request-incoming (id req) vh 'post ("hub" ()) $body) (on (web-request-incoming (id req) vh 'post ("hub" ()) $body)
(actor* ;; Initially, I had an (actor* ...) form here for fault
#:name (gensym 'hub-post) ;; isolation. However, this led to problems since I wanted
(define params (make-immutable-hash ;; to use `assert!` and `retract!` to signal to the
(form-urlencoded->alist (bytes->string/utf-8 body)))) ;; `during/actor`, and the assertions were being lost as
(define callback (hash-ref params 'hub.callback)) ;; the `actor*` terminated. So instead, I'm using Rackety
(define mode ;; `with-handlers`.
(match (hash-ref params 'hub.mode) (define ok?
["subscribe" 'subscribe] (with-handlers [(values (lambda (e) #f))]
["unsubscribe" 'unsubscribe])) (define params (make-immutable-hash
(define topic (hash-ref params 'hub.topic)) (form-urlencoded->alist (bytes->string/utf-8 body))))
(define lease-seconds (define callback (hash-ref params 'hub.callback))
(match (hash-ref params 'hub.lease_seconds "unbounded") (define mode
["unbounded" #f] (match (hash-ref params 'hub.mode)
[n (string->number n)])) ["subscribe" 'subscribe]
(define secret-string (hash-ref params 'hub.secret #f)) ["unsubscribe" 'unsubscribe]))
(define secret-bytes (and secret-string (string->bytes/utf-8 secret-string))) (define topic (hash-ref params 'hub.topic))
(define expiry-deadline (and lease-seconds (+ (current-seconds) lease-seconds))) (define lease-seconds
(define canonical-hub (url->string (resource->url (web-request-header-resource req)))) (match (hash-ref params 'hub.lease_seconds "unbounded")
(define ok? ["unbounded" #f]
(match mode [n (string->number n)]))
['subscribe (define secret-string (hash-ref params 'hub.secret #f))
(if (subscription-change-validate "subscribe" (define secret-bytes (and secret-string (string->bytes/utf-8 secret-string)))
(or lease-seconds "unbounded") (define expiry-deadline (and lease-seconds (+ (current-seconds) lease-seconds)))
topic (define canonical-hub
callback) (url->string (resource->url (web-request-header-resource req))))
(begin (match mode
(retract! (subscription topic ? ? callback ?)) ['subscribe
(assert! (if (subscription-change-validate "subscribe"
(subscription topic expiry-deadline canonical-hub callback secret-bytes)) (or lease-seconds "unbounded")
#t) topic
#f)] callback)
['unsubscribe (begin
(if (subscription-change-validate "unsubscribe" (retract! (subscription topic ? ? callback ?))
#f (assert!
topic (subscription topic expiry-deadline canonical-hub callback secret-bytes))
callback) #t)
(begin #f)]
(retract! (subscription topic ? ? callback ?)) ['unsubscribe
#t) (if (subscription-change-validate "unsubscribe"
#f)])) #f
(if ok? topic
(web-respond/status! id 202 #"Accepted") callback)
(web-respond/status! id 403 #"Forbidden" #"Validation failed")))) (begin
(retract! (subscription topic ? ? callback ?))
#t)
#f)])))
(if ok?
(web-respond/status! id 202 #"Accepted")
(web-respond/status! id 403 #"Forbidden" #"Validation failed")))
(during/actor (subscription $topic _ _ $callback _) (during/actor (subscription $topic _ _ $callback _)
#:name (list 'subscription topic callback) #:name (list 'subscription topic callback)