Libtmux_unix.Workspace.await
- val await : ?cancel:Cancellation
.t -> ?compensate_on_failure:bool -> t -> (Libtmux_workspace , Libtmux.Execution .receipt .Error ) result.t -
Public owner:
Libtmux_unixApply steps at most once per execution handle. Expected failures return retained receipts. On initial application,
compensate_on_failuredefaults totrue, attempting removal of proven newly created panes after failure or cancellation. Passingfalseskips that compensation. Cancellation propagates after recording progress and at most 500 ms of protected compensation; useinspectafterward.Examples#
Start a private server and capture its first session. This complete program creates a private daemon, checks its result and closes its clients. Use OCaml 5.5.2 on Linux with tmux 3.3a through 3.8. Run it from the source checkout after following the installation guide. View source
open Libtmuxmodule Client = Libtmux_unix.Clientmodule Workspace = Libtmux_unix.Workspacemodule Config = Libtmux_workspace.Configmodule Plan = Libtmux_workspace.Planmodule Execution = Libtmux_workspace.Executionlet checked pp = function| Ok value -> value| Error error -> failwith (Format.asprintf "%a" pp error)let get result = checked Error.pp resultlet protect ~finally use =match use () with| value ->finally ();value| exception error ->let backtrace = Printexc.get_raw_backtrace () in(try finally ()with cleanup ->Format.eprintf "cleanup failed: %s@." (Printexc.to_string cleanup));Printexc.raise_with_backtrace error backtrace(* docs:begin bootstrap *)let bootstrap ~binary ~version ~directory endpoint =let spawn = Spawn.make (Exec { program = "/bin/cat"; args = [ "-u" ] }) inlet config =Config.make ~directory ~session:"bootstrap-demo"[ Config.window ~name:"editor" [ Config.pane ~spawn () ] ]|> checked Config.pp_errorinlet plan =Plan.make ~endpoint ~version ~observed:None config |> checked Plan.pp_erroringet (Workspace.submit_bootstrap ~binary plan)(* docs:end bootstrap *)let require_success (receipt : Execution.receipt) =if receipt.status <> Execution.Succeeded then (Format.eprintf "workspace %s did not complete@." receipt.operation_id;(match receipt.status with| Execution.Rejected error -> Format.eprintf "%a@." Plan.pp_error error| Execution.Unavailable error -> Format.eprintf "%a@." Error.pp error| _ -> ());Iarray.iter(fun (step : Execution.step) ->match step.status with| Execution.Failed error | Execution.Uncertain error ->Format.eprintf "step %d: %a@." step.index Error.pp error| _ -> ())receipt.steps;Option.iter(fun error -> Format.eprintf "compensation: %a@." Error.pp error)receipt.cleanup_error;Iarray.iter(fun (cleanup : Execution.cleanup) ->match cleanup.outcome with| Ok () -> ()| Error error -> Format.eprintf "cleanup: %a@." Error.pp error)receipt.cleanup;failwith "bootstrap incomplete; no automatic retry")let local_version binary =let input = Unix.open_process_args_in binary [| binary; "-V" |] inlet version =protect~finally:(fun () ->if Unix.close_process_in input <> Unix.WEXITED 0 thenfailwith "tmux version discovery failed")(fun () -> String.trim (input_line input))inif not (String.starts_with ~prefix:"tmux " version) thenfailwith "invalid tmux version";String.sub version 5 (String.length version - 5)let () =let binary = if Array.length Sys.argv = 2 then Sys.argv.(1) else "tmux" inlet directory = Filename.temp_dir "libtmux-ocaml-showcase-" "" inprotect~finally:(fun () ->Sys.readdir directory|> Array.iter (fun name -> Sys.remove (Filename.concat directory name));Unix.rmdir directory)(fun () ->let socket = Filename.concat directory "server" inlet config_file = Filename.concat directory "tmux.conf" inOut_channel.with_open_text config_file (fun output ->output_string output "set-option -s exit-unattached on\n");let wrapper = Filename.concat directory "tmux" inOut_channel.with_open_text wrapper (fun output ->Printf.fprintf output "#!/bin/sh\nexec %s -f %s \"$@\"\n"(Filename.quote binary)(Filename.quote config_file));Unix.chmod wrapper 0o700;let execution =bootstrap ~binary:wrapper ~version:(local_version binary) ~directory(Endpoint.socket_path socket)in(* docs:begin await-bootstrap *)let snapshot =protect~finally:(fun () -> get (Workspace.close execution))(fun () ->let receipt = get (Workspace.await execution) inrequire_success receipt;let client = Option.get (Workspace.client execution) inget (Client.capture client))(* docs:end await-bootstrap *)inassert (Iarray.length (Snapshot.sessions snapshot) = 1);assert (Iarray.length (Snapshot.windows snapshot) = 1);assert (Iarray.length (Snapshot.panes snapshot) = 1);assert (Session.name (Iarray.get (Snapshot.sessions snapshot) 0)= "bootstrap-demo");assert (Window.name (Iarray.get (Snapshot.windows snapshot) 0) = "editor");Printf.printf "socket=%s\n" socket;print_endline "bootstrapped: 1 session, 1 window, 1 pane")Run the recorded entry point:
Terminal window $ opam exec -- dune exec examples/showcase_bootstrap.exe -- tmuxExpected outcome line, after the temporary socket path:
bootstrapped: 1 session, 1 window, 1 pane- Parameters
-
-
compensate_on_failure? (bool) #
In other ports#
Build a session from a workspace description
| Language | Equivalent |
|---|---|
| Python | tmuxp |
| Ruby | Lib |
| PowerShell | Lib Applies the exact reviewed -Plan after PowerShell confirmation. -WhatIf previews without applying it; application is detached. |
| Julia | Lib Applies a prepared WorkspacePlan on an explicit Server, detached and under one deadline. Existing session names fail unless reuse is explicit. |
| Haskell | No public Haskell equivalent is implemented; the current modules expose scalar values and version parsing. |
| Common Lisp | libtmux |
| TypeScript | builder |
| Rust | src |
| Go | workspace |
| Java | io |
| C# | Lib |
| C++ | libtmux:: |
| Swift | Workspace |
| Perl | Lib Loads through installed public core APIs; existing-target policy and known owned rollback effects are explicit. |
No equivalent is recorded in Lua, Erlang, Elixir, Clojure, Kotlin, Scala or F#.