<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Event-Driven-Architecture on Brian Faust</title><link>https://vacua.dev/tags/event-driven-architecture/</link><description>Recent content in Event-Driven-Architecture on Brian Faust</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate><atom:link href="https://vacua.dev/tags/event-driven-architecture/rss.xml" rel="self" type="application/rss+xml"/><item><title>A Process Manager Remembers What the Queue Cannot</title><link>https://vacua.dev/process-managers-long-running-business-processes/</link><pubDate>Fri, 01 Sep 2023 00:00:00 +0000</pubDate><guid>https://vacua.dev/process-managers-long-running-business-processes/</guid><description>&lt;p&gt;An order is paid at 10:00. Inventory is reserved at 10:01. The warehouse does
not respond until 14:30. Shipping fails the next morning, after two worker
deployments and a payment-provider timeout.&lt;/p&gt;
&lt;p&gt;No request, transaction, or queue worker owns that whole timeline. Chaining
jobs can move execution from one step to the next, but the queue does not know
whether the business process is waiting, complete, compensating, or stuck.&lt;/p&gt;
&lt;p&gt;A Process Manager exists to remember that state and decide what should happen
when a relevant message arrives. Its value begins where call-stack control
ends.&lt;/p&gt;</description></item><item><title>An Outbox Moves the Failure Window</title><link>https://vacua.dev/an-outbox-moves-the-failure-window/</link><pubDate>Tue, 01 Aug 2023 00:00:00 +0000</pubDate><guid>https://vacua.dev/an-outbox-moves-the-failure-window/</guid><description>&lt;p&gt;Place an order, commit it, then publish &lt;code&gt;OrderPlaced&lt;/code&gt;. If the broker rejects
the send, the order remains placed and nothing durable says publication is
still required.&lt;/p&gt;
&lt;p&gt;Reverse the sequence. Publish &lt;code&gt;OrderPlaced&lt;/code&gt;, then commit the order. If the
database rolls back, the broker now carries a fact which the source database
never accepted.&lt;/p&gt;
&lt;p&gt;A transactional outbox changes the sequence again. Insert the order and a
pending message in one local transaction. Rollback removes both. Commit makes
both durable. A separate relay can keep trying the message after the request
which placed the order has ended.&lt;/p&gt;</description></item><item><title>Publishing Events Is Not Event Sourcing</title><link>https://vacua.dev/publishing-events-is-not-event-sourcing/</link><pubDate>Sat, 01 Jul 2023 00:00:00 +0000</pubDate><guid>https://vacua.dev/publishing-events-is-not-event-sourcing/</guid><description>&lt;p&gt;Two wallet applications accept the same credits and publish the same
&lt;code&gt;FundsCredited&lt;/code&gt; event. Both end with a balance of 3,500 cents. Both can update
a listener-owned read model.&lt;/p&gt;
&lt;p&gt;Now delete the wallet row and ask each application to recover.&lt;/p&gt;
&lt;p&gt;The first application cannot. Its &lt;code&gt;wallets.balance_minor&lt;/code&gt; column was the
authoritative value. The events were notifications sent after accepted
changes, and their payloads do not contain enough information to reconstruct
the balance.&lt;/p&gt;</description></item><item><title>A Domain Event Is a Fact, Not a Question</title><link>https://vacua.dev/a-domain-event-is-a-fact-not-a-question/</link><pubDate>Thu, 01 Jun 2023 00:00:00 +0000</pubDate><guid>https://vacua.dev/a-domain-event-is-a-fact-not-a-question/</guid><description>&lt;p&gt;An order cannot be placed until a credit policy accepts it. The handler needs
that answer before it can continue:&lt;/p&gt;
&lt;figure class="code-figure"&gt;
 &lt;div class="code-block" data-copy-code&gt;
 &lt;button class="copy-code" type="button" aria-label="Copy code"&gt;copy&lt;/button&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;credit&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;allows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$amountCents&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CreditRefused&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$amountCents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$placedOn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Turn that call into a &lt;code&gt;CheckCredit&lt;/code&gt; event and the question does not disappear.
It becomes harder to see. The handler still needs an answer, but an event
dispatcher normally gives it a list of listeners, not a typed decision. Now
the code needs a mutable payload, stopped propagation, or some other private
convention to recover the response.&lt;/p&gt;</description></item><item><title>EventStorming Finds Disagreement Before It Finds Services</title><link>https://vacua.dev/domain-modeling-workshops-eventstorming-in-practice/</link><pubDate>Tue, 01 Feb 2022 00:00:00 +0000</pubDate><guid>https://vacua.dev/domain-modeling-workshops-eventstorming-in-practice/</guid><description>&lt;p&gt;Ask sales, support, finance, and engineering when an order becomes cancelled
and the answers may sound compatible until they share a wall.&lt;/p&gt;
&lt;p&gt;Sales says cancellation happens when the customer asks. Support says it
happens after a case is approved. Finance says a paid order remains active
until the refund clears. Engineering points to a &lt;code&gt;cancelled_at&lt;/code&gt; column written
before the payment provider responds.&lt;/p&gt;
&lt;p&gt;That disagreement is not workshop noise. It is the model.&lt;/p&gt;</description></item></channel></rss>