Who decides what happens next: a boss, or the events themselves?
π Where this lives: the difference between these two styles is the difference between a script and an app. A script runs top to bottom and finishes β centralised control. A phone app sits there doing nothing until you touch it, a notification arrives, or the battery gets low β event-driven control. Choosing wrongly is the most painful architectural mistake to correct, because control style pervades every line: a codebase written as a call sequence cannot be converted to event-driven without rewriting essentially all of it. Search "event driven architecture versus orchestration".
The two families
The organisational models of a system (repository, layered,
clientβserver) describe its STATIC STRUCTURE but not how it
behaves at run time. CONTROL STYLES are concerned with the
control flow between subsystems β how the flow of control
between them is organised.
Two generic control styles are used in software systems:
CENTRALISED CONTROL
One subsystem has overall responsibility for control, and
starts and stops other subsystems.
EVENT-BASED CONTROL
Rather than one subsystem being responsible for control, each
subsystem can respond to externally generated events from
other subsystems or from the system's environment.
CENTRALISED CONTROL β TWO MODELS:
1. THE CALLβRETURN MODEL
The familiar top-down subroutine model where control
starts at the top of a subroutine hierarchy and, through
subroutine calls, passes to lower levels in the tree.
Β· applicable to SEQUENTIAL systems only
Β· the control subroutine is at the top; control passes
down and returns up
Β· simple to analyse β you can trace exactly what happens
when, and where a value came from
ββββββββββββββββ
β main β
βββββ¬ββββ¬ββββ¬βββ
β β β
ββββΌβ ββΌββ ββΌβββ
βr1 β βr2β βr3 β
βββββ ββββ βββββ
2. THE MANAGER MODEL
Applicable to CONCURRENT systems. One system component is
designated as a system MANAGER and controls the starting,
stopping and coordination of other system processes.
Β· a process is a subsystem or module that can execute in
parallel with other processes
Β· a manager may also be implemented in a sequential system
as a CASE STATEMENT that decides which process to
invoke depending on state variables β this variant is
often called a CALL-RETURN with dispatch, and is common
in real-time systems
ββββββββββββββββββββββββ
β system controller β
ββββ¬βββββ¬βββββ¬βββββ¬βββββ
β β β β
βββββΌβ βββΌβββ ββΌβββ ββΌβββββββ
βuserβ βsensβ βactβ βcomputeβ
βintfβ β or β βuatβ βprocessβ
ββββββ ββββββ βββββ βββββββββ
EVENT-BASED CONTROL β TWO MODELS:
1. BROADCAST MODELS
An event is broadcast to all subsystems. Any subsystem
that has registered to handle that event can handle it.
Β· effective in integrating subsystems distributed across
different computers on a network
Β· the subsystems that generate events do not know which
subsystem will handle them β so the coupling is
genuinely minimal
Β· a subsystem may generate an event, or register an
interest in particular events; when an event occurs the
handler is invoked
Β· CONTROL POLICY IS NOT EMBEDDED in the event and message
handler β the subsystems decide on the events of
interest to them
Β· DISADVANTAGE: the subsystem generating an event does not
know if or when the event will be handled
2. INTERRUPT-DRIVEN MODELS
Used in REAL-TIME SYSTEMS where interrupts are detected by
an interrupt handler and passed to some other component
for processing.
Β· there are a known number of interrupt types, each with a
handler
Β· each type is associated with a memory location, and a
hardware switch causes a transfer to its handler
Β· allows a VERY FAST RESPONSE to an event β this is the
point of the model
Β· DISADVANTAGES: complex to program and difficult to
validate; the number of interrupts is limited by the
hardware.
OTHER EVENT-DRIVEN MODELS worth naming:
SPREADSHEETS a cell change triggers recomputation of
dependent cells (a dependency-driven model)
PRODUCTION rule-based systems where a fact matching a
SYSTEMS rule's condition fires its action
The same feature, both ways
REQUIREMENT: when a licence is issued, print it, email the
applicant, update the revenue dashboard, and notify the police
records system.
CENTRALISED (callβreturn / manager):
LicenceIssuer.issue(app):
licence = allocateNumber(app)
printer.print(licence) # 1
mailer.send(app.email, licence) # 2
dashboard.increment(app.fee) # 3
policeSystem.notify(licence) # 4
app.status = ISSUED
return licence
β THE ORDER IS EXPLICIT AND READABLE. Anyone can see exactly
what happens, in what sequence, by reading one function.
β EASY TO DEBUG β one stack trace shows the whole story.
β TRANSACTIONAL REASONING IS POSSIBLE β you can wrap it.
β LicenceIssuer must KNOW ABOUT four subsystems. Adding an
SMS notification means editing this function β so the module
that issues licences changes whenever a notification
requirement changes. That is exactly the coupling problem.
β IF THE POLICE SYSTEM IS SLOW, issuing a licence is slow. The
officer waits at the counter for a system they do not care
about.
β IF THE POLICE SYSTEM IS DOWN, what should happen? Fail the
whole issuance? Then an external outage stops licence
issuance nationally. Swallow the error? Then records
silently diverge.
EVENT-BASED (broadcast):
LicenceIssuer.issue(app):
licence = allocateNumber(app)
app.status = ISSUED
publish(LicenceIssued(licence, app.id, app.fee))
return licence
# elsewhere, independently:
PrintService subscribes to LicenceIssued
MailService subscribes to LicenceIssued
DashboardService subscribes to LicenceIssued
PoliceGateway subscribes to LicenceIssued
β LicenceIssuer KNOWS ABOUT NOTHING. Adding SMS means adding
a new subscriber and editing no existing code β the
open/closed principle, achieved structurally.
β A SLOW OR DOWN SUBSCRIBER DOES NOT BLOCK issuance. The
officer is served; the police notification retries.
β NATURALLY DISTRIBUTABLE across machines.
β THE ORDER IS NO LONGER VISIBLE ANYWHERE. To answer "what
happens when a licence is issued?" you must search for
subscribers. This is the single biggest cost, and it grows
with the system.
β THE PUBLISHER DOES NOT KNOW IF THE EVENT WAS HANDLED. Did
the email go out? Nothing in the issuing code can tell you.
β DEBUGGING IS HARD β there is no single stack trace; you
need correlation ids and distributed tracing.
β NO TRANSACTION spans the subscribers. If printing fails
after the status is ISSUED, you have an issued licence with
no printed document, and you need a compensating action.
THE HONEST SUMMARY
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CENTRALISED EVENT-BASED
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
coupling high low
order of events explicit invisible
adding a consumer edit the caller add a subscriber
debugging one stack trace tracing required
failure isolation poor good
transactions natural need compensation
latency of the sum of all just the publish
originating action steps
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NEITHER COLUMN IS THE WINNER. Centralised control buys
UNDERSTANDABILITY at the price of coupling; event-based control
buys DECOUPLING at the price of understandability. The right
choice depends on which of those you are short of.
Where each style belongs
USE CENTRALISED CONTROL WHEN
Β· the sequence matters and must be auditable
Β· a transaction must span the steps
Β· the system is sequential, or small enough that one component
can reasonably know the others
Β· debuggability is worth more than flexibility β safety and
financial systems commonly choose this deliberately
USE EVENT-BASED CONTROL WHEN
Β· the set of reactions to an event is OPEN β you expect to add
more, and you do not want to edit the originator each time
Β· subsystems are distributed across machines or owned by
different teams
Β· reactions must not block or endanger the originating action
Β· the system must respond to environmental events it does not
initiate (real-time, embedded, GUI)
THE MIXED APPROACH THAT REAL SYSTEMS USE:
Keep the CRITICAL PATH centralised and transactional; push
everything else onto events.
LicenceIssuer.issue(app): # one transaction
licence = allocateNumber(app) # must not be lost
app.status = ISSUED # must not be lost
commit()
publish(LicenceIssued(...)) # everything optional
Print, email, dashboard and police notification are all
reactions that may be retried, delayed or added to. Number
allocation and status are invariants that must be atomic.
Splitting on that line β INVARIANTS CENTRALISED, REACTIONS
EVENT-DRIVEN β is the most useful heuristic in this topic, and
it is the shape almost every well-built system converges on.
The split heuristic β invariants centralised, reactions event-driven β is the most transferable idea in this topic. The test for which side a step belongs on: if this step silently never ran, would the system be in an incorrect state, or merely an incomplete one? Incorrect means it belongs inside the transaction; incomplete means it can be an event.
π Go further: the event-based column's worst problem β no transaction spans the subscribers β has a named solution: the saga pattern. Instead of one atomic transaction, you define a sequence of local transactions each with a compensating action, so a failure at step 4 triggers explicit undo of steps 3, 2 and 1 rather than a rollback. It is strictly harder than a database transaction (compensations are business decisions β you cannot "un-send" an email, you send a correction), and understanding why that difficulty is unavoidable in a distributed system is what makes the centralised/event trade-off concrete rather than stylistic. Search "saga pattern compensating transaction distributed".
π‘ Exam angle: describe both control styles and all four models β callβreturn and manager under centralised control, broadcast and interrupt-driven under event-based β with a diagram of each. State that callβreturn applies to sequential systems and the manager model to concurrent ones. Give the key disadvantage of each event model: for broadcast, the publisher does not know if or when the event will be handled; for interrupt-driven, it is complex to program and hard to validate, with a hardware-limited number of interrupts. Note that control styles describe dynamic behaviour, whereas organisational models describe static structure.
Syllabus points
Centralized vs event-based control
Create a free account to tick topics off, take notes as you read, watch the video lessons and get a day-by-day study plan built around your exam date.