CascadeGraph is a configuration-driven, event-driven computation engine that models execution as an explicit Directed Acyclic Graph (DAG) of Topics and Agents.
Instead of letting event-driven behavior emerge implicitly from callbacks, mutable state, and timing quirks, CascadeGraph makes the computation graph a first-class architectural artifact: validated up front, structurally bounded, and visible during execution.
The project explores a simple but powerful idea:
Strong structural constraints can make event-driven systems dramatically easier to reason about, debug, and trust.
Event-driven systems often become difficult to reason about because the most important behavior is not explicit in the architecture.
Common problems include:
- โ hidden mutable state inside callbacks
- ๐ cyclic dependencies and uncontrolled feedback loops
- ๐ tight coupling between computation, orchestration, and presentation
- โฑ behavior that depends more on timing than on structure
CascadeGraph explores a different design philosophy:
- ๐ง make the computation graph explicit
- ๐ validate structural correctness before execution begins
- ๐งฉ isolate computation units from each other
- ๐ก model dataflow directly instead of burying it in control flow
- ๐ reject invalid topologies early instead of debugging them at runtime
This pushes complexity to configuration validation time, not to the middle of execution.
This is not just a calculator over a graph.
CascadeGraph is interesting because it treats architecture itself as a correctness mechanism.
It demonstrates:
- ๐ณ DAG-enforced execution instead of permissive graph wiring
- ๐ Explicit dataflow through Topics and Agents
- ๐ก Isolated execution units using Active Objectโstyle wrappers
- ๐ง Fan-in / fan-out semantics as structural graph behavior
- ๐ก Live operational visibility through graph visualization and event streaming
- ๐งฑ Strict separation of concerns between model, controller, and UI
The result is a system where key guarantees come from structure, not discipline.
- graph topology is derived from configuration
- acyclicity is validated using DFS-based cycle detection
- cyclic graphs are rejected before execution begins
This guarantees:
- โ termination
- ๐ no feedback loops
- ๐ structural correctness by construction
Agents are narrow, reactive computation units.
- ๐ฅ inputs are explicit through subscribed Topics
- ๐ค outputs are explicit through published Topics
- ๐ no implicit direct coupling between Agents
Some agents may maintain local, bounded state where needed, such as fan-in behavior. That state is explicit and intentional, never global or hidden.
- ๐ก fan-out: Topics broadcast events to multiple downstream Agents
- ๐งฎ fan-in: Agents wait for required inputs before publishing
- ๐ dependencies are structural, not temporal
- graph structure is defined declaratively at runtime
- wiring is decoupled from Agent implementation
- Agents are instantiated dynamically via reflection
- Model โ Topics, Agents, Graph, execution semantics
- Controller โ REST API for config loading and event publishing
- View โ Cytoscape.js visualization driven by SSE
The domain model is completely unaware of HTTP, JSON, browser state, or UI concerns.
Topics are named, stateless pub/sub channels.
- ๐ข they fan out events to subscribed Agents
- ๐งผ they do not store message history
- ๐ they are managed centrally through
TopicManager
Agents are reactive computation units.
- ๐ฅ they subscribe to input Topics
- ๐ค they publish to output Topics
- ๐ they are driven by incoming events rather than direct invocation
- ๐ they are uniquely identified per configuration
Events are immutable payloads that move through the graph.
- ๐ immutable by design
- โก delivered synchronously at the Topic level
- ๐ structurally bounded by the DAG constraint
At a high level, execution works as follows:
- ๐ load textual configuration
- ๐ instantiate Agents via reflection
- ๐ wire Agents and Topics into a bipartite graph
- ๐ validate acyclicity and reject invalid graphs
- ๐งต wrap Agents with execution decorators
- ๐ publish input events via REST
- โก propagate events across the graph
- ๐ terminate naturally because cyclic propagation is impossible
This makes execution behavior easier to reason about because propagation is explicitly shaped by graph structure.
Each Agent is wrapped using an Active Objectโstyle decorator.
That wrapper provides:
- ๐งต a dedicated worker thread per Agent
- ๐ฌ a bounded queue per Agent
- ๐ serialized execution per Agent
This gives the system several useful properties:
- ๐ก isolation between Agents
- ๐ predictable per-Agent execution semantics
- ๐ฆ bounded backpressure at the Agent boundary
CascadeGraph does not guarantee one globally deterministic execution order across all Agents.
Its determinism is:
- โ structural โ the graph is acyclic and execution terminates
- โ local โ each Agent processes events serially
- โ not globally schedule-deterministic across the entire system
That trade-off is deliberate and explicit.
One of the strongest aspects of the project is that the computation model is not only explicit in code โ it is also visible during runtime.
The UI allows you to:
- ๐ load a demo computation graph
- โ๏ธ publish values into input Topics
- โจ watch graph nodes highlight as propagation happens
- ๐ inspect the live event log stream
- ๐งน clear Topic values and observe downstream effects
This makes CascadeGraph not just a graph engine, but a debuggable execution surface for event-driven computation.
Consider a simple configuration:
configs.PlusAgent
A,B
S
configs.IncAgent
S
S1
This means:
PlusAgentconsumesAandB, then publishes toSIncAgentconsumesS, then publishes toS1
If the user publishes:
A = 5B = 3
Then the graph may evolve as:
PlusAgentreceives both required inputs- it computes
S = 8 IncAgentreceivesS = 8- it computes
S1 = 9
In the UI, you can observe that propagation path directly through graph highlighting and live event logs.
- โ Fail-fast DAG validation before execution
- ๐ณ DFS-based cycle detection as a structural correctness gate
- ๐ Explicit fan-in / fan-out semantics
- ๐งต Active Objectโstyle Agent isolation with bounded queues
- ๐งฑ Strict MVC separation between domain model, API, and visualization
- ๐ก SSE-based live updates for runtime visibility
- ๐ญ Reflection-driven Agent instantiation for configurable composition
Rather than using design patterns as a checklist, CascadeGraph uses them to enforce architectural boundaries:
- ๐ข PublishโSubscribe โ Topics notify Agents without direct coupling
- ๐ฏ Strategy-like computation units โ each Agent encapsulates one computation rule
- ๐งต Decorator + Active Object โ execution behavior is separated from Agent logic
- ๐ญ Factory via reflection โ Agents are composed dynamically from configuration
- ๐ Centralized Topic registry โ preserves Topic identity and namespace consistency
- ๐งฑ Facade-like controller layer โ REST entrypoints hide orchestration details from the UI
The important point is not the pattern names themselves, but the constraints they help preserve.
CascadeGraph is intentionally constrained.
- ๐ซ feedback loops
- ๐ global execution ordering guarantees
- ๐ distributed multi-process execution
- ๐พ persistence or event replay
- ๐ฌ stronger-than-at-most-once delivery semantics
These constraints prioritize:
- ๐ง structural correctness
- ๐ debuggability
- ๐ predictability
- ๐งฉ explicit execution semantics
over maximal expressiveness or distributed throughput.
- ๐งฎ deterministic schedulers or topological execution modes
- ๐ distributed Topics via Kafka or Redis Streams
- ๐ง richer stateful Agents with lifecycle management
- ๐ retry policies and dead-letter Topics
- ๐ metrics, tracing, and critical-path analysis
- ๐งพ static configuration linting and richer validation
- โ Java 17+
- ๐ฆ Maven 3.6+
git clone <repository-url>
cd Design_MVCmvn spring-boot:runhttp://localhost:8080/
- Click Load Config to load the demo computation graph
- Enter a Topic name such as
Aand a value such as5, then click Publish - Watch the graph highlight as events propagate through the DAG
- Use the Event Log panel to inspect the live stream of system events
- Click Clear on a Topic to reset its value and observe downstream effects
- ๐ engineers learning event-driven or dataflow architectures
- ๐ผ portfolio reviewers evaluating system-level thinking
- ๐งฑ developers interested in workflow engines and constrained execution models
CascadeGraph demonstrates how to design event-driven systems around explicit structure and enforced constraints.
More specifically, it shows:
- ๐ณ graph-validated computation
- ๐ explicit dataflow modeling
- ๐ fail-fast structural validation
- ๐งต isolated reactive execution units
- ๐งฑ clean architectural separation
- ๐ก live runtime visibility through visualization and SSE
Constraining a system correctly often matters more than making it more powerful.
In CascadeGraph, explicit structure, isolation, and validation simplify reasoning about behavior that would otherwise become difficult to debug in traditional event-driven designs.
Shaked Arazi.