2022-11-30 19:50:25 +00:00
|
|
|
#lang racket/base
|
2022-11-30 18:27:54 +00:00
|
|
|
;;; SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
;;; SPDX-FileCopyrightText: Copyright © 2022 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
|
|
|
|
|
|
|
(provide async
|
|
|
|
async?
|
|
|
|
suspend
|
2022-11-30 19:50:25 +00:00
|
|
|
await
|
|
|
|
define/await)
|
2022-11-30 18:27:54 +00:00
|
|
|
|
|
|
|
(require (only-in (submod "actor.rkt" internals) with-active-facet))
|
2022-11-30 19:50:25 +00:00
|
|
|
(require "syntax.rkt")
|
2022-11-30 18:27:54 +00:00
|
|
|
|
|
|
|
(define prompt-tag (make-continuation-prompt-tag 'syndicate))
|
|
|
|
|
|
|
|
(define-syntax-rule (async body ...)
|
|
|
|
(async* (lambda () body ...)))
|
|
|
|
|
|
|
|
(define (async* thunk)
|
2022-12-09 08:24:13 +00:00
|
|
|
(call-with-continuation-prompt thunk prompt-tag (lambda (k) (k))))
|
2022-11-30 18:27:54 +00:00
|
|
|
|
|
|
|
(define (async?)
|
|
|
|
(continuation-prompt-available? prompt-tag))
|
|
|
|
|
|
|
|
(define (capture-chain proc)
|
|
|
|
(call-with-composable-continuation
|
|
|
|
(lambda (k)
|
|
|
|
(let ((k (lambda results
|
|
|
|
(async* (lambda () (apply k results))))))
|
|
|
|
(abort-current-continuation prompt-tag (lambda () (proc k)))))
|
|
|
|
prompt-tag))
|
|
|
|
|
|
|
|
(define (suspend proc)
|
|
|
|
(unless (async?) (error 'suspend "Cannot suspend async chain outside async block"))
|
|
|
|
(define facet this-facet)
|
|
|
|
(capture-chain
|
|
|
|
(lambda (k)
|
|
|
|
(proc (lambda results
|
|
|
|
(with-active-facet facet
|
|
|
|
(lambda ()
|
|
|
|
(apply k results))))))))
|
|
|
|
|
|
|
|
(define-syntax-rule (await k body ...)
|
|
|
|
(suspend (lambda (k)
|
|
|
|
(react
|
|
|
|
(define facet this-facet)
|
|
|
|
(let ((k (lambda results (stop-facet facet (apply k results)))))
|
|
|
|
body ...)))))
|
|
|
|
|
2022-11-30 19:50:25 +00:00
|
|
|
(define-syntax-rule (define/await [name (op args ...)] ...)
|
|
|
|
(define-values (name ...)
|
|
|
|
(await k
|
|
|
|
(define name (op query-result args ...)) ...
|
|
|
|
(sync! this-target (k name ...)))))
|
|
|
|
|
2022-11-30 18:27:54 +00:00
|
|
|
(module+ test
|
|
|
|
(require "dataspace.rkt")
|
|
|
|
(actor-system/dataspace (ds)
|
|
|
|
(spawn
|
|
|
|
#:name 'service
|
|
|
|
(at ds
|
|
|
|
(during 'waiting
|
|
|
|
(assert 'ready)
|
|
|
|
(on-stop (stop-current-facet)))))
|
|
|
|
(at ds
|
|
|
|
(define (D x) (log-info "~v ~a" this-facet x))
|
|
|
|
(on-start (D "outer+"))
|
|
|
|
(on-stop (D "outer-"))
|
|
|
|
(async (D "1")
|
|
|
|
(await k (D "@") (k (void)))
|
|
|
|
(D "2")
|
|
|
|
(await k
|
|
|
|
(on-start (D "A1+"))
|
|
|
|
(on-stop (D "A1-"))
|
|
|
|
(assert 'waiting)
|
|
|
|
(on (asserted 'ready)
|
|
|
|
(D "A2")
|
|
|
|
(k (void))))
|
|
|
|
(D "3")
|
|
|
|
(await k (D "B") (k (void)))
|
|
|
|
(D "4")
|
|
|
|
(stop-current-facet)))))
|