Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ready-event allocation #114

Open
jackfirth opened this issue Dec 7, 2017 · 3 comments
Open

Ready-event allocation #114

jackfirth opened this issue Dec 7, 2017 · 3 comments

Comments

@jackfirth
Copy link
Owner

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:

(define my-disposable
  (disposable-evt <evt-alloc>
                  <evt-result-dealloc>))

Which is equivalent to this...

(define (wrapper e)
  (<evt-result-dealloc> (sync/timeout #f e)))
(define my-disposable
  (disposable-apply sync (disposable <evt-alloc> wrapper)))

Thanks for the idea @BourgondAries!

@jackfirth
Copy link
Owner Author

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.

@jackfirth
Copy link
Owner Author

jackfirth commented Dec 11, 2017

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.

@jackfirth
Copy link
Owner Author

jackfirth commented Dec 11, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant