Initial import of LogDarioSeq baseline
Establishes version control for the personal Logseq DB fork before starting the server-client architecture migration and domain features described in docs/agent-guide and the approved implementation plan. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
234
cli/lib/server_command.ml
Normal file
234
cli/lib/server_command.ml
Normal file
@@ -0,0 +1,234 @@
|
||||
type parsed =
|
||||
| Parsed_list
|
||||
| Parsed_cleanup
|
||||
| Parsed_start
|
||||
| Parsed_stop
|
||||
| Parsed_restart
|
||||
|
||||
type action =
|
||||
| Server_list
|
||||
| Server_cleanup
|
||||
| Server_start of { repo : Cli_primitive.repo; graph : Cli_primitive.graph }
|
||||
| Server_stop of { repo : Cli_primitive.repo; graph : Cli_primitive.graph }
|
||||
| Server_restart of { repo : Cli_primitive.repo; graph : Cli_primitive.graph }
|
||||
|
||||
let command_id = function
|
||||
| Parsed_list -> Command_id.Server_list
|
||||
| Parsed_cleanup -> Server_cleanup
|
||||
| Parsed_start -> Server_start
|
||||
| Parsed_stop -> Server_stop
|
||||
| Parsed_restart -> Server_restart
|
||||
|
||||
let validate_parsed _ = Ok ()
|
||||
|
||||
let action_with_repo config make message =
|
||||
match config.Cli_config.repo with
|
||||
| Some repo -> Ok (make repo (Cli_config.repo_to_graph repo))
|
||||
| None -> Error (Error.missing_repo message)
|
||||
|
||||
let build ?registry:_ config _globals = function
|
||||
| Parsed_list -> Ok Server_list
|
||||
| Parsed_cleanup -> Ok Server_cleanup
|
||||
| Parsed_start ->
|
||||
action_with_repo config
|
||||
(fun repo graph -> Server_start { repo; graph })
|
||||
"repo is required for server start"
|
||||
| Parsed_stop ->
|
||||
action_with_repo config
|
||||
(fun repo graph -> Server_stop { repo; graph })
|
||||
"repo is required for server stop"
|
||||
| Parsed_restart ->
|
||||
action_with_repo config
|
||||
(fun repo graph -> Server_restart { repo; graph })
|
||||
"repo is required for server restart"
|
||||
|
||||
let status_value = function
|
||||
| Server_runtime.Starting -> Edn_util.string "starting"
|
||||
| Ready -> Edn_util.string "ready"
|
||||
| Error -> Edn_util.string "error"
|
||||
| Unknown -> Edn_util.string "unknown"
|
||||
|
||||
let owner_source_value source =
|
||||
Edn_util.string (Cli_primitive.string_of_owner_source source)
|
||||
|
||||
let optional_string key = function
|
||||
| Some value -> Vec.singleton (Edn_util.keyword key, Edn_util.string value)
|
||||
| None -> Vec.empty
|
||||
|
||||
let server_value (server : Server_runtime.server) =
|
||||
Edn_util.map_vec
|
||||
( Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "repo",
|
||||
Edn_util.string (Cli_primitive.string_of_repo server.repo) );
|
||||
( Edn_util.keyword "graph",
|
||||
match server.graph with
|
||||
| Some graph ->
|
||||
Edn_util.string (Cli_primitive.string_of_graph graph)
|
||||
| None -> Edn_util.nil );
|
||||
(Edn_util.keyword "pid", Edn_util.int server.pid);
|
||||
(Edn_util.keyword "host", Edn_util.string server.host);
|
||||
(Edn_util.keyword "port", Edn_util.int server.port);
|
||||
(Edn_util.keyword "base-url", Edn_util.string server.base_url);
|
||||
(Edn_util.keyword "status", status_value server.status);
|
||||
( Edn_util.keyword "owner-source",
|
||||
owner_source_value server.owner_source );
|
||||
(Edn_util.keyword "owned", Edn_util.bool server.owned);
|
||||
|]
|
||||
|> fun fields ->
|
||||
Vec.append fields (optional_string "revision" server.revision)
|
||||
|> fun fields ->
|
||||
Vec.append fields (optional_string "root-dir" server.root_dir) )
|
||||
|
||||
let start_result_value (result : Server_runtime.start_result) =
|
||||
Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "repo",
|
||||
Edn_util.string (Cli_primitive.string_of_repo result.repo) );
|
||||
( Edn_util.keyword "owner-source",
|
||||
owner_source_value result.owner_source );
|
||||
(Edn_util.keyword "owned", Edn_util.bool result.owned);
|
||||
|])
|
||||
|
||||
let stop_result_value (result : Server_runtime.stop_result) =
|
||||
Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "repo",
|
||||
Edn_util.string (Cli_primitive.string_of_repo result.repo) );
|
||||
|])
|
||||
|
||||
let error_value (err : Error.t) =
|
||||
Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "code",
|
||||
Edn_util.string (Error.code_to_string err.code) );
|
||||
(Edn_util.keyword "message", Edn_util.string err.message);
|
||||
|])
|
||||
|
||||
let failed_cleanup_value (server, err) =
|
||||
match Edn_util.as_map (server_value server) with
|
||||
| Some fields ->
|
||||
Edn_util.map_vec
|
||||
(Vec.push_back fields (Edn_util.keyword "error", error_value err))
|
||||
| None ->
|
||||
Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
(Edn_util.keyword "server", server_value server);
|
||||
(Edn_util.keyword "error", error_value err);
|
||||
|])
|
||||
|
||||
let execute_with_mode action config mode =
|
||||
let open Cli_effect in
|
||||
match action with
|
||||
| Server_list ->
|
||||
bind (Server_runtime.list_servers config) (fun servers ->
|
||||
pure
|
||||
(Cli_result.ok ~command:Command_id.Server_list mode
|
||||
(Raw
|
||||
(Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "servers",
|
||||
Edn_util.vector_vec (servers |> Vec.map server_value)
|
||||
);
|
||||
|])))))
|
||||
| Server_cleanup ->
|
||||
bind
|
||||
(Server_runtime.cleanup_revision_mismatched_servers config
|
||||
~cli_revision:"unknown") (function
|
||||
| Ok result ->
|
||||
pure
|
||||
(Cli_result.ok ~command:Command_id.Server_cleanup mode
|
||||
(Raw
|
||||
(Edn_util.map_vec
|
||||
(Vec.of_array
|
||||
[|
|
||||
( Edn_util.keyword "cli-revision",
|
||||
Edn_util.string result.cli_revision );
|
||||
( Edn_util.keyword "checked",
|
||||
Edn_util.int result.checked );
|
||||
( Edn_util.keyword "mismatched",
|
||||
Edn_util.int result.mismatched );
|
||||
( Edn_util.keyword "eligible",
|
||||
Edn_util.int result.eligible );
|
||||
( Edn_util.keyword "skipped-owner",
|
||||
Edn_util.int result.skipped_owner );
|
||||
( Edn_util.keyword "killed",
|
||||
Edn_util.vector_vec
|
||||
(result.killed |> Vec.map server_value) );
|
||||
( Edn_util.keyword "failed",
|
||||
Edn_util.vector_vec
|
||||
(result.failed |> Vec.map failed_cleanup_value)
|
||||
);
|
||||
|]))))
|
||||
| Error err ->
|
||||
pure (Output_mode.error ~command:Command_id.Server_cleanup mode err))
|
||||
| Server_start { repo; _ } ->
|
||||
bind (Server_runtime.start_server config repo ~create_empty_db:false)
|
||||
(function
|
||||
| Ok result ->
|
||||
pure
|
||||
(Cli_result.ok ~command:Command_id.Server_start mode
|
||||
(Raw (start_result_value result)))
|
||||
| Error err ->
|
||||
pure (Output_mode.error ~command:Command_id.Server_start mode err))
|
||||
| Server_stop { repo; _ } ->
|
||||
bind (Server_runtime.stop_server config repo) (function
|
||||
| Ok result ->
|
||||
pure
|
||||
(Cli_result.ok ~command:Command_id.Server_stop mode
|
||||
(Raw (stop_result_value result)))
|
||||
| Error err ->
|
||||
pure (Output_mode.error ~command:Command_id.Server_stop mode err))
|
||||
| Server_restart { repo; _ } ->
|
||||
bind (Server_runtime.restart_server config repo) (function
|
||||
| Ok result ->
|
||||
pure
|
||||
(Cli_result.ok ~command:Command_id.Server_restart mode
|
||||
(Raw (start_result_value result)))
|
||||
| Error err ->
|
||||
pure (Output_mode.error ~command:Command_id.Server_restart mode err))
|
||||
|
||||
let meta ?(examples = Vec.empty) id doc =
|
||||
{
|
||||
Command_registry.id;
|
||||
path = Command_id.to_path id;
|
||||
doc;
|
||||
long_doc = None;
|
||||
examples;
|
||||
options = Vec.empty;
|
||||
category = Command_registry.Graph_management;
|
||||
requires_graph = Command_id.requires_graph id;
|
||||
requires_auth = Command_id.requires_auth id;
|
||||
write_command = Command_id.is_write id;
|
||||
human_table_headers_order = Vec.empty;
|
||||
}
|
||||
|
||||
let metadata () =
|
||||
Vec.of_array
|
||||
[|
|
||||
meta
|
||||
~examples:(Vec.singleton "logseq server list")
|
||||
Command_id.Server_list "List db-worker-node servers";
|
||||
meta
|
||||
~examples:(Vec.singleton "logseq server cleanup")
|
||||
Server_cleanup
|
||||
"Clean up revision-mismatched CLI-owned db-worker-node servers";
|
||||
meta
|
||||
~examples:(Vec.singleton "logseq server start --graph my-graph")
|
||||
Server_start "Start db-worker-node for a graph";
|
||||
meta
|
||||
~examples:(Vec.singleton "logseq server stop --graph my-graph")
|
||||
Server_stop "Stop db-worker-node for a graph";
|
||||
meta
|
||||
~examples:(Vec.singleton "logseq server restart --graph my-graph")
|
||||
Server_restart "Restart db-worker-node for a graph";
|
||||
|]
|
||||
|
||||
let execute action config =
|
||||
let (Output.Mode.Packed mode) = Output_mode.for_config config in
|
||||
execute_with_mode action config mode
|
||||
Reference in New Issue
Block a user