diff --git a/cmd/lk/simulate.go b/cmd/lk/simulate.go index 75299c73..f9186e93 100644 --- a/cmd/lk/simulate.go +++ b/cmd/lk/simulate.go @@ -73,6 +73,10 @@ var simulateCommand = &cli.Command{ Aliases: []string{"n"}, Usage: "Number of scenarios to generate", }, + &cli.IntFlag{ + Name: "concurrency", + Usage: "Max simulations running in parallel (default: server-side limit)", + }, &cli.StringFlag{ Name: "scenarios", Usage: "Path to a scenarios `FILE` (yaml). If omitted, scenarios are generated from the agent's source", @@ -158,6 +162,7 @@ type simulateConfig struct { client *lksdk.AgentSimulationClient pc *config.ProjectConfig numSimulations int32 + concurrency int32 mode simulateMode agentName string projectDir string @@ -221,6 +226,7 @@ func runSimulate(ctx context.Context, cmd *cli.Command) error { pc := simulateProjectConfig numSimulations := int32(cmd.Int("num-simulations")) + concurrency := int32(cmd.Int("concurrency")) agentName := generateAgentName() projectDir, projectType, err := agentfs.DetectProjectRoot(".") @@ -271,6 +277,7 @@ func runSimulate(ctx context.Context, cmd *cli.Command) error { client: simClient, pc: pc, numSimulations: numSimulations, + concurrency: concurrency, mode: mode, agentName: agentName, projectDir: projectDir, @@ -341,6 +348,8 @@ func startSimulationAgent(c *simulateConfig, forwardOutput io.Writer) (*AgentPro "--api-secret", c.pc.APISecret, "--log-level", "DEBUG", "--log-format", "colored", + // disable the worker load limit so the run can saturate the agent + "--simulation", }, Env: []string{ // force the agent to register under the dispatch name regardless of any @@ -361,6 +370,9 @@ func createSimulationRun(ctx context.Context, c *simulateConfig) (string, *livek AgentName: c.agentName, NumSimulations: c.numSimulations, } + if c.concurrency > 0 { + req.Concurrency = &c.concurrency + } if c.mode == modeScenarios { // Run the scenarios from the yaml. When unset, the server generates // num_simulations scenarios from the uploaded source. diff --git a/cmd/lk/simulate_ci.go b/cmd/lk/simulate_ci.go index 1188abb5..5e46217f 100644 --- a/cmd/lk/simulate_ci.go +++ b/cmd/lk/simulate_ci.go @@ -320,8 +320,12 @@ func printCIResults(run *livekit.SimulationRun, agent *AgentProcess) { if run.Summary != nil { printCISummary(run) } else { + msg := "The summary for this run is not available" + if run.Error != "" { + msg = run.Error + } fmt.Fprintln(os.Stdout) - fmt.Fprintln(os.Stdout, "⚠ The summary for this run is not available") + fmt.Fprintln(os.Stdout, "⚠ "+msg) } } diff --git a/cmd/lk/simulate_tui.go b/cmd/lk/simulate_tui.go index afb0065c..0376235f 100644 --- a/cmd/lk/simulate_tui.go +++ b/cmd/lk/simulate_tui.go @@ -1002,7 +1002,11 @@ func (m *simulateModel) viewRunning() string { } else if m.run.Summary != nil { b.WriteString(m.renderSummary()) } else if isTerminalRunStatus(m.run.Status) { - b.WriteString(fmt.Sprintf("\n %s %s\n", yellowStyle.Render("⚠"), yellowStyle.Render("The summary for this run is not available"))) + msg := "The summary for this run is not available" + if m.run.Error != "" { + msg = m.run.Error + } + b.WriteString(fmt.Sprintf("\n %s %s\n", yellowStyle.Render("⚠"), yellowStyle.Render(msg))) } } diff --git a/go.mod b/go.mod index 8e8856d2..55d6bd0c 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/google/go-containerregistry v0.20.7 github.com/google/go-querystring v1.2.0 github.com/joho/godotenv v1.5.1 - github.com/livekit/protocol v1.46.7-0.20260608020211-e9abadf97706 + github.com/livekit/protocol v1.46.7-0.20260610175657-3ccff51ebf5b github.com/livekit/server-sdk-go/v2 v2.16.7-0.20260608025623-a5da15b13baa github.com/mattn/go-isatty v0.0.22 github.com/moby/patternmatcher v0.6.1 diff --git a/go.sum b/go.sum index a1004c06..e2675e62 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5AT github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20260605212259-862d4a7bcb1e h1:SkgQRcG2VYEhh80Qb/zYZo8rWKJzNfJcfUQnXe6su2M= github.com/livekit/mediatransportutil v0.0.0-20260605212259-862d4a7bcb1e/go.mod h1:o8CFmAdrVwzJNOCsQCLUzXRjokkufNshnQHOe4fRaqU= -github.com/livekit/protocol v1.46.7-0.20260608020211-e9abadf97706 h1:MVujVVdveJa++lNgb3ekY2+T2P8JV4RlvFqNCJyC+SM= -github.com/livekit/protocol v1.46.7-0.20260608020211-e9abadf97706/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= +github.com/livekit/protocol v1.46.7-0.20260610175657-3ccff51ebf5b h1:F3dXIOp+D5rpXn1VwQWUm5tTV0W9Jbcf0yUrnY56sWs= +github.com/livekit/protocol v1.46.7-0.20260610175657-3ccff51ebf5b/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= github.com/livekit/psrpc v0.7.2 h1:6oZ+NODJ2pLyaT6VqDq1F4Qc/3TpDUSpyphj/P9MhQc= github.com/livekit/psrpc v0.7.2/go.mod h1:rAI+m2+/cb4x9RXhLRtUx5ZwdfjjXOl4zi46IjEetaw= github.com/livekit/server-sdk-go/v2 v2.16.7-0.20260608025623-a5da15b13baa h1:B19yilP7+JjekKMD0WejMh1Kvypdxpr5yxQZiFStRD0=