m/relieve – relieve backpressure

{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
        missionary/missionary {:mvn/version "b.27-SNAPSHOT"}
        com.hyperfiddle/rcf {:mvn/version "20220902-130636"}
        compliment/compliment {:mvn/version "0.3.9"}}}
Extensible Data Notation
(require
  '[hyperfiddle.rcf :as rcf :refer [tests ! % with]]
  '[missionary.core :as m])
(hyperfiddle.rcf/enable!)
8.2s

`m/relieve` is a dangerous primitive, yes it converts a discrete flow into a continuous flow BUT it does so by consuming the upstream flow as fast as possible and reducing it into an accumulator. In other words it "relieves" backpressure.

This is appropriate for event sources like user interactions (typing into a dom input) because you only care about the freshest value and you never want your backpressure to slow down the user from typing.

HOWEVER, by disabling backpressure you've ... lost all the benefits of backpressure, the whole point of backpressure is to tell the producer to slow down, backpressure is the right default.

the dangerous part is that m/relieve can be used to create "heaters" like this monster, which will turn your fan on while counting as fast as it can:

(tests
  (def <spinner
    (->> (m/ap (loop [] (m/amb (m/? (m/sleep 0 1)) (recur))))
         (m/reductions + 0)
         (m/relieve {})))
  (def !it (<spinner #(! ::notify) #(! ::terminate)))
  % := ::notify
  @!it := 1
  % := ::notify
  @!it := 2
  % := ::notify
  @!it := 3
  (!it))
1.5s

Here is a video of the heater: https://www.loom.com/share/4406782e7a29487d8186eda86f8ef17b

The safe way to turn a discrete flow into continuous flow is m/reductions with m/latest:

(tests
  "This counter is backpressured, it will count as fast as the consumer samples"
  (def <counter
    (->> (m/ap (loop [] (m/amb (m/? (m/sleep 0 1)) (recur))))
         (m/reductions + 0)
         (m/latest identity)))
  (def !it (<counter #(! ::notify) #(! ::terminate)))
  % := ::notify
  @!it := 1
  % := ::notify
  @!it := 2
  % := ::notify
  @!it := 3
  (!it))
1.0s
Runtimes (1)