-
Notifications
You must be signed in to change notification settings - Fork 0
Guide Concurrency
ARO's concurrency model is radically simple: feature sets are async, statements are sync. This chapter explains how ARO handles concurrent operations without requiring you to think about threads, locks, or async/await.
ARO's concurrency model matches how project managers think:
- "When X happens, do Y" — Feature sets are triggered by events
- "Do this, then this, then this" — Steps happen in order
You don't think about threads, locks, race conditions, or async/await. You think about things happening and responding to them in sequence.
Every feature set runs asynchronously when triggered by an event:
┌─────────────────────────────────────────────────────┐
│ Event Bus │
│ │
│ HTTP Request ──┬──► (listUsers: User API) │
│ │ │
│ Socket Data ───┼──► (Handle Data: Socket Handler) │
│ │ │
│ File Changed ──┼──► (Process File: File Handler) │
│ │ │
│ UserCreated ───┴──► (Send Email: Notification) │
│ │
│ (Multiple events trigger multiple feature sets │
│ running concurrently) │
└─────────────────────────────────────────────────────┘
When multiple events arrive, multiple feature sets execute simultaneously. 100 HTTP requests = 100 concurrent feature set executions.
Inside a feature set, statements execute synchronously and serially:
(Process Order: Order API) {
<Extract> the <data> from the <request: body>. (* 1. First *)
<Validate> the <data> for the <order-schema>. (* 2. Second *)
<Create> the <order> with <data>. (* 3. Third *)
<Store> the <order> in the <order-repository>. (* 4. Fourth *)
<Emit> to <Send Confirmation> with <order>. (* 5. Fifth *)
<Return> a <Created: status> with <order>. (* 6. Last *)
}
Each statement completes before the next one starts. No callbacks. No promises. No async/await syntax. Just sequential execution.
Traditional async code in JavaScript:
async function processOrder(req) {
const data = await extractData(req);
const validated = await validate(data);
const order = await createOrder(validated);
await storeOrder(order);
await emitEvent('OrderCreated', order);
return { status: 201, body: order };
}ARO code:
(Process Order: Order API) {
<Extract> the <data> from the <request: body>.
<Validate> the <data> for the <order-schema>.
<Create> the <order> with <data>.
<Store> the <order> in the <order-repository>.
<Emit> to <Send Confirmation> with <order>.
<Return> a <Created: status> with <order>.
}
No async. No await. Just statements in order.
Within a feature set, there's no shared mutable state problem:
- Variables are scoped to the feature set
- Statements execute serially
- No concurrent access to the same data
Events naturally express concurrency:
- User A requests an order while User B requests their profile
- Both feature sets run concurrently
- Each processes their own data independently
While you write synchronous-looking code, the ARO runtime executes operations asynchronously based on data dependencies. This is transparent to you.
The runtime performs data-flow driven execution:
- Eager Start: I/O operations begin immediately (non-blocking)
- Dependency Tracking: The runtime tracks which variables each statement needs
- Lazy Synchronization: Only wait for data when it's actually used
- Preserved Semantics: Results appear in statement order
(Process Config: File Handler) {
<Open> the <config-file> from the <path>. (* 1. Starts file load *)
<Compute> the <hash> for the <request>. (* 2. Runs immediately *)
<Log> <request> to the <console>. (* 3. Runs immediately *)
<Parse> the <config> from the <config-file>. (* 4. Waits for file *)
<Return> an <OK: status> with <config>.
}
What happens:
- Statement 1 kicks off file loading (async, returns immediately)
- Statements 2 and 3 execute while the file loads in background
- Statement 4 waits only if the file isn't ready yet
- You see: synchronous execution
- Runtime does: parallel I/O with sequential semantics
Write synchronous code. Get async performance.
Feature sets can trigger other feature sets:
(Create User: User API) {
<Extract> the <data> from the <request: body>.
<Create> the <user> with <data>.
<Store> the <user> in the <user-repository>.
(* Triggers other feature sets asynchronously *)
<Emit> to <Send Welcome Email> with <user>.
(* Continues immediately, doesn't wait for handler *)
<Return> a <Created: status> with <user>.
}
(Send Welcome Email: Notifications) {
<Extract> the <email> from the <event: email>.
<Send> the <welcome-email> to the <email>.
<Return> an <OK: status>.
}
When <Emit> executes:
- The event is dispatched to the target feature set
- Execution continues in the current feature set
- The target handler starts executing independently
ARO explicitly does not provide:
-
async/awaitkeywords - Promises / Futures
- Threads / Task spawning
- Locks / Mutexes / Semaphores
- Channels
- Actors
- Parallel for loops
These are implementation concerns. The runtime handles them. You write sequential code that responds to events.
(Application-Start: My API) {
<Start> the <http-server> on port 8080.
<Keepalive> the <application> for the <events>.
<Return> an <OK: status>.
}
(* Each request triggers this independently *)
(getUser: User API) {
<Extract> the <id> from the <pathParameters: id>.
<Retrieve> the <user> from the <user-repository> where id = <id>.
<Return> an <OK: status> with <user>.
}
(Application-Start: Echo Server) {
<Start> the <socket-server> on port 9000.
<Keepalive> the <application> for the <events>.
<Return> an <OK: status>.
}
(* Each client message triggers this independently *)
(Handle Data: Socket Event Handler) {
<Extract> the <data> from the <event: data>.
<Extract> the <connection> from the <event: connection>.
<Send> the <data> to the <connection>.
<Return> an <OK: status>.
}
(Application-Start: File Watcher) {
<Watch> the <directory> for the <changes> with "./watched".
<Keepalive> the <application> for the <events>.
<Return> an <OK: status>.
}
(* Each file change triggers this independently *)
(Handle File Change: File Event Handler) {
<Extract> the <path> from the <event: path>.
<Extract> the <type> from the <event: type>.
<Compute> the <message> from "File " + <path> + " " + <type>.
<Log> <message> to the <console>.
<Return> an <OK: status>.
}
| Concept | Behavior |
|---|---|
| Feature sets | Run async (triggered by events) |
| Statements | Appear sync (serial execution) |
| I/O operations | Async under the hood |
| Events | Non-blocking dispatch |
| Concurrency primitives | None needed |
Write synchronous code. Get async performance. No callbacks, no promises, no await.
Fundamentals
- The Basics
- Feature Sets
- Actions
- Variables
- Type System
- Control Flow
- Error Handling
- Computations
- Dates
- Concurrency
Runtime & Events
I/O & Communication
Advanced