(* Overe - OCaml Urbit Runtime with Multicore Support * * This is the main entry point that wires together: * - Nock interpreter and state management (nock_lib) * - I/O drivers (io_drivers) * - Eio async runtime * - Domain-based parallelism * * Architecture: * - Main event loop running on primary domain * - I/O drivers running in concurrent fibers * - Event processing with real Nock execution * - Effect dispatch to appropriate drivers *) open Nock_lib (* Run Overe with I/O drivers integrated *) let run_with_drivers ~env config = Printf.printf "šŸš€ Starting Overe Runtime with I/O Drivers\n%!"; Printf.printf " Pier: %s\n%!" config.Runtime.pier_path; Printf.printf " OCaml %s on %d cores\n%!" Sys.ocaml_version (Domain.recommended_domain_count ()); Printf.printf "\n"; Eio.Switch.run @@ fun sw -> let fs = Eio.Stdenv.fs env in (* Create runtime *) let runtime = Runtime.create ~sw ~fs config in (* Create event stream (lock-free!) *) let event_stream = Eio.Stream.create 1000 in Printf.printf "āœ“ Runtime created\n%!"; (* Load snapshot or boot fresh kernel *) (match State.load_snapshot runtime.Runtime.state ~fs config.snapshot_path with | Ok eve -> Printf.printf "āœ“ Loaded snapshot at event %Ld\n%!" eve | Error _msg -> Printf.printf "⚠ No snapshot found, booting from pill...\n%!"; (* Boot from ivory pill (minimal kernel - fast to load!) *) let pill_path = "ivory.pill" in Printf.printf "Loading pill: %s\n%!" pill_path; match Boot.boot_from_file ~fs runtime.state pill_path with | Ok () -> Printf.printf "āœ“ Arvo kernel loaded from pill!\n%!" | Error msg -> Printf.printf "āœ— Pill load failed: %s\n%!" msg; Printf.printf "Falling back to fake kernel...\n%!"; match Boot.boot_fake runtime.state with | Ok () -> Printf.printf "āœ“ Fake kernel booted\n%!" | Error msg2 -> Printf.printf "āœ— Boot failed: %s\n%!" msg2 ); (* Replay events from log *) Printf.printf "Replaying events from log...\n%!"; Eventlog.replay runtime.event_log ~sw (fun event_num _event -> Printf.printf " Replayed event %Ld\n%!" event_num ); Printf.printf "āœ“ Runtime ready! State: %s\n%!" (State.summary runtime.state); Printf.printf "\n"; (* Create I/O drivers *) Printf.printf "Initializing I/O drivers...\n%!"; (* Behn (timer) *) let behn = Io_drivers.Behn.create () in Printf.printf " āœ“ Behn (timers)\n%!"; (* Clay (filesystem) *) let clay_config = { Io_drivers.Clay.pier_path = config.pier_path } in let clay = Io_drivers.Clay.create clay_config in Printf.printf " āœ“ Clay (filesystem)\n%!"; (* Dill (terminal) *) let dill_config = { Io_drivers.Dill.prompt = "~zod:dojo>" } in let dill = Io_drivers.Dill.create dill_config in Printf.printf " āœ“ Dill (terminal)\n%!"; (* Iris (HTTP client) *) let iris = Io_drivers.Iris.create () in Printf.printf " āœ“ Iris (HTTP client)\n%!"; Printf.printf "\nšŸŽÆ All drivers initialized!\n\n"; (* Event processor fiber - processes events from the stream *) let event_processor () = Printf.printf "[Runtime] Event processor fiber started\n%!"; try while true do let ovum = Eio.Stream.take event_stream in (* Convert ovum to noun for Nock execution *) (* Ovum format: [wire card] *) let event_noun = Noun.cell ovum.Effects.wire ovum.Effects.card in (* Process event through Arvo *) let _effects = State.poke runtime.state event_noun in runtime.events_processed <- Int64.succ runtime.events_processed; (* Log progress periodically *) if Int64.rem runtime.events_processed 100L = 0L then Printf.printf "[Runtime] Processed %Ld events\n%!" runtime.events_processed done with End_of_file -> Printf.printf "[Runtime] Event processor shutting down\n%!" in (* Effect executor fiber - executes effects *) let effect_executor () = Printf.printf "[Runtime] Effect executor fiber started\n%!"; let rec loop () = match Effects.try_dequeue runtime.effect_queue with | None -> Eio.Time.sleep (Eio.Stdenv.clock env) 0.001; loop () | Some eff -> (match eff with | Effects.Log msg -> Printf.printf "[Effect] Log: %s\n%!" msg | Effects.SetTimer { id; time } -> Printf.printf "[Effect] SetTimer: id=%Ld time=%f\n%!" id time | _ -> Printf.printf "[Effect] Other effect\n%!" ); runtime.effects_executed <- Int64.succ runtime.effects_executed; loop () in try loop () with End_of_file -> Printf.printf "[Runtime] Effect executor shutting down\n%!" in (* Run all fibers concurrently *) Printf.printf "šŸš€ Starting all fibers...\n\n"; Eio.Fiber.all [ (* Core runtime fibers *) event_processor; effect_executor; (* I/O driver fibers *) (fun () -> Io_drivers.Behn.driver_fiber behn ~sw ~env ~effect_queue:runtime.effect_queue ~event_stream); (fun () -> Io_drivers.Clay.run clay ~env ~sw ~event_stream); (fun () -> let _ = Io_drivers.Dill.run dill ~env ~sw ~event_stream in ()); (fun () -> let _ = Io_drivers.Iris.run iris ~env ~sw ~event_stream in ()); ]; (* Shutdown *) Printf.printf "\nšŸ›‘ Runtime shutting down...\n%!"; Printf.printf " Events processed: %Ld\n%!" runtime.events_processed; Printf.printf " Effects executed: %Ld\n%!" runtime.effects_executed; (* Save final snapshot *) Printf.printf "Saving final snapshot...\n%!"; State.save_snapshot runtime.state ~fs config.snapshot_path; Printf.printf "āœ“ Snapshot saved\n%!" (* Main entry point *) let () = Printf.printf "\n"; Printf.printf "╔══════════════════════════════════════════════════════════════╗\n"; Printf.printf "ā•‘ Overe - OCaml Urbit Runtime with Multicore Support ā•‘\n"; Printf.printf "ā•‘ ā•‘\n"; Printf.printf "ā•‘ šŸš€ Features: ā•‘\n"; Printf.printf "ā•‘ - True multicore parallelism (OCaml 5 domains) ā•‘\n"; Printf.printf "ā•‘ - Async I/O with Eio (non-blocking everything!) ā•‘\n"; Printf.printf "ā•‘ - Parallel Nock execution (domainslib) ā•‘\n"; Printf.printf "ā•‘ - Full I/O driver stack (Behn/Ames/Eyre/Clay/Dill/Iris) ā•‘\n"; Printf.printf "ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n"; Printf.printf "\n"; (* Default config *) let config = Runtime.default_config ~pier_path:"./pier" () in (* Run with Eio *) Eio_main.run @@ fun env -> run_with_drivers ~env config