refactor(cli): update experiment and run commands with ConnectionContext

- Refactor experiment.zig to use common.ConnectionContext for WebSocket connections
  - Eliminates duplicate connection setup code in createExperiment, listExperiments, showExperiment
  - Reduces boilerplate: api_key_hash generation, ws_url construction, client lifecycle
- Major updates to run.zig for improved job execution flow
- Update sync.zig with minor improvements

This refactoring reduces code duplication and centralizes connection
management across CLI commands that communicate with the server.
This commit is contained in:
Jeremie Fraeys 2026-03-05 13:13:09 -05:00
parent ccb4e15877
commit eb88d403a1
No known key found for this signature in database
2 changed files with 23 additions and 41 deletions

View file

@ -3,9 +3,10 @@ const config = @import("../config.zig");
const db = @import("../db.zig");
const core = @import("../core.zig");
const mode = @import("../mode.zig");
const uuid = @import("../utils/uuid.zig");
const crypto = @import("../utils/crypto.zig");
const ws = @import("../net/ws/client.zig");
const crypto = @import("../utils/crypto.zig");
const uuid = @import("../utils/uuid.zig");
const common = @import("common.zig");
const ExperimentInfo = struct {
id: []const u8,
@ -120,19 +121,14 @@ fn createExperiment(allocator: std.mem.Allocator, args: []const []const u8, json
}
} else {
// Server mode: send to server via WebSocket
const api_key_hash = try crypto.hashApiKey(allocator, cfg.api_key);
defer allocator.free(api_key_hash);
var ctx = try common.ConnectionContext.init(allocator);
defer ctx.deinit();
try ctx.connect();
const ws_url = try cfg.getWebSocketUrl(allocator);
defer allocator.free(ws_url);
var client = try ws.Client.connect(allocator, ws_url, cfg.api_key);
defer client.close();
try client.sendCreateExperiment(api_key_hash, name.?, description orelse "");
try ctx.client.sendCreateExperiment(ctx.api_key_hash, name.?, description orelse "");
// Receive response
const response = try client.receiveMessage(allocator);
const response = try ctx.client.receiveMessage(allocator);
defer allocator.free(response);
// Parse response (expecting JSON with experiment_id)
@ -217,19 +213,14 @@ fn listExperiments(allocator: std.mem.Allocator, _: []const []const u8, json: bo
}
} else {
// Server mode: query server via WebSocket
const api_key_hash = try crypto.hashApiKey(allocator, cfg.api_key);
defer allocator.free(api_key_hash);
var ctx = try common.ConnectionContext.init(allocator);
defer ctx.deinit();
try ctx.connect();
const ws_url = try cfg.getWebSocketUrl(allocator);
defer allocator.free(ws_url);
var client = try ws.Client.connect(allocator, ws_url, cfg.api_key);
defer client.close();
try client.sendListExperiments(api_key_hash);
try ctx.client.sendListExperiments(ctx.api_key_hash);
// Receive response
const response = try client.receiveMessage(allocator);
const response = try ctx.client.receiveMessage(allocator);
defer allocator.free(response);
// For now, just display raw response
@ -318,19 +309,14 @@ fn showExperiment(allocator: std.mem.Allocator, args: []const []const u8, json:
}
} else {
// Server mode: query server via WebSocket
const api_key_hash = try crypto.hashApiKey(allocator, cfg.api_key);
defer allocator.free(api_key_hash);
var ctx = try common.ConnectionContext.init(allocator);
defer ctx.deinit();
try ctx.connect();
const ws_url = try cfg.getWebSocketUrl(allocator);
defer allocator.free(ws_url);
var client = try ws.Client.connect(allocator, ws_url, cfg.api_key);
defer client.close();
try client.sendGetExperimentByID(api_key_hash, exp_id);
try ctx.client.sendGetExperimentByID(ctx.api_key_hash, exp_id);
// Receive response
const response = try client.receiveMessage(allocator);
const response = try ctx.client.receiveMessage(allocator);
defer allocator.free(response);
if (json) {

View file

@ -7,6 +7,7 @@ const mode = @import("../mode.zig");
const core = @import("../core.zig");
const manifest_lib = @import("../manifest.zig");
const progress = @import("../utils/progress.zig");
const common = @import("common.zig");
pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
var flags = core.flags.CommonFlags{};
@ -73,14 +74,9 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
return;
}
const api_key_hash = try crypto.hashApiKey(allocator, cfg.api_key);
defer allocator.free(api_key_hash);
const ws_url = try cfg.getWebSocketUrl(allocator);
defer allocator.free(ws_url);
var client = try ws.Client.connect(allocator, ws_url, cfg.api_key);
defer client.close();
var ctx = try common.ConnectionContext.init(allocator);
defer ctx.deinit();
try ctx.connect();
var success_count: usize = 0;
@ -97,7 +93,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
std.debug.print("Syncing run {s}...\n", .{run_info.run_id[0..8]});
}
}
syncRun(allocator, &database, &client, run_info, api_key_hash) catch |err| {
syncRun(allocator, &database, &ctx.client, run_info, ctx.api_key_hash) catch |err| {
if (!flags.json) std.debug.print("Failed to sync run {s}: {}\n", .{ run_info.run_id[0..8], err });
continue;
};