Fork me on GitHub
#cljfx
<
2022-04-13
>
acim122:04:05

Another question, maybe both can be answered whenever someone has time to catch up on these, I have a function defined for wrap effects (namely :read-file):

(fx/wrap-effects {:context   (fx/make-reset-effect *context)
                                                         :dispatch  fx/dispatch-effect
                                                         :read-dir  effects/recursive-directory-view
                                                         :read-file effects/read-file-content})

acim122:04:49

This works fine:

(defn read-file-content [v dispatch!]
  (future
    (let [c @file-cache
          f (:file v)]
      (if-let [cached-text (cache/lookup c f)]
        (do
          (compare-and-set! file-cache c (cache/hit c f)) ; prefer lose update for hit than a concurrent miss not cached
          (dispatch! (assoc (:on-result v) :text cached-text)))
        (let [text (lr-file/read f)]
          (reset! file-cache (cache/miss c f text))   ; prefer optimistic update on miss, possibly losing another miss
          (dispatch! (assoc (:on-result v) :text text)))))))

acim122:04:11

If I do it like this, preferring not to spawn a thread to read the file if it's already in hand, I get an exception on cache hit (not using future):

(defn read-file-content [v dispatch!]
  (let [c @file-cache
        f (:file v)]
    (if-let [cached-text (cache/lookup c f)]
      (do
        (compare-and-set! file-cache c (cache/hit c f))     ; prefer lose update for hit than a concurrent miss not cached
        (dispatch! (assoc (:on-result v) :text cached-text)))
      (future
        (let [text (lr-file/read f)]
          (reset! file-cache (cache/miss c f text))   ; prefer optimistic update on miss, possibly losing another miss
          (dispatch! (assoc (:on-result v) :text text)))))))

acim122:04:08

Exception: Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$promise$reify__8486 at clojure.lang.RT.seqFrom(RT.java:553) at clojure.lang.RT.seq(RT.java:533) at clojure.core$seq__5387.invokeStatic(core.clj:137) at clojure.core$seq__5387.invoke(core.clj:137) at cljfx.event_handler$wrap_effects$dispatch_sync_BANG___2133.invoke(event_handler.clj:27) at cljfx.event_handler$wrap_effects$dispatch_sync_BANG___2133.invoke(event_handler.clj:25) at log_reader.effects$read_file_content.invokeStatic(effects.clj:18) at log_reader.effects$read_file_content.invoke(effects.clj:12) at cljfx.event_handler$wrap_effects$dispatch_sync_BANG___2133.invoke(event_handler.clj:30)

vlaaad09:04:15

Not quite sure what's going on there, but it seems your event handler - not effect function - returns a promise? And it should return effect map...

acim114:04:35

Oh, I see. You're right, one event handler is returning a derefable from a call to fx/on-fx-thread . I meant that to be returning nil (no state changes), so maybe I need to add an explicit nil return there (EDIT: yup, that was it). Or find a way not to have to do it this way per your comment here: https://clojurians.slack.com/archives/CGHHJNENB/p1649927857568349?thread_ts=1649707330.172579&amp;cid=CGHHJNENB Thanks, @U47G49KHQ

acim122:04:37

Again, that's only for going down the non-future path. Seems like I must unconditionally execute my dispatch! call in another thread, or I'm missing the way to do what I'm intending