oracle-samples/clara-rules

Make fire-rules "cancellable"

Zylox opened this issue · 2 comments

Zylox commented

Consider the following just as an example (infinitely looping rules are just to show a "long running" session, not the case we are expecting to catch) :

(ns clara.test-interruption
  (:require [clara.rules :as r]))

(def counter (atom 0))

(defrecord A [])
(r/defrule a-rule
  [A]
  =>
  (swap! counter inc)
  (r/insert! (->A)))
(defn lock-me
  []
  (-> (r/mk-session)
      (r/insert (->A))
      (r/fire-rules)))
(defn background-lock
  []
  (let [fut (future (lock-me))
        val (deref fut 5000 :dead)]
    (when (= :dead val)
      (println "session timed out, cancelling")
      (println "counter at " (deref counter))
      (future-cancel fut))
    (println "done")))

If you execute this, then periodically check on the state of the counter, you can see that the "cancelled" future is still executing in the background.

We have a use case where we would like to abort firing rules and throw away the session if it takes too long. Using futures, we are able to return control to the parent thread, but the session keeps executing in the background. This can be problematic.

The most naive way to do this is the following: Zylox@81c1fb0. Running the above example with this line DOES cancel the future.

If the session is "stuck" in somewhere other than fire-rules* this obviously wont help, but i think thats where the vast majority of long running session would be. Also this doesn't have any answer for how this would happen in cljs (because to be honest i know near nothing about cljs)

This might be too naive though. The session is in a garbage state in this situation and we should probably find a way to indicate as much. I haven't had time to think about the best way to do this and am open to ideas.

EDIT: updated example to something slightly better.

The session being “in a bad state” after maybe isn’t really a big concern. I think this would be the case for other exceptions thrown during rule execution anyways right? So not really a unique case if so

Zylox commented

upon some further thought, i do think there are probably some more places we would want to make "interruptable" than just the one in my example....i'll mock up some examples when i get some more time.