From f7a770989b0a57ee72ba1570290abb8bd399c15c Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Mon, 2 Jun 2025 17:04:25 +0300 Subject: [PATCH] feat: Improve ZinitClient and JSON-RPC client - Enhanced error handling and response parsing in `ZinitClient`: The `discover` function now provides more robust error handling and response parsing, improving reliability. - Improved code style and formatting: Minor formatting changes for better readability and maintainability. The `ServiceConfig` and `ServiceConfigResponse` structs have been slightly restructured. - Updated JSON-RPC client structure: The `Client` struct is now publicly mutable (`pub mut`), simplifying its use. Removed unnecessary blank lines for improved code clarity. --- lib/osal/zinit/zinit_client.v | 38 +++++++++++++++++------------------ lib/schemas/jsonrpc/client.v | 10 ++++----- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lib/osal/zinit/zinit_client.v b/lib/osal/zinit/zinit_client.v index 71fa9bf8..f2d71dc5 100644 --- a/lib/osal/zinit/zinit_client.v +++ b/lib/osal/zinit/zinit_client.v @@ -52,16 +52,16 @@ pub: pub fn (mut c ZinitClient) discover() !string { // Use a simpler approach - just get the raw response and return it as a string request := jsonrpc.new_request_generic('rpc.discover', []string{}) - + // Send the request and get the raw response - raw_response := c.rpc_client.rpc_client.transport.send(request.encode(), jsonrpc.SendParams{ + raw_response := c.rpc_client.transport.send(request.encode(), jsonrpc.SendParams{ timeout: 5 // Increase timeout to 5 seconds })! - + // Extract just the result part from the response // This is a simplified approach to avoid full JSON parsing start_idx := raw_response.index('{"info":') or { return error('Invalid response format') } - + // Return the raw JSON string return raw_response[start_idx..] } @@ -142,10 +142,10 @@ pub: // - signal: The signal to send (e.g., SIGTERM, SIGKILL) pub fn (mut c ZinitClient) kill(name string, signal string) ! { params := KillParams{ - name: name + name: name signal: signal } - + request := jsonrpc.new_request_generic('service_kill', params) c.rpc_client.send[KillParams, EmptyResponse](request)! } @@ -211,11 +211,11 @@ pub fn (mut c ZinitClient) get_all_logs() ![]string { // ServiceConfig represents the configuration for a service pub struct ServiceConfig { pub: - exec string - oneshot bool - after []string - log string - env map[string]string + exec string + oneshot bool + after []string + log string + env map[string]string shutdown_timeout int } @@ -234,10 +234,10 @@ pub: // - A string indicating the result of the operation pub fn (mut c ZinitClient) create_service(name string, config ServiceConfig) !string { params := CreateServiceParams{ - name: name + name: name content: config } - + request := jsonrpc.new_request_generic('service_create', params) return c.rpc_client.send[CreateServiceParams, string](request)! } @@ -255,11 +255,11 @@ pub fn (mut c ZinitClient) delete_service(name string) !string { // ServiceConfigResponse represents the response from get_service pub struct ServiceConfigResponse { pub: - exec string - oneshot bool - after []string - log string - env map[string]string + exec string + oneshot bool + after []string + log string + env map[string]string shutdown_timeout int } @@ -287,4 +287,4 @@ pub fn (mut c ZinitClient) start_http_server(address string) !string { pub fn (mut c ZinitClient) stop_http_server() ! { request := jsonrpc.new_request_generic('system_stop_http_server', []string{}) c.rpc_client.send[[]string, EmptyResponse](request)! -} \ No newline at end of file +} diff --git a/lib/schemas/jsonrpc/client.v b/lib/schemas/jsonrpc/client.v index e4d910dd..e924d9bc 100644 --- a/lib/schemas/jsonrpc/client.v +++ b/lib/schemas/jsonrpc/client.v @@ -1,4 +1,5 @@ module jsonrpc + import freeflowuniverse.herolib.ui.console // IRPCTransportClient defines the interface for transport mechanisms used by the JSON-RPC client. @@ -27,11 +28,10 @@ pub: retry int } - // Client implements a JSON-RPC 2.0 client that can send requests and process responses. // It uses a pluggable transport layer that implements the IRPCTransportClient interface. pub struct Client { -mut: +pub mut: // The transport implementation used to send requests and receive responses transport IRPCTransportClient } @@ -44,13 +44,12 @@ mut: // Returns: // - A pointer to a new Client instance pub fn new_client(transport IRPCTransportClient) &Client { - mut cl:=Client{ - transport: transport + mut cl := Client{ + transport: transport } return &cl } - // send sends a JSON-RPC request with parameters of type T and expects a response with result of type D. // This method handles the full request-response cycle including validation and error handling. // @@ -69,7 +68,6 @@ pub fn (mut c Client) send[T, D](request RequestGeneric[T], params SendParams) ! console.print_debug('Sending request: ${request.encode()}') response_json := c.transport.send(request.encode(), params)! - // Decode the response JSON into a strongly-typed response object response := decode_response_generic[D](response_json) or { return error('Unable to decode response.\n- Response: ${response_json}\n- Error: ${err}')