Database Reference
In-Depth Information
How to do it…
In fact, the only change will be for the update-totals function, and even that change
is minor:
(defn update-totals [fields items]
(let [mzero (mapv (constantly 0) fields)
[sum-hu sum-fams] (sum-items mzero fields items)]
(dosync
( commute total-hu #(+ sum-hu %))
( commute total-fams #(+ sum-fams %)))))
Do you see the difference? We just used commute instead of alter . That's the only change
we need to make.
How it works…
Now the references are updated after the dosync . With alter , the changes happen inside
the dosync , within the same transaction. However, with commute , both changes are run
separately, and both are scheduled to run when Clojure knows there will be no conlicts.
Depending on the use case, this can dramatically cut down on the number of retries and
speed up the overall program.
Combining agents and STM
Agents by themselves are pretty useful. However, if we want to still use the agent task queuing
and concurrency framework, even though an agent function needs to coordinate the state
beyond the agent's own data, we'll need to use both agents and the STM: send or send-off
to coordinate the agent's state. This will need to be combined with dosync , ref-set , alter ,
or commute inside the agent function to coordinate with the other state.
This combination provides simplicity over complex state and data coordination problems. This is
a huge help in managing the complexity of a data processing and analysis system.
For this recipe, we'll look at the same problem we did in the Managing program complexity
with agents recipe. However, this time we'll structure it a little differently. The inal result will
be stored in a shared reference, and the agents will update it as they go.
 
Search WWH ::




Custom Search