Fork me on GitHub
#core-async
<
2017-11-28
>
nickmbailey22:11:10

is there a common pattern where a function returns either a channel that will receive the result of some computation or the result itself immediately

nickmbailey22:11:18

for instance if the result is cached in memory

tanzoniteblack22:11:50

@nickmbailey creating channels is cheap, so we generally just have use cases like that always return a channel. NB: Creating a channel is cheap, go blocks are not, so don't just do (go val), but actually create a channel and put your value onto it. That way your calling functions don't have to do a check to see if they returned a channel or not

tanzoniteblack22:11:01

We use a helper function for this behavior, which might help you unless someone else has a better suggestion:

(defn val-chan
  "Helper function to make a value available on a channel without invoking
  `go`. Significantly faster alternative, since it doesn't require thread
  switching."
  [value]
  (let [c (async/chan 1)]
    (when (some? value)
      (async/put! c value))
    (async/close! c)
    c))

nickmbailey23:11:25

Do you typically have callers check if a value is immediately available?

nickmbailey23:11:00

My use case is a rest API and I want to return a 200 response with the value if it’s immediately available and a 202 with an id if it will need to be processed

tanzoniteblack23:11:32

https://clojuredocs.org/clojure.core.async/poll! ; a non-blocking take from a channel that will return nil if if thing isn't yet available

tbaldridge23:11:28

go blocks aren't that expensive

tbaldridge23:11:11

something like (go 1) is probably about as expensive as adding something to a hashmap