Fork me on GitHub
Ivan Koz06:07:48

I'm writing a simple async rest client, and there is an auth session token that should be shared, updated between all requests. I came up with a lock based solution, is there better options to do so? <>


I usually have a core.async go block that runs a loop keeping credentials fresh and handing credentials to anyone that needs them. I don't think keeping state for a rest client in a global singleton (a def) is a good idea.

Ivan Koz06:07:47

do you have any public code at hand that i could peek into?


Not of mine, no. is vaguely similar, but much more complex, largely due to different potential ways to get away credentials. I've mostly used the core.async loop think for exchanging credentials for a bearer token and keeping that token up to date.


aws-api creates a single scheduled executor for doing refreshes, but the credential state itself is in passed around atoms (not singletons)

Ivan Koz06:07:53

thanks, i'll dig into it


If it truly is a kind of stateful session token, forcing serial interaction, I would be tempted to use a threadpool of size 1 to enforce that instead of a lock, basically instead of blocking on a lock, when you need to access the serial resource you throw a thunk on the threadpool for that resource. But that may be more complex, just the idea that serial usage can be well represented by the execution of a single thread, instead serializing multiple threads via a lock


When calling core.async's thread function, will that use the thread pool? Or is it equivalent to spawning a new Java thread?


it's backed by a cachedthreadpool


I see, thanks! 🙂


This took me by surprise:

(sorted-map "hello" "world")               ;; => {"hello" "world"}
(sorted-map :hello :world)                 ;; => {:hello :world}
(sorted-map "hello" "world" :hello :world) ;; => Execution error: class java.lang.String cannot be cast to class clojure.lang.Keyword
Is this expected?


Sorted map needs comparable keys. This makes it unsafe for checking if a key is there or not, unless you provide a comparator that can sort any key


hi please help how i can do arity overload in defprotocol?

(defprotocol Logger
    ([_ params])
    ([_ ex params]))
(defprotocol Logger
  (error [_ params])
  (error [_ ex params])))
are not working --- UPD: found
(defprotocol Logger
    [_ params]
    [_ ex params]))


The empty? docstring famously recommends using seq instead of (not (empty? . However doesn't that create transient garbage? Which might happen in a tight loop, you never know Maybe I can use not-empty (or just (not (empty? )? What is being traded off other than concision?


(empty? x) is already (not (seq x)).

👍 1

what about not-empty then?


Clojure 1.11.1
user=> (source not-empty)
(defn not-empty
  "If coll is empty, returns nil, else coll"
  {:added "1.0"
   :static true}
  [coll] (when (seq coll) coll))


I should have checked :) I thought not-empty was directly backed by some java code


Nah, seq is at the very bottom.


It sounds a bit off that for any emptiness check you have to coerce to seq first. I would wager that any given coll just knows whether it's empty - it could be a fast boolean check?


i think it's changing in clojure 1.12


it will be based on count if the operation is O(1)


awesome! Good timing


> any given coll just knows whether it's empty Lazy seqs don't know that though. And constructing ephemeral classes that will be thrown away almost immediately should be a cheap op at the end of the day, at least as far as I'm aware, given all the optimizations JVM is doing. Of course, probably not as cheap as a check of a field or whatever, but still much cheaper than one might guess.


Ephemeral objects rather than ephemeral classes

👍 1