Hi, it's a long time that this question was posted, but I have found it interesting in the implementation of token refreshes.
First of all, for service invocation, given a `revise-oauth-token` method, I think this is good client code: (http/request {:method :get :url "https://example.com/" :oauth-token (revise-oauth-token token-store)}) If you find it too repetitive or fragile in your client code, you can make a local function, but I wouldn't abstract the service invocation at a higher layer. Regarding the implementation of the token store, we could initially think of a synchronized store, like an atom, and `revise-oauth-token` would swap its content when a refresh is required. This is inconvenient for multithreaded clients, because there could be several refresh invocations going on concurrently. In order to avoid concurrent refreshes, I propose to implement the token store as an atom of promises. Implementation of `revise-oauth-token` would be: (defn revise-oauth-token [token-store] (:access_token @(swap! token-store (fn [token-promise] (if (token-needs-refresh? @token-promise (Instant/now)) (delay (refresh-oauth-token (:refresh_token @token-promise))) token-promise))))) Note that using a delay avoids running `refresh-oauth-token` within the `swap!` operation, as this operation may be run multiple times. Also note that `token-needs-refresh` takes an argument with the present time. This keeps the function pure, which could help for unit testing, for example. There is an alternative implementation using `compare-and-set!` that avoids checking `token-needs-refresh?` several times, but it is more complicated. I have posted full sample code in a gist: https://gist.github.com/titogarcia/4f09bcc5fa38fbdc1076954b9a99a8fc Remark: None of this refers to "functional programming" per se. Dealing with state in a purely functional way involves using different constructs (like possibly monads, for which you can find Clojure libraries if you are interested), and best practices are still a topic of research. Clojure has taken the pragmatic approach of making purely functional code easy to write, but it doesn't reject the use of state, rather it provides well-behaved primitives like vars, atoms, agents, etc. Ernesto -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/ac79058b-2c31-4b9c-9cf3-e2de998eb8deo%40googlegroups.com.