mirror of
https://github.com/open-gitagent/langship.sh.git
synced 2026-08-03 07:21:04 +02:00
feat: Update AppSidebar to include new Environments and Credentials sections feat: Enhance node form with branch selection for triggers and deployment feat: Create CredentialForm and CredentialRow components for managing credentials feat: Add API endpoints for credential management fix: Update node catalog defaults for deploy and promote nodes
120 lines
4.1 KiB
Go
120 lines
4.1 KiB
Go
package executors
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/lyzrai/flow/pkg/engine"
|
|
"github.com/lyzrai/flow/pkg/models"
|
|
)
|
|
|
|
// stubExecutor implements a no-op executor that:
|
|
// - logs the node's parameters under a distinct slog message
|
|
// - sleeps `sleep` to simulate work (interruptible by ctx cancel)
|
|
// - decorates each input item with `{stub: <stage>, status: success}` so
|
|
// downstream nodes have something to read.
|
|
//
|
|
// This is a deliberate placeholder for nodes whose real backing is still
|
|
// pending (Test, Eval, Policy, Deploy, Promote, Rollback). Swap individual
|
|
// stubs for real executors as they're built; the runtime contract stays
|
|
// the same.
|
|
type stubExecutor struct {
|
|
stage string // "test" | "eval" | "policy" | ...
|
|
logName string // slog message name
|
|
sleep time.Duration // simulated work
|
|
}
|
|
|
|
func (e *stubExecutor) Execute(ctx context.Context, node models.NodeDef, inputs [][]models.Item, _ *engine.ExecutionContext) (map[int][]models.Item, error) {
|
|
slog.InfoContext(ctx, e.logName,
|
|
slog.String("node", node.Name),
|
|
slog.Any("parameters", node.Parameters),
|
|
)
|
|
|
|
logger := engine.NodeLoggerFromContext(ctx)
|
|
logger.Log("[stub:" + e.stage + "] starting " + node.Name)
|
|
if len(node.Parameters) > 0 {
|
|
for k, v := range node.Parameters {
|
|
logger.Log(" param " + k + " = " + sprintAny(v))
|
|
}
|
|
}
|
|
|
|
if e.sleep > 0 {
|
|
t := time.NewTimer(e.sleep)
|
|
defer t.Stop()
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil, ctx.Err()
|
|
case <-t.C:
|
|
}
|
|
}
|
|
|
|
var inputItems []models.Item
|
|
for _, in := range inputs {
|
|
inputItems = append(inputItems, in...)
|
|
}
|
|
if len(inputItems) == 0 {
|
|
// Trigger nodes typically pass {} as the single seed item; preserve
|
|
// that shape so a stub at the head of the pipeline still produces
|
|
// something downstream can consume.
|
|
inputItems = []models.Item{{}}
|
|
}
|
|
|
|
out := make([]models.Item, 0, len(inputItems))
|
|
for _, item := range inputItems {
|
|
ci := copyItem(item)
|
|
ci["__stub"] = e.stage
|
|
ci["__status"] = "success"
|
|
ci["__node"] = node.Name
|
|
out = append(out, ci)
|
|
}
|
|
logger.Log("[stub:" + e.stage + "] finished " + node.Name + " (" + strconvItoa(len(out)) + " items)")
|
|
return map[int][]models.Item{0: out}, nil
|
|
}
|
|
|
|
// strconvItoa wraps strconv.Itoa so we don't pull strconv into stubs.go just for one call.
|
|
func strconvItoa(n int) string { return fmt.Sprintf("%d", n) }
|
|
|
|
// sprintAny formats a parameter value for log lines, capping length so a
|
|
// huge JSON blob doesn't blow up the log channel.
|
|
func sprintAny(v any) string {
|
|
s := fmt.Sprintf("%v", v)
|
|
if len(s) > 200 {
|
|
return s[:200] + "…"
|
|
}
|
|
return s
|
|
}
|
|
|
|
// TestExecutor stubs the Test stage.
|
|
type TestExecutor struct{}
|
|
|
|
func (e *TestExecutor) Execute(ctx context.Context, node models.NodeDef, inputs [][]models.Item, ec *engine.ExecutionContext) (map[int][]models.Item, error) {
|
|
return (&stubExecutor{stage: "test", logName: "stub_test", sleep: 500 * time.Millisecond}).Execute(ctx, node, inputs, ec)
|
|
}
|
|
|
|
// EvalExecutor stubs the Eval stage.
|
|
type EvalExecutor struct{}
|
|
|
|
func (e *EvalExecutor) Execute(ctx context.Context, node models.NodeDef, inputs [][]models.Item, ec *engine.ExecutionContext) (map[int][]models.Item, error) {
|
|
return (&stubExecutor{stage: "eval", logName: "stub_eval", sleep: 750 * time.Millisecond}).Execute(ctx, node, inputs, ec)
|
|
}
|
|
|
|
// PolicyExecutor stubs the Policy stage.
|
|
type PolicyExecutor struct{}
|
|
|
|
func (e *PolicyExecutor) Execute(ctx context.Context, node models.NodeDef, inputs [][]models.Item, ec *engine.ExecutionContext) (map[int][]models.Item, error) {
|
|
return (&stubExecutor{stage: "policy", logName: "stub_policy", sleep: 200 * time.Millisecond}).Execute(ctx, node, inputs, ec)
|
|
}
|
|
|
|
// DeployExecutor lives in deploy.go (real impl) — was previously a stub.
|
|
|
|
// PromoteExecutor lives in promote.go (real impl) — was previously a stub.
|
|
|
|
// RollbackExecutor stubs the Rollback stage.
|
|
type RollbackExecutor struct{}
|
|
|
|
func (e *RollbackExecutor) Execute(ctx context.Context, node models.NodeDef, inputs [][]models.Item, ec *engine.ExecutionContext) (map[int][]models.Item, error) {
|
|
return (&stubExecutor{stage: "rollback", logName: "stub_rollback", sleep: 500 * time.Millisecond}).Execute(ctx, node, inputs, ec)
|
|
}
|