-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
send-to-self - is it a code smell? #40
Comments
Hey Kamil, first of all, great news about finally migrating, congrats. Clojure.spec alone is well worth it. I don't like this Clojure's atoms would provide all the coordination needed here, however our handlers would need to return a function that can be applied in a Do you think that would make sense? |
Hm, that's true, and that would be going back one step almost to using I'm still in the middle of migration (other things got priority over that for a few days), and I tried to move from Something like: (defn helper
[...]
;; Helper wants to emit some messages, or alter state, as well.
{:emit-msg ....
:new-state ....})
(defn handler
[{:keys [current-state]}]
(let [helper-ret (helper ...)]
;; Handler wants to do all the things helper did, and also do some more
;; (i.e. emit more messages or alter state - but alter state based on the
;; state that helper returned, not the "current-state".
(__merge__ helper-ret {:emit-msg ....}))) I hope this is a clear example. It's manageable of course, but leads to an either ugly, or verbose code. One idea I was thinking about would be to use something like this instead: (defn handler
[...]
[{:emit-msg ...}
{:alter-state assoc :page 3}
{:emit-msg ...}
{:alter-state dissoc :data}]) So - a sequence of actions that handlers wants to do (which will be carried out by systems-toolbox). With this format, building on top of helper's return value is a simple matter of using This approach would also kinda solve the issue you described above too, right? I don't like the idea of referring to What do you think? |
Hey,
I'm in the middle of migrating to systems-toolbox 0.6.x (finally! :)) and it gets me to think again about
:send-to-self
(formerlyrun-handler
). It feels very weird to have to use that instead of:emit-msg
.In fact, the only reason we need it is because state component can grow very large. We can't split it, because this would mean having multiple state atoms. We don't want to do that - it makes sense (for all the reasons we discussed, and others are giving) to keep app state in a single place.
systems-toolbox
kinda encourages to think there's 1-1 relationship between state maps/atoms, and components (i.e. for a single state atom, you get a single component). That doesn't have to be the case, though, does it? By having a single state atom/map, upon which multiple state components would operate, we still get the advantage of having a single source of truth, and at the same time we could split logic sensibly which should make:send-to-self
simply unnecessary.For instance, let's imagine this state map:
We could have one state component that would operate on
:shopping-basket
, and another that would operate on:auth-token
. For instance:Imagine such handler - it would submit order for processing (adding an auth token to it), and at the same time ask auth component to get a fresh auth token (in this imaginary scenario tokens can be used only once).
To write such a code, I'd need both auth and purchase components to be separate, otherwise
:auth/renew-token
wouldn't get delivered.It's much cleaner than having to write:
This one is harder for a number of reasons:
:send-to-self
doesn't useput-fn
, so no meta support, among other goodness.I wonder what is your take on that?
The text was updated successfully, but these errors were encountered: