← Back to context

Comment by DeathArrow

9 hours ago

When working with high throughput concurrent code like consumer producer pipelines, it's better to avoid shared mutable state entirely. Something actor like fits better and C# or Go channels works wonders.

> it's better to avoid shared mutable state entirely.

Yes! I would even go so far as to have the type system separate the mutable from the non-mutable for this reason!

> Something actor like fits better and C# or Go channels works wonders.

Or even STM channels/queues:

  https://hackage.haskell.org/package/stm/docs/Control-Concurrent-STM-TChan.html
  https://hackage.haskell.org/package/stm/docs/Control-Concurrent-STM-TQueue.html

Account balance is necessarily a shared mutable state.

  • It's not necessarily shared. You could assign a single thread to own the account balances, reading requests from a message queue. That probably scales better than locking. A single thread can do several million transactions per second, more than the entire global financial system.

    • What if you want to compose an action on a balance with something else? (That is what the OP is about)

      Also, with a queue, you've moved the shared state elsewhere, namely, into the queue.

      2 replies →

    • And in a green threading system like Go or Scala Cats, the balances thread isn’t a thread at all, and it will run in the same thread as the transfer caller when the call isn’t contended, so you don’t even have a context switch.

Sure, but sometimes shared mutable state is better, especially from a performance point of view. For example blurring an image.

  • Isn't that a typical case where you don't have to share anything? Divide the image into N chunks, let N threads handle each one, no sharing, just need a single sync point at the end to wait on completion.