liveBook · Manning

Mvar request-response pattern

As explained in Functional Design and Architecture: Examples in Haskell

The MVar request-response pattern is a communication pattern in which a service thread receives requests through an MVar and returns results through a response channel.

The MVar request–response pattern connects a requester to a service running in another thread. A pair of MVars forms a channel: one holds a request and the other returns its result. It gives actors an explicit communication boundary instead of direct access to one another’s internals. section 8.1.2 section 8.1.3

Figure 8.5 The MVar Request–Response pattern flow

The flow shows the reciprocal blocking that coordinates one requester and one responder: send a request, process it, then return a response. section 8.1.3

Use the channel as a small synchronous remote service:

  • The requester puts a value into the request MVar, then takes the matching result from the response MVar. section 8.1.3
  • The responder takes a request, computes its result, and puts that result into the response MVar before serving the next request. section 8.1.3
  • Pair every takeMVar with a later putMVar; an unfilled MVar can leave another thread blocked indefinitely. section 8.1.3

FizzBuzz worker

A generic Pipe bundles request and response MVars. sendRequest puts an integer and waits; a worker repeatedly takes integers, applies FizzBuzz, and puts back strings. The same shape can carry typed request constructors, such as simulation commands, with a response MVar stored inside the request that requires a matching result type. section 8.1.3 section 8.2.1

For a simulator actor, embedding the response MVar in a request constructor makes completion part of handling that request. A finite RunSimulation returns a result, while StartSimulation launches ongoing work without one. This protocol can later be translated to a process boundary such as HTTP or gRPC. section 8.2.1

The pattern is useful for small, orderly thread interactions, but large MVar-based concurrent models can become awkward and overcomplicated. When that happens, STM or a message queue may better fit the architecture. section 8.3

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Works through both MVar operations, blocking behavior, deadlock risks, and a typed protocol refinement.
Examples
Demonstrates a FizzBuzz worker and a simulator protocol with run, start, and shutdown requests.
What you can do after
Build it from scratch with paired MVars, a service loop, and typed per-request result channels.
How it connects
Connects actor model, MVars, software transactional memory, message queues, HTTP, and gRPC.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.