Open jackfirth opened 6 years ago
Uh oh: disposable-apply
calls the function during allocation of the wrapper disposable, so it's also called with breaks enabled. Maybe the underlying disposable
protocol needs a way for a function to say which parts of allocation require that breaking is enabled? Or maybe all allocation and deallocation should be expressed in terms of events internally.
Update: breaks can be re-enabled inside a region where breaks are disabled (just like parameterizations) so this ought to be possible using helpers like this:
(define (unbreakable-evt evt)
(guard-evt (λ () (parameterize-break #f (sync evt)))))
(define (breakable-evt evt)
(guard-evt (λ () (parameterize-break #t (sync evt)))))
Then, with disposable allocation and deallocation defined in terms of events, a disposable that needs to wait arbitrarily could use these helpers to specify when breaking is or isn't allowed.
But this might be a bad idea. I'll have to find out more about how events and breaks interact.
Turns out the way disposable-apply
spawns child threads causes breaks to not be propagated regardless of how the joined disposables handle breaks. Had a discussion in the Racket slack channel which resulted in this:
(define (pair-evt a b)
(define left (handle-evt a (cons 'left _)))
(define right (handle-evt b (cons 'right _)))
(replace-evt (choice-evt left right)
(match-lambda
[(cons 'left v) (handle-evt b (cons v _))]
[(cons 'right v) (handle-evt a (cons _ v))])))
Something built on top of this ought to be capable of replacing the current delay/thread
backed implementation of disposable-apply
. This would require no child threads be spawned, making break forwarding and exception handling simpler.
Attempting to make a disposable with
tcp-accept
and port closing is undesirable, because waiting for a connection could take an arbitrarily long time and disposable allocation is called with breaks disabled. Instead, such a disposable should work by creating an event that is ready for synchronization when a connection is established, and guarantees no connection was created if it's not chosen for synchronization. A helper for constructing these sorts of disposables would help people avoid doing things the wrong way. Something like this:Which is equivalent to this...
Thanks for the idea @BourgondAries!