mirror of
https://github.com/taoensso/telemere.git
synced 2026-02-12 14:35:17 +00:00
[new] Add with-signal
This commit is contained in:
parent
5a0d9d8241
commit
e8818b4ed3
2 changed files with 41 additions and 16 deletions
|
|
@ -76,6 +76,7 @@
|
||||||
impl/msg-splice
|
impl/msg-splice
|
||||||
impl/msg-skip
|
impl/msg-skip
|
||||||
#?(:clj impl/with-signals)
|
#?(:clj impl/with-signals)
|
||||||
|
#?(:clj impl/with-signal)
|
||||||
#?(:clj impl/signal!))
|
#?(:clj impl/signal!))
|
||||||
|
|
||||||
;;;; Signal help
|
;;;; Signal help
|
||||||
|
|
|
||||||
|
|
@ -222,8 +222,8 @@
|
||||||
|
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
||||||
(enc/defonce ^:dynamic *sig-spy* "To support `with-signals`" nil)
|
(enc/defonce ^:dynamic *sig-spy* "To support `with-signals`, etc." nil)
|
||||||
(enc/defonce ^:dynamic *sig-handlers* "?[<wrapped-handler-fn>]" nil)
|
(enc/defonce ^:dynamic *sig-handlers* "?[<wrapped-handler-fn>]" nil)
|
||||||
|
|
||||||
(defn- force-msg [sig]
|
(defn- force-msg [sig]
|
||||||
(if-not (map? sig)
|
(if-not (map? sig)
|
||||||
|
|
@ -235,11 +235,11 @@
|
||||||
(defn -with-signals
|
(defn -with-signals
|
||||||
"Private util to support `with-signals` macro."
|
"Private util to support `with-signals` macro."
|
||||||
[form-fn
|
[form-fn
|
||||||
{:keys [handle? force-msg? trap-errors?]
|
{:keys [handle? trap-errors? force-msg?]
|
||||||
:or {handle? true}}]
|
:or {handle? true}}]
|
||||||
|
|
||||||
(let [sigs_ (volatile! nil)]
|
(let [sigs_ (volatile! nil)]
|
||||||
(binding [*sig-spy* [sigs_ (not handle?)]]
|
(binding [*sig-spy* [sigs_ (not :last-only?) handle?]]
|
||||||
(let [form-result
|
(let [form-result
|
||||||
(if-not trap-errors?
|
(if-not trap-errors?
|
||||||
(form-fn)
|
(form-fn)
|
||||||
|
|
@ -255,38 +255,62 @@
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defmacro ^:public with-signals
|
(defmacro ^:public with-signals
|
||||||
"Executes given form and records any signals triggered by it.
|
"Experimental.
|
||||||
|
Executes given form and records any signals triggered by it.
|
||||||
Return value depends on given options. Useful for tests/debugging.
|
Return value depends on given options. Useful for tests/debugging.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
|
`handle?`
|
||||||
|
Should registered handlers receive signals triggered by form, as usual?
|
||||||
|
Default: true.
|
||||||
|
|
||||||
`trap-errors?`
|
`trap-errors?`
|
||||||
If true: returns [[form-value form-error] signals], trapping any form error.
|
If true: returns [[form-value form-error] signals], trapping any form error.
|
||||||
If false: returns [ form-value signals], throwing on form error.
|
If false: returns [ form-value signals], throwing on form error.
|
||||||
Default: false.
|
Default: false.
|
||||||
|
|
||||||
`handle?`
|
|
||||||
Should registered handlers receive signals triggered by form, as usual?
|
|
||||||
Default: true.
|
|
||||||
|
|
||||||
`force-msg?`
|
`force-msg?`
|
||||||
Should delayed `:msg_` fields in signals be replaced with realized strings?
|
Should delayed `:msg_` keys in signals be replaced with realized strings?
|
||||||
Default: false."
|
Default: false.
|
||||||
|
|
||||||
|
See also `with-signal` for a simpler API."
|
||||||
{:arglists
|
{:arglists
|
||||||
'([ form]
|
'([form]
|
||||||
[{:keys [handle? force-msg? trap-errors?]} form])}
|
[{:keys [handle? trap-errors? force-msg?]
|
||||||
|
:or {handle? true}} form])}
|
||||||
|
|
||||||
([ form] `(-with-signals (fn [] ~form) nil))
|
([ form] `(-with-signals (fn [] ~form) nil))
|
||||||
([opts form] `(-with-signals (fn [] ~form) ~opts))))
|
([opts form] `(-with-signals (fn [] ~form) ~opts))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defmacro ^:public with-signal
|
||||||
|
"Experimental
|
||||||
|
Minimal version of `with-signals`.
|
||||||
|
Executes given form and returns the last signal triggered by it.
|
||||||
|
Useful for tests/debugging.
|
||||||
|
|
||||||
|
- Always allows registered handlers to receive signals as usual.
|
||||||
|
- Always traps form errors.
|
||||||
|
- Never forces `:msg_` key.
|
||||||
|
|
||||||
|
See also `with-signals` for more options."
|
||||||
|
[form]
|
||||||
|
`(let [sig_# (volatile! nil)]
|
||||||
|
(binding [*sig-spy* [sig_# :last-only :handle]]
|
||||||
|
(enc/catching ~form))
|
||||||
|
@sig_#)))
|
||||||
|
|
||||||
(defn dispatch-signal!
|
(defn dispatch-signal!
|
||||||
"Dispatches given signal to registered handlers, supports `with-signals`."
|
"Dispatches given signal to registered handlers, supports `with-signals`."
|
||||||
[signal]
|
[signal]
|
||||||
(or
|
(or
|
||||||
(when-let [[sigs_ skip-handlers?] *sig-spy*]
|
(when-let [[v_ last-only? handle?] *sig-spy*]
|
||||||
(vswap! sigs_ #(conj (or % []) (sigs/signal-value signal nil)))
|
(let [sv (sigs/signal-value signal nil)]
|
||||||
skip-handlers?)
|
(if last-only?
|
||||||
|
(vreset! v_ sv)
|
||||||
|
(vswap! v_ #(conj (or % []) sv))))
|
||||||
|
(when-not handle? :stop))
|
||||||
|
|
||||||
(sigs/call-handlers! *sig-handlers* signal)))
|
(sigs/call-handlers! *sig-handlers* signal)))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue