syndicate-rkt/syndicate/reassert.rkt

39 lines
1.5 KiB
Racket

;;; SPDX-License-Identifier: LGPL-3.0-or-later
;;; SPDX-FileCopyrightText: Copyright © 2010-2021 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
#lang syndicate
;; Re-assert an assertion when one of a set of triggering events is seen, after a delay.
;; Building block for building reconnection strategies.
(provide reassert-on
(struct-out fixed-retry))
(require/activate syndicate/drivers/timer)
(struct fixed-retry (delay-ms) #:transparent
#:property prop:procedure
(lambda (f) (values (fixed-retry-delay-ms f) f)))
(define-logger syndicate/reassert)
(define-syntax reassert-on
(syntax-rules ()
[(_ assertion #:strategy strategy reset-event ...)
(reassert-on* assertion
#:strategy strategy
(list (lambda (k) (stop-when reset-event (k))) ...))]
[(_ assertion reset-event ...)
(reassert-on assertion #:strategy (fixed-retry 1000) reset-event ...)]))
(begin-for-declarations
(define (reassert-on* assertion #:strategy strategy event-fns)
(on-start (let reassert ((strategy strategy))
(react (log-syndicate/reassert-debug "~v: Asserting" assertion)
(assert assertion)
(define (reset)
(log-syndicate/reassert-debug "~v: Resetting with ~v" assertion strategy)
(define-values (delay-ms next-strategy) (strategy))
(sleep (/ delay-ms 1000.0))
(reassert next-strategy))
(for-each (lambda (f) (f reset)) event-fns))))))