diff options
author | polwex <polwex@sortug.com> | 2025-10-06 04:03:14 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-10-06 04:03:14 +0700 |
commit | 24eac75c69b3d74388bbbc8ee2b6792e7590e4c6 (patch) | |
tree | 3e3a22dde0d977dca4b28fc92ada0faea24990f7 /ocaml/lib/effects.ml | |
parent | fd51dfdccf7b565e4214fe47a1420a9990fab342 (diff) |
did this madman really implement parallelism on urbit
Diffstat (limited to 'ocaml/lib/effects.ml')
-rw-r--r-- | ocaml/lib/effects.ml | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/ocaml/lib/effects.ml b/ocaml/lib/effects.ml new file mode 100644 index 0000000..e73af3e --- /dev/null +++ b/ocaml/lib/effects.ml @@ -0,0 +1,154 @@ +(* Effects - Output from Arvo event processing + * + * When Arvo processes an event (poke), it returns: + * - Updated kernel state + * - List of effects to perform + * + * Effects are messages to I/O drivers (vanes): + * - Behn: timers + * - Ames: network packets + * - Eyre: HTTP responses + * - Clay: filesystem operations + * - Dill: terminal output + * etc. + *) + +(* Effect type - what to do after processing an event *) +type t = + (* Timer effect: set a timer *) + | SetTimer of { + id: int64; (* Timer ID *) + time: float; (* Unix timestamp when to fire *) + } + + (* Timer effect: cancel a timer *) + | CancelTimer of { + id: int64; (* Timer ID to cancel *) + } + + (* Log effect: print to console *) + | Log of string + + (* Network effect: send UDP packet (Ames) *) + | SendPacket of { + dest: string; (* IP:port *) + data: bytes; (* Packet data *) + } + + (* HTTP effect: send HTTP response (Eyre) *) + | HttpResponse of { + id: int; (* Request ID *) + status: int; (* HTTP status code *) + headers: (string * string) list; + body: bytes; + } + + (* File effect: write file (Clay) *) + | WriteFile of { + path: string; + data: bytes; + } + + (* Generic placeholder for other effects *) + | Other of { + vane: string; (* Which vane (behn, ames, eyre, etc) *) + data: Noun.noun; (* Effect data as noun *) + } + +(* Effect result - what happened when we tried to execute an effect *) +type effect_result = + | Success + | Failed of string + +(* Ovum - an input event to Arvo + * + * Format: [wire card] + * wire: path for response routing + * card: [driver-name data] + *) +type ovum = { + wire: Noun.noun; (* Response routing path *) + card: Noun.noun; (* [vane-tag event-data] *) +} + +(* Create a simple ovum *) +let make_ovum ~wire ~card = { wire; card } + +(* Create a timer ovum (from behn) *) +let timer_ovum ~id ~fire_time = + { + wire = Noun.Atom (Z.of_int64 id); + card = Noun.cell + (Noun.atom 0) (* behn tag - simplified *) + (Noun.Atom (Z.of_float (fire_time *. 1000000.0))); (* microseconds *) + } + +(* Create a log ovum *) +let log_ovum ~msg:_ = + { + wire = Noun.atom 0; + card = Noun.cell + (Noun.atom 1) (* log tag *) + (Noun.atom 0); (* simplified - would be text *) + } + +(* Parse effects from Arvo output + * + * In a real implementation, this would parse the noun structure + * that Arvo returns and convert it to our effect types. + * + * For now: simplified - just return empty list + *) +let parse_effects (_arvo_output : Noun.noun) : t list = + (* TODO: Parse real Arvo effect format *) + [] + +(* Effect queue - for async effect processing *) +type queue = { + q: t Queue.t; + lock: Mutex.t; + cond: Condition.t; +} + +(* Create effect queue *) +let create_queue () = { + q = Queue.create (); + lock = Mutex.create (); + cond = Condition.create (); +} + +(* Add effect to queue *) +let enqueue queue eff = + Mutex.lock queue.lock; + Queue.add eff queue.q; + Condition.signal queue.cond; + Mutex.unlock queue.lock + +(* Get next effect from queue (blocking) *) +let dequeue queue = + Mutex.lock queue.lock; + while Queue.is_empty queue.q do + Condition.wait queue.cond queue.lock + done; + let eff = Queue.take queue.q in + Mutex.unlock queue.lock; + eff + +(* Try to get effect without blocking *) +let try_dequeue queue = + Mutex.lock queue.lock; + let result = + if Queue.is_empty queue.q then + None + else + Some (Queue.take queue.q) + in + Mutex.unlock queue.lock; + result + +(* Get queue length *) +let queue_length queue = + Mutex.lock queue.lock; + let len = Queue.length queue.q in + Mutex.unlock queue.lock; + len |