### Run gorkflow Examples in Go Source: https://github.com/sicko7947/gorkflow/blob/main/example/README.md Demonstrates how to import and run gorkflow examples within a Go program. It shows the creation of an engine, starting the simple math workflow, and starting the conditional workflow with their respective inputs. ```go import ( "context" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "github.com/sicko7947/gorkflow/example/simple_math" "github.com/sicko7947/gorkflow/example/conditional" ) func main() { // Create engine (uses defaults: stdout logger, DefaultEngineConfig) eng := engine.NewEngine(store.NewMemoryStore()) // Run simple math workflow mathWf, _ := simple_math.NewSimpleMathWorkflow() mathInput := simple_math.WorkflowInput{Val1: 10, Val2: 5, Mult: 2} runID1, _ := eng.StartWorkflow(context.Background(), mathWf, mathInput) // Run conditional workflow condWf, _ := conditional.NewConditionalWorkflow() condInput := conditional.ConditionalInput{ Value: 10, EnableDoubling: true, EnableFormatting: true, } runID2, _ := eng.StartWorkflow(context.Background(), condWf, condInput) } ``` -------------------------------- ### Explore gorkflow Example Guide Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md This command navigates to the example directory of the gorkflow project and displays the content of the GUIDE.md file, which provides a step-by-step walkthrough. ```bash cd example/ cat GUIDE.md ``` -------------------------------- ### Starting Conditional Workflows with Gorkflow Engine Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Shows how to initialize the Gorkflow engine and start a workflow with different conditional inputs. This demonstrates how enabling or disabling flags affects the execution of conditional steps like doubling and formatting. ```go import ( "context" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "github.com/sicko7947/gorkflow/example/conditional" ) func main() { // Create engine eng := engine.NewEngine(store.NewMemoryStore()) // Create conditional workflow wf, _ := conditional.NewConditionalWorkflow() // Example 1: Enable both steps input1 := conditional.ConditionalInput{ Value: 10, EnableDoubling: true, EnableFormatting: true, } runID1, _ := eng.StartWorkflow(context.Background(), wf, input1) // Result: Value doubled to 20, formatted output // Example 2: Skip doubling input2 := conditional.ConditionalInput{ Value: 10, EnableDoubling: false, // Step skipped! EnableFormatting: true, } runID2, _ := eng.StartWorkflow(context.Background(), wf, input2) // Result: Default output used, formatted // Example 3: Skip both conditional steps input3 := conditional.ConditionalInput{ Value: 10, EnableDoubling: false, EnableFormatting: false, } runID3, _ := eng.StartWorkflow(context.Background(), wf, input3) // Result: Both steps skipped, default values used } ``` -------------------------------- ### Execute Simple Math Workflow with gorkflow Engine Source: https://github.com/sicko7947/gorkflow/blob/main/example/simple_math/README.md Demonstrates how to create and execute a simple math workflow using the gorkflow engine. It involves initializing the engine, defining the workflow, and starting its execution with input data. The output is the calculated result. ```go import ( "context" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "github.com/sicko7947/gorkflow/example/simple_math" ) func main() { // Create engine with default logger and config eng := engine.NewEngine(store.NewMemoryStore()) // Create workflow wf, _ := simple_math.NewSimpleMathWorkflow() // Execute input := simple_math.WorkflowInput{ Val1: 10, Val2: 5, Mult: 2, } runID, _ := eng.StartWorkflow(context.Background(), wf, input) // Result: (10 + 5) * 2 = 30 } ``` -------------------------------- ### Manage Simple Math Workflow with gorkflow Orchestrator Source: https://github.com/sicko7947/gorkflow/blob/main/example/simple_math/README.md Illustrates using the gorkflow orchestrator for a more structured workflow management. It shows how to initialize the orchestrator, start a workflow, retrieve its status, and optionally cancel it. This approach encapsulates the engine and workflow for a cleaner API. ```go import ( "context" "fmt" "os" "github.com/rs/zerolog" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "github.com/sicko7947/gorkflow/example/simple_math" ) func main() { logger := zerolog.New(os.Stdout).With().Timestamp().Logger() store := store.NewMemoryStore() // Create orchestrator (encapsulates workflow + engine) orch, _ := simple_math.NewOrchestrator( store, logger, engine.DefaultEngineConfig, ) // Start workflow input := simple_math.WorkflowInput{Val1: 10, Val2: 5, Mult: 2} runID, _ := orch.StartWorkflow(context.Background(), input) // Get status status, _ := orch.GetWorkflowStatus(context.Background(), runID) fmt.Printf("Status: %s, Output: %+v\n", status.Status, status.Output) // Cancel if needed _ = orch.CancelWorkflow(context.Background(), runID) } ``` -------------------------------- ### Simple Math Workflow Example Overview Source: https://github.com/sicko7947/gorkflow/blob/main/example/README.md This example demonstrates basic sequential workflow execution in gorkflow. It covers sequential step execution, type-safe data passing, step configuration options like retries and timeouts, and the use of a fluent builder API. The workflow involves adding two numbers, multiplying by a factor, and formatting the result. ```bash cd simple_math cat README.md # Full documentation ``` -------------------------------- ### Bash: Read Example Overview Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to display the contents of the `README.md` file in the `example/` directory. This file provides an overview of the available workflow examples. ```bash cat README.md ``` -------------------------------- ### Starting Conditional Workflows with Gorkflow Orchestrator Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Demonstrates using the Gorkflow orchestrator to start a workflow with conditional flags and retrieve its status and output. This provides a higher-level abstraction for managing workflows. ```go import ( "context" "github.com/rs/zerolog" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "github.com/sicko7947/gorkflow/example/conditional" ) func main() { logger := zerolog.New(os.Stdout).With().Timestamp().Logger() store := store.NewMemoryStore() // Create orchestrator orch, _ := conditional.NewOrchestrator( store, logger, engine.DefaultEngineConfig, ) // Start workflow with conditional flags input := conditional.ConditionalInput{ Value: 10, EnableDoubling: true, EnableFormatting: false, } runID, _ := orch.StartWorkflow(context.Background(), input) // Get status status, _ := orch.GetWorkflowStatus(context.Background(), runID) fmt.Printf("Status: %s, Output: %+v\n", status.Status, status.Output) } ``` -------------------------------- ### Bash: Navigate to Simple Math Example Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to change the current directory into the `simple_math` example workflow directory. ```bash cd simple_math/ ``` -------------------------------- ### Bash: Navigate to Example Directory Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to change the current directory to the root of the example workflows. This is the first step to exploring the provided examples. ```bash cd example/ ``` -------------------------------- ### Install gorkflow Go Package Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md This command shows how to add the gorkflow workflow engine as a dependency to your Go project using the go get command. ```bash go get github.com/sicko7947/gorkflow ``` -------------------------------- ### Conditional Execution Workflow Example Overview Source: https://github.com/sicko7947/gorkflow/blob/main/example/README.md This example showcases runtime conditional step execution using gorkflow's `ThenStepIf` builder API. It illustrates how to evaluate conditions based on workflow state, handle default values when steps are skipped, and implement runtime decision-making. The workflow includes setting up flags, conditionally doubling a value, and conditionally formatting it. ```bash cd conditional cat README.md # Full documentation ``` -------------------------------- ### Start Workflow Execution with Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md Demonstrates initiating a workflow execution using the Go engine. This function takes a context, the workflow definition, and the input data for the workflow. ```Go engine.StartWorkflow(ctx, wf, input) ``` -------------------------------- ### Go: Initialize Workflow Engine with Custom Logger Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Demonstrates initializing the Gorkflow execution engine with a custom logger. This example uses `zerolog` to create a structured logger that outputs to stdout. ```go // Custom logger only logger := zerolog.New(os.Stdout).With().Timestamp().Logger() eng := engine.NewEngine(store, engine.WithLogger(logger)) ``` -------------------------------- ### Bash: Navigate to Conditional Example Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to change the current directory into the `conditional` example workflow directory. ```bash cd ../conditional/ ``` -------------------------------- ### Using ThenStepIf for Conditional Steps Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Shows the Gorkflow builder API usage with `ThenStepIf` to add steps that conditionally execute based on a provided condition function and default values. ```go builder.NewWorkflow("example", "Example"). ThenStep(setupStep). ThenStepIf(doubleStep, shouldDouble, defaultValue). // ← Conditional! ThenStepIf(formatStep, shouldFormat, nil). Build() ``` -------------------------------- ### Implementing Conditional Steps with Step-Level API Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Shows an alternative approach using the step-level API to create conditional steps, specifying a base step, a condition function, and default output. This provides type-safe defaults. ```go baseStep := workflow.NewStep("process", "Process", handler) defaultOutput := &ProcessOutput{Status: "skipped"} conditionalStep := workflow.NewConditionalStep(baseStep, condition, defaultOutput) builder.ThenStep(conditionalStep) ``` -------------------------------- ### DynamoDB Storage Backend for Gorkflow Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Provides instructions and code examples for setting up and using AWS DynamoDB as a persistent storage backend for Gorkflow. This includes initializing the store with a DynamoDB client and table name, and details on using provided shell scripts for table management. ```go import ( "github.com/sicko7947/gorkflow/store" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/dynamodb" ) cfg, _ := config.LoadDefaultConfig(context.Background()) client := dynamodb.NewFromConfig(cfg) store, err := store.NewDynamoDBStore(client, "workflow-table") ``` -------------------------------- ### Configure Production DynamoDB Storage for Gorkflow Workflows Source: https://context7.com/sicko7947/gorkflow/llms.txt This Go code demonstrates how to configure AWS DynamoDB for persistent storage in production Gorkflow deployments. It loads AWS configuration, initializes a DynamoDB client and store, and integrates it with the Gorkflow engine. The example also shows how to start a workflow, log its execution, and query for completed runs. ```go package main import ( "context" "fmt" "os" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/dynamodb" "github.com/rs/zerolog" workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" ) func main() { ctx := context.Background() // Load AWS configuration cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"), ) if err != nil { fmt.Fprintf(os.Stderr, "Unable to load AWS SDK config: %v\n", err) os.Exit(1) } // Create DynamoDB client dynamoClient := dynamodb.NewFromConfig(cfg) // Initialize DynamoDB store with table name dynamoStore, err := store.NewDynamoDBStore(dynamoClient, "workflow_executions") if err != nil { fmt.Fprintf(os.Stderr, "Failed to create DynamoDB store: %v\n", err) os.Exit(1) } // Configure logger logger := zerolog.New(os.Stdout).With().Timestamp().Logger() // Create engine with DynamoDB persistence eng := engine.NewEngine( dynamoStore, engine.WithLogger(logger), ) // Build and execute workflow wf, _ := NewDataWorkflow() input := ProcessInput{Data: []string{"data1", "data2"}} runID, err := eng.StartWorkflow( ctx, wf, input, workflow.WithResourceID("production-job-001"), ) if err != nil { logger.Fatal().Err(err).Msg("Workflow execution failed") } logger.Info().Str("run_id", runID).Msg("Workflow running with DynamoDB persistence") // Query workflow runs with filters runs, err := eng.ListRuns(ctx, workflow.RunFilter{ WorkflowID: "data_processor", Status: func() *workflow.RunStatus { s := workflow.RunStatusCompleted; return &s }(), Limit: 10, }) if err != nil { logger.Error().Err(err).Msg("Failed to list runs") } else { logger.Info().Int("count", len(runs)).Msg("Retrieved completed workflow runs") for _, run := range runs { logger.Info(). Str("run_id", run.RunID). Str("status", string(run.Status)). Time("created_at", run.CreatedAt). Msg("Workflow run") } } } ``` -------------------------------- ### Setting Workflow State for Conditional Logic Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Illustrates how to set runtime state within a workflow context, which is crucial for conditional step execution. These flags determine whether subsequent conditional steps will run. ```go ctx.State.Set("enable_doubling", input.EnableDoubling) ctx.State.Set("enable_formatting", input.EnableFormatting) ``` -------------------------------- ### Execute Workflow and Track Status (Go) Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Executes a defined workflow using the Gorkflow engine. This involves setting up a store, creating an engine instance, starting the workflow with input and tags, and retrieving its status. ```go import ( "context" "github.com/rs/zerolog" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" ) func main() { // Create store store := store.NewMemoryStore() // Create engine with default logger and config eng := engine.NewEngine(store) // Or with custom logger and config // logger := zerolog.New(os.Stdout).With().Timestamp().Logger() // eng := engine.NewEngine(store, // engine.WithLogger(logger), // engine.WithConfig(engine.DefaultEngineConfig), // ) // Create workflow wf, err := NewCalculationWorkflow() if err != nil { logger.Fatal().Err(err).Msg("Failed to create workflow") } // Start workflow ctx := context.Background() runID, err := eng.StartWorkflow( ctx, wf, CalculationInput{A: 10, B: 5}, workflow.WithTags(map[string]string{ "type": "calculation", }), ) if err != nil { logger.Fatal().Err(err).Msg("Failed to start workflow") } logger.Info().Str("run_id", runID).Msg("Workflow started") // Get workflow status run, err := eng.GetRun(ctx, runID) if err != nil { logger.Fatal().Err(err).Msg("Failed to get workflow status") } logger.Info(). Str("status", string(run.Status)). Float64("progress", run.Progress). Msg("Workflow status") } ``` -------------------------------- ### Evaluating Conditions from Workflow State Source: https://github.com/sicko7947/gorkflow/blob/main/example/conditional/README.md Demonstrates a condition function that reads boolean flags from the workflow state to determine execution paths. This function is used by `ThenStepIf` to decide whether to execute a step. ```go shouldDouble := func(ctx *workflow.StepContext) (bool, error) { var enableDoubling bool ctx.State.Get("enable_doubling", &enableDoubling) return enableDoubling, nil } ``` -------------------------------- ### Execute Workflows with Gorkflow Engine in Go Source: https://context7.com/sicko7947/gorkflow/llms.txt Initializes the Gorkflow engine with a memory store and custom logger. It defines a workflow, prepares input data, and starts the workflow execution with options like resource ID, tags, and TTL. The code then polls for the workflow's completion status and retrieves step execution details. ```go package main import ( "context" "fmt" "os" "time" "github.com/rs/zerolog" workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" ) func main() { ctx := context.Background() // Create storage backend (in-memory for development) memStore := store.NewMemoryStore() // Configure custom logger logger := zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout}). With(). Timestamp(). Str("service", "workflow-engine"). Logger(). Level(zerolog.InfoLevel) // Initialize engine with options eng := engine.NewEngine( memStore, engine.WithLogger(logger), engine.WithConfig(engine.EngineConfig{ MaxConcurrentWorkflows: 20, DefaultTimeout: 10 * time.Minute, }), ) // Build workflow wf, err := NewDataWorkflow() if err != nil { logger.Fatal().Err(err).Msg("Failed to build workflow") } // Prepare input data input := ProcessInput{ Data: []string{"item1", "item2", "item3"}, } // Start workflow execution with options runID, err := eng.StartWorkflow( ctx, wf, input, workflow.WithResourceID("user-123"), workflow.WithTags(map[string]string{ "user": "john.doe", "request": "api-call", }), workflow.WithTTL(24*time.Hour), // Auto-cleanup after 24 hours ) if err != nil { logger.Fatal().Err(err).Msg("Failed to start workflow") } logger.Info().Str("run_id", runID).Msg("Workflow started successfully") // Poll for completion for { run, err := eng.GetRun(ctx, runID) if err != nil { logger.Error().Err(err).Msg("Failed to retrieve run status") break } logger.Info(). Str("status", string(run.Status)). Float64("progress", run.Progress). Msg("Workflow status") // Check if workflow reached terminal state if run.Status.IsTerminal() { if run.Status == workflow.RunStatusCompleted { logger.Info().Msg("Workflow completed successfully") } else if run.Status == workflow.RunStatusFailed { logger.Error(). Str("error", run.Error.Message). Msg("Workflow failed") } break } time.Sleep(1 * time.Second) } // Retrieve detailed step execution information steps, err := eng.GetStepExecutions(ctx, runID) if err != nil { logger.Error().Err(err).Msg("Failed to get step executions") } else { for _, step := range steps { logger.Info(). Str("step_id", step.StepID). Str("status", string(step.Status)). Int64("duration_ms", step.DurationMs). Int("attempt", step.Attempt). Msg("Step execution details") } } } ``` -------------------------------- ### State Management in Gorkflow Steps Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Explains how to access and modify workflow state within step handlers. The `StepContext` provides access to state management functions (`Set`, `Get`) and previous step outputs. This is crucial for sharing data and maintaining context across workflow steps. ```go func handler(ctx *workflow.StepContext, input MyInput) (MyOutput, error) { // Get state accessor state := ctx.State // Set state state.Set(ctx.Context, "counter", 42) // Get state counter, err := state.Get(ctx.Context, "counter") // Access previous step output outputs := ctx.Outputs prevOutput, err := outputs.Get(ctx.Context, "previous-step-id") return MyOutput{}, nil } ``` -------------------------------- ### Run Tests and Coverage with Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md These commands demonstrate how to execute all tests, include coverage, and filter for integration tests in the gorkflow project using the Go testing framework. ```bash # All tests go test ./... # With coverage go test -cover ./... # Integration tests only go test -tags=integration ./store/... ``` -------------------------------- ### Create Workflow Engine with Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md Shows how to instantiate the workflow engine in Go. It requires a store implementation, a logger, and a configuration object. ```Go engine.NewEngine(store, logger, config) ``` -------------------------------- ### Go: Initialize Workflow Engine with Defaults Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Shows the basic initialization of the Gorkflow execution engine using default settings. This includes using a default logger (stdout at Info level) and default engine configuration. ```go // Simple: Use defaults (stdout logger at Info level, DefaultEngineConfig) eng := engine.NewEngine(store) ``` -------------------------------- ### Create and Execute a Simple Workflow in Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md This Go code snippet illustrates how to define a simple workflow with a single step, build the workflow, and then execute it using the gorkflow engine with an in-memory store. ```go import ( workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/builder" "github.com/sicko7947/gorkflow/engine" "github.com/sicko7947/gorkflow/store" "context" "os" "github.com/rs/zerolog" ) // Define step step := workflow.NewStep( "hello", "Say Hello", func(ctx *workflow.StepContext, input string) (string, error) { return "Hello, " + input, nil }, ) // Build workflow wf, _ := builder.NewWorkflow("greeting", "Greeting Workflow"). Sequence(step). Build() // Execute store := store.NewMemoryStore() logger := zerolog.New(os.Stdout) eng := engine.NewEngine(store, logger, engine.DefaultEngineConfig) runID, _ := eng.StartWorkflow(context.Background(), wf, "World") ``` -------------------------------- ### Go: Initialize Workflow Engine with Custom Logger and Config Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Shows how to initialize the Gorkflow execution engine with both a custom logger (using `zerolog`) and a custom configuration object, providing full control over logging and engine behavior. ```go // Both custom logger and config eng := engine.NewEngine(store, engine.WithLogger(logger), engine.WithConfig(customConfig), ) ``` -------------------------------- ### Go: Access Previous Step Outputs and Manage State Source: https://context7.com/sicko7947/gorkflow/llms.txt Illustrates how to access outputs from previous steps using `ctx.Outputs.GetOutput()` and `ctx.Outputs.HasOutput()`, and how to retrieve all workflow state with `ctx.State.GetAll()` and delete specific keys with `ctx.State.Delete()` in a Go step handler. ```go package main import ( workflow "github.com/sicko7947/gorkflow" ) type OrderInput struct { OrderID string `json:"orderId"` Amount float64 `json:"amount"` } type PaymentResult struct { TransactionID string `json:"transactionId"` Success bool `json:"success"` } type ShippingResult struct { TrackingNumber string `json:"trackingNumber"` } // Access outputs from previous steps func NewNotificationStep() *workflow.Step[ShippingResult, bool] { return workflow.NewStep( "send_notification", "Send Order Notification", func(ctx *workflow.StepContext, input ShippingResult) (bool, error) { // Access output from a previous step by step ID var paymentResult PaymentResult err := ctx.Outputs.GetOutput("process_payment", &paymentResult) if err != nil { ctx.Logger.Warn().Err(err).Msg("Could not retrieve payment step output") } // Check if a specific step has output if ctx.Outputs.HasOutput("arrange_shipping") { ctx.Logger.Info().Msg("Shipping step completed successfully") } // Retrieve all workflow state allState, err := ctx.State.GetAll() if err != nil { return false, err } ctx.Logger.Info(). Int("state_keys", len(allState)). Str("tracking", input.TrackingNumber). Bool("payment_success", paymentResult.Success). Msg("Notification sent with full context") // Clean up temporary state ctx.State.Delete("temporary_data") return true, nil }, ) } ``` -------------------------------- ### Build Workflow Sequence with Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md Illustrates the process of building a workflow by chaining steps using a builder pattern in Go. This typically involves creating a workflow builder and then sequencing the desired steps. ```Go builder.NewWorkflow().Sequence(step1, step2).Build() ``` -------------------------------- ### Define Workflow Steps with Go Generics Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md Demonstrates how to define workflow steps using Go generics, allowing for type safety in input and output parameters. ```Go func NewStep[TIn, TOut any]() Step[TIn, TOut] { // Implementation details... return nil } ``` -------------------------------- ### Bash: Run Integration Tests for DynamoDB Store Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to execute integration tests specifically for the DynamoDB store implementation. This requires the `-tags=integration` build tag and is typically run against the `store` package. ```bash go test -tags=integration ./store/... ``` -------------------------------- ### Go: Initialize Workflow Engine with Custom Configuration Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Illustrates initializing the Gorkflow execution engine with a custom configuration object. This allows tuning parameters like the maximum number of concurrent workflows and default timeouts. ```go // Custom config only eng := engine.NewEngine(store, engine.WithConfig(engine.EngineConfig{ MaxConcurrentWorkflows: 10, DefaultTimeout: 5 * time.Minute, })) ``` -------------------------------- ### Build Workflow using Fluent API (Go) Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Constructs a workflow using Gorkflow's builder API. This allows defining the workflow's name, description, version, execution configuration, and the sequence of steps. ```go import ( "github.com/sicko7947/gorkflow/builder" ) func NewCalculationWorkflow() (*workflow.Workflow, error) { wf, err := builder.NewWorkflow("calculation", "Calculation Workflow"). WithDescription("A simple calculation workflow"). WithVersion("1.0"). WithConfig(workflow.ExecutionConfig{ MaxRetries: 3, RetryDelayMs: 1000, TimeoutSeconds: 30, }). Sequence( NewAddStep(), NewFormatStep(), ). Build() if err != nil { return nil, err } return wf, nil } ``` -------------------------------- ### Bash: Run All Go Tests Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to execute all unit and integration tests within the Go project. This is a standard command for verifying the project's functionality. ```bash go test ./... ``` -------------------------------- ### Memory Storage Backend for Gorkflow Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Demonstrates the use of an in-memory storage backend for Gorkflow, suitable for testing and development environments. This provides a simple and fast storage solution that does not require external infrastructure. ```go store := store.NewMemoryStore() ``` -------------------------------- ### Create Workflow Steps with Handlers (Go) Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Implements workflow steps using Gorkflow's `NewStep` function. Each step defines its name, description, and a handler function that processes input and returns output. Options for retries and timeouts can be applied. ```go func NewAddStep() *workflow.Step[CalculationInput, SumOutput] { return workflow.NewStep( "add", "Add Two Numbers", func(ctx *workflow.StepContext, input CalculationInput) (SumOutput, error) { sum := input.A + input.B ctx.Logger.Info().Int("sum", sum).Msg("Addition completed") return SumOutput{Sum: sum}, nil }, ) } func NewFormatStep() *workflow.Step[SumOutput, ResultOutput] { return workflow.NewStep( "format", "Format Result", func(ctx *workflow.StepContext, input SumOutput) (ResultOutput, error) { message := fmt.Sprintf("The sum is %d", input.Sum) return ResultOutput{ Result: input.Sum, Message: message, }, nil }, workflow.WithRetries(5), workflow.WithTimeout(5*time.Second), ) } ``` -------------------------------- ### Bash: Run Go Tests with Coverage Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Command to run all Go tests and generate a code coverage report. This helps in identifying parts of the codebase that are not adequately tested. ```bash go test -cover ./... ``` -------------------------------- ### Go: Store and Retrieve Workflow State in Steps Source: https://context7.com/sicko7947/gorkflow/llms.txt Demonstrates how to use a Go step handler to store data (like transaction IDs and metadata) into the workflow state using `ctx.State.Set()` and retrieve it in another step using `ctx.State.Get()` or check its existence with `ctx.State.Has()`. ```go package main import ( workflow "github.com/sicko7947/gorkflow" ) type OrderInput struct { OrderID string `json:"orderId"` Amount float64 `json:"amount"` } type PaymentResult struct { TransactionID string `json:"transactionId"` Success bool `json:"success"` } type ShippingResult struct { TrackingNumber string `json:"trackingNumber"` } // Step that stores data in workflow state func NewPaymentStep() *workflow.Step[OrderInput, PaymentResult] { return workflow.NewStep( "process_payment", "Process Payment", func(ctx *workflow.StepContext, input OrderInput) (PaymentResult, error) { // Perform payment processing transactionID := "txn_12345" // Store transaction details in workflow state err := ctx.State.Set("transaction_id", transactionID) if err != nil { return PaymentResult{}, err } // Store additional metadata metadata := map[string]interface{}{ "payment_method": "credit_card", "processor": "stripe", "timestamp": "2024-01-15T10:30:00Z", } err = ctx.State.Set("payment_metadata", metadata) if err != nil { return PaymentResult{}, err } ctx.Logger.Info(). Str("transaction_id", transactionID). Msg("Payment processed and stored in state") return PaymentResult{ TransactionID: transactionID, Success: true, }, nil }, ) } // Step that reads from workflow state func NewShippingStep() *workflow.Step[PaymentResult, ShippingResult] { return workflow.NewStep( "arrange_shipping", "Arrange Shipping", func(ctx *workflow.StepContext, input PaymentResult) (ShippingResult, error) { // Check if payment was successful using state var transactionID string err := ctx.State.Get("transaction_id", &transactionID) if err != nil { return ShippingResult{}, err } // Retrieve payment metadata var metadata map[string]interface{} err = ctx.State.Get("payment_metadata", &metadata) if err != nil { ctx.Logger.Warn().Msg("Could not retrieve payment metadata") } // Check if state key exists if ctx.State.Has("shipping_address") { var address string ctx.State.Get("shipping_address", &address) } ctx.Logger.Info(). Str("transaction_id", transactionID). Msg("Shipping arranged using stored transaction") return ShippingResult{ TrackingNumber: "TRACK123456", }, nil }, ) } ``` -------------------------------- ### Go: Configure Workflow Execution Parameters Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Demonstrates how to set default execution parameters for all steps within a workflow using the fluent builder API. This includes defining retry counts, delay, backoff strategy, timeouts, and error handling behavior. ```go builder.NewWorkflow("my-workflow", "My Workflow"). WithConfig(workflow.ExecutionConfig{ MaxRetries: 3, RetryDelayMs: 1000, RetryBackoff: workflow.BackoffLinear, TimeoutSeconds: 30, ContinueOnError: false, }) ``` -------------------------------- ### Define Type-Safe Workflow Step in Go Source: https://context7.com/sicko7947/gorkflow/llms.txt Demonstrates creating a type-safe workflow step using Go generics. It defines input and output structures and a handler function with configurable retry and timeout settings. Dependencies include the gorkflow library. ```go package main import ( "time" workflow "github.com/sicko7947/gorkflow" ) // Define data structures for step input and output type UserInput struct { UserID string `json:"userId"` Email string `json:"email"` } type ValidationResult struct { IsValid bool `json:"isValid"` Message string `json:"message"` UserID string `json:"userId"` } // Create a step with type-safe handler func NewValidateUserStep() *workflow.Step[UserInput, ValidationResult] { return workflow.NewStep( "validate_user", "Validate User Information", func(ctx *workflow.StepContext, input UserInput) (ValidationResult, error) { // Access structured logging with context ctx.Logger.Info(). Str("user_id", input.UserID). Str("email", input.Email). Int("attempt", ctx.Attempt). Msg("Validating user") // Perform validation logic isValid := len(input.Email) > 0 && len(input.UserID) > 0 result := ValidationResult{ IsValid: isValid, Message: "User validation completed", UserID: input.UserID, } return result, nil }, // Configure step-specific retry and timeout behavior workflow.WithRetries(5), workflow.WithBackoff(workflow.BackoffExponential), workflow.WithTimeout(10*time.Second), workflow.WithRetryDelay(2*time.Second), ) } ``` -------------------------------- ### Go: Build Workflow with Builder-Level Conditional API Source: https://context7.com/sicko7947/gorkflow/llms.txt Constructs a gorkflow using the builder API, incorporating a conditional step execution for the manual review process. The `ThenStepIf` method is used to specify the `manualReviewStep`, the `needsManualReview` condition function, and a default value for `ReviewResult` if the step is skipped. This is the recommended approach for conditional logic. ```go package main import ( "fmt" workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/builder" ) // ... (previous type definitions and needsManualReview function) // Define steps func checkOrderStep() *workflow.Step[OrderData, OrderData] { return workflow.NewStep( "check_order", "Check Order Requirements", func(ctx *workflow.StepContext, input OrderData) (OrderData, error) { // Store flags in state for conditional evaluation ctx.State.Set("requires_review", input.RequiresReview) ctx.State.Set("order_amount", input.Amount) ctx.Logger.Info(). Bool("requires_review", input.RequiresReview). Float64("amount", input.Amount). Msg("Order checked") return input, nil }, ) } func manualReviewStep() *workflow.Step[OrderData, ReviewResult] { return workflow.NewStep( "manual_review", "Manual Review Process", func(ctx *workflow.StepContext, input OrderData) (ReviewResult, error) { ctx.Logger.Info(). Str("order_id", input.OrderID). Msg("Performing manual review") return ReviewResult{ Approved: true, Reviewer: "admin@example.com", }, nil }, ) } func processOrderStep() *workflow.Step[ReviewResult, ProcessResult] { return workflow.NewStep( "process_order", "Process Order", func(ctx *workflow.StepContext, input ReviewResult) (ProcessResult, error) { status := "processed" if !input.Approved { status = "rejected" } return ProcessResult{Status: status}, nil }, ) } // Build workflow with conditional execution func NewConditionalWorkflow() (*workflow.Workflow, error) { checkStep := checkOrderStep() reviewStep := manualReviewStep() processStep := processOrderStep() // Builder-level conditional API (recommended) wf, err := builder.NewWorkflow("order_processing", "Order Processing with Conditional Review"). WithDescription("Processes orders with conditional manual review"). WithVersion("1.0"). ThenStep(checkStep). // Step executes only if condition returns true ThenStepIf( reviewStep, needsManualReview, &ReviewResult{Approved: true, Reviewer: "auto-approved"}, // Default value if skipped ). ThenStep(processStep). Build() if err != nil { return nil, fmt.Errorf("failed to build conditional workflow: %w", err) } return wf, nil } ``` -------------------------------- ### Go: Build Workflow with Fluent API and Mixed Execution Source: https://context7.com/sicko7947/gorkflow/llms.txt Defines a data processing workflow using a fluent builder. It includes sequential steps (validate, transform), parallel steps (audit, notify), and a final sequential step (finalize). Workflow-level configurations for retries, timeouts, and error handling are applied. Dependencies include the 'github.com/sicko7947/gorkflow' library. ```go package main import ( "fmt" workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/builder" ) type ProcessInput struct { Data []string `json:"data"` } type ProcessedData struct { Items []string `json:"items"` } type FinalResult struct { Success bool `json:"success"` Count int `json:"count"` } func NewDataWorkflow() (*workflow.Workflow, error) { // Define workflow-level defaults wf, err := builder.NewWorkflow("data_processor", "Data Processing Workflow"). WithDescription("Processes data through multiple validation and transformation steps"). WithVersion("2.1.0"). WithConfig(workflow.ExecutionConfig{ MaxRetries: 3, RetryDelayMs: 1000, RetryBackoff: workflow.BackoffLinear, TimeoutSeconds: 30, ContinueOnError: false, }). WithTags(map[string]string{ "environment": "production", "team": "data-engineering", }). // Sequential execution chain Sequence( workflow.NewStep("validate", "Validate Input", validateHandler), workflow.NewStep("transform", "Transform Data", transformHandler), ). // Parallel execution for independent tasks Parallel( workflow.NewStep("audit", "Audit Log", auditHandler), workflow.NewStep("notify", "Send Notification", notifyHandler), ). // Continue with sequential steps ThenStep(workflow.NewStep("finalize", "Finalize Results", finalizeHandler)). Build() if err != nil { return nil, fmt.Errorf("workflow build failed: %w", err) } return wf, nil } func validateHandler(ctx *workflow.StepContext, input ProcessInput) (ProcessInput, error) { if len(input.Data) == 0 { return ProcessInput{}, fmt.Errorf("empty data") } return input, nil } func transformHandler(ctx *workflow.StepContext, input ProcessInput) (ProcessedData, error) { return ProcessedData{Items: input.Data}, nil } func auditHandler(ctx *workflow.StepContext, input ProcessedData) (ProcessedData, error) { ctx.Logger.Info().Int("items", len(input.Items)).Msg("Audit completed") return input, nil } func notifyHandler(ctx *workflow.StepContext, input ProcessedData) (ProcessedData, error) { ctx.Logger.Info().Msg("Notification sent") return input, nil } func finalizeHandler(ctx *workflow.StepContext, input ProcessedData) (FinalResult, error) { return FinalResult{Success: true, Count: len(input.Items)}, nil } ``` -------------------------------- ### Go: Build Workflow with Type-Safe Conditional Step Wrapper Source: https://context7.com/sicko7947/gorkflow/llms.txt Constructs a gorkflow by wrapping a standard step with a condition using `workflow.NewConditionalStep`. This approach applies the condition directly at the step level, providing type safety. The `manualReviewStep` is wrapped with the `needsManualReview` condition and a default `ReviewResult`. ```go package main import ( "fmt" workflow "github.com/sicko7947/gorkflow" "github.com/sicko7947/gorkflow/builder" ) // ... (previous type definitions, needsManualReview function, and step definitions) // Alternative: Type-safe conditional step wrapper func NewConditionalWorkflowTypeSafe() (*workflow.Workflow, error) { checkStep := checkOrderStep() reviewStep := manualReviewStep() processStep := processOrderStep() // Wrap step with condition at step level defaultReview := &ReviewResult{Approved: true, Reviewer: "auto-approved"} conditionalReviewStep := workflow.NewConditionalStep( reviewStep, needsManualReview, defaultReview, ) wf, err := builder.NewWorkflow("order_processing", "Order Processing"). ThenStep(checkStep). ThenStep(conditionalReviewStep). ThenStep(processStep). Build() return wf, err } ``` -------------------------------- ### Parallel Execution in Gorkflow Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Demonstrates how to define and build a workflow that executes multiple independent steps concurrently. This is useful for tasks that can be processed in parallel to reduce overall execution time. The `Parallel` function takes multiple steps as arguments. ```go wf, err := builder.NewWorkflow("parallel-example", "Parallel Example"). Parallel( NewStep1(), NewStep2(), NewStep3(), ). ThenStep(NewMergeStep()). Build() ``` -------------------------------- ### DynamoDB Table Management Scripts Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Shell scripts for managing the DynamoDB table used by Gorkflow. Includes commands for creating and deleting tables, with options to configure AWS region, table name, and other settings via environment variables. The create script details table design and indexing. ```bash # Using defaults (ap-southeast-2 region, workflow_executions table) ./scripts/create-dynamodb-table.sh # Custom region and table name export AWS_REGION=us-east-1 export AWS_DYNAMODB_TABLE_NAME=my_workflow_table ./scripts/create-dynamodb-table.sh # Or inline AWS_REGION=eu-west-1 AWS_DYNAMODB_TABLE_NAME=workflows ./scripts/create-dynamodb-table.sh # Delete table (prompts for confirmation) ./scripts/delete-dynamodb-table.sh ``` -------------------------------- ### Go: Configure Step-Level Execution Parameters Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Illustrates how to override default workflow execution parameters for individual steps. This allows for specific retry, backoff, and timeout configurations on a per-step basis. ```go workflow.NewStep( "my-step", "My Step", handler, workflow.WithRetries(5), workflow.WithBackoff(workflow.BackoffExponential), workflow.WithTimeout(60*time.Second), ) ``` -------------------------------- ### Conditional Execution in Gorkflow Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Illustrates how to implement conditional logic within workflows, allowing steps to execute only when a specific condition is met. This enables dynamic workflow paths based on runtime data or previous step outcomes. Both builder-level and step-level APIs are shown. ```go // Define a condition function condition := func(ctx *workflow.StepContext) (bool, error) { // Access state or previous step outputs var shouldProcess bool ctx.State.Get("should_process", &shouldProcess) return shouldProcess, nil } // Builder-level API (recommended) processStep := workflow.NewStep("process", "Process Data", processHandler) memungkinkan := builder.NewWorkflow("conditional-workflow", "Conditional Workflow"). ThenStep(checkStep). ThenStepIf(processStep, condition, nil). // ← Builder-level conditional ThenStep(finalStep). Build() // Alternative: Step-level API (for type-safe default values) baseStep := workflow.NewStep("process", "Process Data", processHandler) defaultOutput := &ProcessOutput{Status: "skipped"} conditionalStep := workflow.NewConditionalStep(baseStep, condition, defaultOutput) wf, err := builder.NewWorkflow("conditional-workflow", "Conditional Workflow"). ThenStep(checkStep). ThenStep(conditionalStep). Build() ``` -------------------------------- ### Retry Configuration for Gorkflow Steps Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Shows how to configure step-specific retry behavior, including the number of retries, backoff strategy, and timeouts. This allows for robust handling of transient errors by automatically retrying failed steps. The `WithRetries`, `WithBackoff`, and `WithTimeout` options are used. ```go step := workflow.NewStep( "retry-example", "Step with Custom Retry", handler, workflow.WithRetries(5), workflow.WithBackoff(workflow.BackoffExponential), workflow.WithTimeout(10*time.Second), ) ``` -------------------------------- ### Define Workflow Step Input/Output Types (Go) Source: https://github.com/sicko7947/gorkflow/blob/main/README.md Defines the input and output structures for workflow steps using Go structs. This enables type-safe data flow between steps, leveraging Go generics for robust type checking. ```go package main import ( "fmt" workflow "github.com/sicko7947/gorkflow" ) // Input for the workflow type CalculationInput struct { A int `json:"a"` B int `json:"b"` } // Output from step 1 type SumOutput struct { Sum int `json:"sum"` } // Output from step 2 type ResultOutput struct { Result int `json:"result"` Message string `json:"message"` } ``` -------------------------------- ### Monitor Workflow Run Progress with Go Source: https://github.com/sicko7947/gorkflow/blob/main/PROJECT_INDEX.md Explains how to retrieve the status and progress of a running workflow using its unique run ID in Go. This is essential for observing the execution. ```Go engine.GetRun(ctx, runID) ```