orchestrator

package
v0.1.61 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package orchestrator provides the core service orchestration functionality for muster.

The orchestrator is responsible for managing the lifecycle of all services in muster, including both static services (Kubernetes connections, port forwards, MCP servers) and dynamic ServiceClass-based service instances. It ensures services are started in the correct dependency order and handles automatic recovery when dependencies fail.

Architecture

The orchestrator has been enhanced with ServiceClass support and now uses:

  • **Service Registry Pattern**: Unified management of static and dynamic services
  • **Dependency Graph**: Complex dependency relationships across service types
  • **ServiceClass Integration**: Dynamic service creation and lifecycle management
  • **Event-Driven Updates**: Real-time state and health monitoring
  • **API Service Locator**: Clean integration through the central API layer
  • **Tool Caller Interface**: Integration with aggregator for tool execution

Service Types

The orchestrator manages both traditional and ServiceClass-based services:

## Static Services (Traditional)

  • **K8s Connections**: Establish and maintain connections to Kubernetes clusters
  • **Port Forwards**: Create kubectl port-forward tunnels to cluster services
  • **MCP Servers**: Run Model Context Protocol servers for AI assistant integration

## ServiceClass-Based Services (Dynamic)

  • **ServiceClass Instances**: Runtime-configurable services created from YAML definitions
  • **Tool-Driven Lifecycle**: Operations executed through aggregator tool integration
  • **Template-Based Configuration**: Dynamic arg substitution and mapping
  • **Event Streaming**: Real-time instance state and lifecycle events
  • **Persistence Support**: Optional persistence of service instance definitions

ServiceClass Integration

The orchestrator provides comprehensive ServiceClass instance management:

  • **CreateServiceClassInstance**: Creates new instances from ServiceClass definitions
  • **DeleteServiceClassInstance**: Cleanup and lifecycle management
  • **GetServiceClassInstance**: Instance status and data retrieval
  • **ListServiceClassInstances**: Full instance inventory
  • **Event Subscription**: Real-time instance lifecycle events

## ServiceClass Instance Lifecycle

  1. **ServiceClass Validation**: Verify ServiceClass exists and is available
  2. **Tool Availability Check**: Ensure required tools are accessible through aggregator
  3. **Instance Creation**: Create GenericServiceInstance with ServiceClass reference
  4. **Arg Validation**: Validate args against ServiceClass schema
  5. **Tool Execution**: Execute ServiceClass create tool with templated args
  6. **Registration**: Register instance with unified service registry
  7. **Health Monitoring**: Periodic health checks using ServiceClass health tools
  8. **Event Propagation**: Broadcast instance state changes and lifecycle events
  9. **Persistence**: Optional persistence of instance definitions to YAML files

Enhanced Dependency Management

The dependency system now supports complex relationships:

## Traditional Dependencies

  1. **K8s connections** (foundation - no dependencies)
  2. **Port forwards** (depend on K8s connections)
  3. **MCP servers** (may depend on port forwards)

## ServiceClass Dependencies

  • **YAML-Defined Dependencies**: Specified in ServiceClass definitions
  • **Runtime Dependencies**: Added during instance creation
  • **Cross-Type Dependencies**: ServiceClass instances can depend on static services
  • **Tool Dependencies**: ServiceClass availability depends on aggregator tools

## Dependency Features

  • **Cascade Operations**: Failure in one service stops all dependents
  • **Dependency Restoration**: Automatic restart of dependents when dependencies recover
  • **Circular Dependency Detection**: Prevents invalid dependency configurations
  • **Dependency Validation**: Ensures all dependencies exist and are valid

Health Monitoring

Enhanced health monitoring supports both service types:

## Static Service Health

  • Periodic health checks for traditional service types
  • Automatic recovery attempts for failed services
  • Cascade failure handling for dependent services

## ServiceClass Health

  • Tool-driven health checking through ServiceClass health tools
  • Configurable health check intervals and thresholds
  • Template-based arg substitution for health check tools
  • Response mapping for health status extraction
  • Failure threshold tracking and recovery detection

State Management

Comprehensive state management with ServiceClass awareness:

  • **Unified State Tracking**: Both static and ServiceClass services
  • **Event-Driven Updates**: Real-time state change propagation
  • **ServiceClass Instance Events**: Detailed lifecycle event streaming
  • **State Correlation**: Track related operations across service lifecycle
  • **Health Status Integration**: Combined state and health monitoring

Service Instance Persistence

ServiceClass instances can be persisted to YAML files:

  • **Automatic Persistence**: Optional persistence during instance creation
  • **Auto-Start Support**: Instances can be configured to start automatically
  • **Definition Loading**: Persisted instances loaded on orchestrator startup
  • **YAML Management**: Create, update, and delete persisted definitions

API Integration

Following the Service Locator Pattern, the orchestrator provides:

  • **Unified Service Management**: Single interface for all service operations
  • **ServiceClass APIs**: Complete ServiceClass instance management
  • **Event Subscription**: Real-time state and instance event streaming
  • **Tool Provider Integration**: Aggregator tool execution capabilities
  • **Clean Separation**: No direct inter-package dependencies

Usage Examples

## Traditional Orchestrator Usage

cfg := orchestrator.Config{
    Aggregator: aggregatorConfig,
    ToolCaller: toolCaller,
    Storage:    storage,
    Yolo:       false,
}

orch := orchestrator.New(cfg)
if err := orch.Start(ctx); err != nil {
    log.Fatal(err)
}
defer orch.Stop()

## ServiceClass Instance Management

// Create ServiceClass instance
req := orchestrator.CreateServiceRequest{
    ServiceClassName: "kubernetes_port_forward",
    Name:             "my-app-forward",
    Args: map[string]interface{}{
        "namespace":    "default",
        "service_name": "my-app",
        "local_port":   "8080",
        "remote_port":  "80",
    },
    Persist:   true,
    AutoStart: true,
}

instance, err := orch.CreateServiceClassInstance(ctx, req)
if err != nil {
    log.Fatal(err)
}

// Monitor instance lifecycle
events := orch.SubscribeToServiceInstanceEvents()
go func() {
    for event := range events {
        fmt.Printf("Instance %s: %s -> %s\n",
            event.Name, event.OldState, event.NewState)
    }
}()

// Get instance status
status, err := orch.GetServiceClassInstance(instance.Name)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Instance state: %s, health: %s\n", status.State, status.Health)

Service Names

Services are identified by names following these conventions:

## Static Services

  • **K8s connections**: "k8s-mc-{cluster}" or "k8s-wc-{cluster}"
  • **Port forwards**: "{name}" (from configuration)
  • **MCP servers**: "mcp-{name}" (from configuration)

## ServiceClass Instances

  • **User-defined names** specified during instance creation
  • Must be unique within the service registry
  • Can use ServiceClass default name templates with arg substitution

Error Handling

Enhanced error handling for ServiceClass operations:

  • **ServiceClass Validation Errors**: Invalid or unavailable ServiceClass definitions
  • **Tool Execution Errors**: Aggregator tool failures and response mapping errors
  • **Arg Template Errors**: Template substitution and validation failures
  • **Dependency Errors**: Invalid dependencies and circular dependency detection
  • **Instance Management Errors**: Creation, deletion, and lifecycle management failures
  • **Persistence Errors**: YAML file operations and storage failures

Thread Safety

All orchestrator operations are thread-safe:

  • **Concurrent service operations**
  • **Thread-safe service registry access**
  • **Atomic state updates and event propagation**
  • **Safe dependency graph manipulation**
  • **Concurrent ServiceClass instance management**
  • **Protected access to persistence layer**

Index

Constants

View Source
const MaxConcurrentRetries = 5

MaxConcurrentRetries limits the number of MCPServers that can be retried simultaneously. This prevents a "thundering herd" scenario where many failed servers retry at once, potentially overwhelming the system or upstream services.

View Source
const RetryInterval = 30 * time.Second

RetryInterval is the interval at which the orchestrator checks for failed servers to retry.

Variables

This section is empty.

Functions

This section is empty.

Types

type Adapter

type Adapter struct {
	// contains filtered or unexported fields
}

Adapter adapts the orchestrator to implement api.ServiceManagerHandler

func NewAPIAdapter

func NewAPIAdapter(orchestrator *Orchestrator) *Adapter

NewAPIAdapter creates a new orchestrator adapter

func (*Adapter) CreateService

CreateService creates a new ServiceClass-based service instance (unified method)

func (*Adapter) CreateServiceClassInstance

func (a *Adapter) CreateServiceClassInstance(ctx context.Context, req api.CreateServiceInstanceRequest) (*api.ServiceInstance, error)

CreateServiceClassInstance is an alias that delegates to CreateService for backward compatibility

func (*Adapter) DeleteService

func (a *Adapter) DeleteService(ctx context.Context, name string) error

DeleteService deletes a service (works for ServiceClass instances by name)

func (*Adapter) DeleteServiceClassInstance

func (a *Adapter) DeleteServiceClassInstance(ctx context.Context, name string) error

DeleteServiceClassInstance deletes a ServiceClass-based service instance

func (*Adapter) ExecuteTool

func (a *Adapter) ExecuteTool(ctx context.Context, toolName string, args map[string]interface{}) (*api.CallToolResult, error)

ExecuteTool executes a tool by name

func (*Adapter) GetAllServices

func (a *Adapter) GetAllServices() []api.ServiceStatus

func (*Adapter) GetService

func (a *Adapter) GetService(name string) (*api.ServiceInstance, error)

GetService returns detailed service information by name

func (*Adapter) GetServiceClassInstance

func (a *Adapter) GetServiceClassInstance(name string) (*api.ServiceInstance, error)

GetServiceClassInstance returns service instance info by ID

func (*Adapter) GetServiceStatus

func (a *Adapter) GetServiceStatus(name string) (*api.ServiceStatus, error)

Service status

func (*Adapter) GetTools

func (a *Adapter) GetTools() []api.ToolMetadata

GetTools returns all tools this provider offers

func (*Adapter) ListServiceClassInstances

func (a *Adapter) ListServiceClassInstances() []api.ServiceInstance

ListServiceClassInstances returns all service class instances

func (*Adapter) Register

func (a *Adapter) Register()

Register registers the adapter with the API

func (*Adapter) RestartService

func (a *Adapter) RestartService(name string) error

func (*Adapter) StartService

func (a *Adapter) StartService(name string) error

Service lifecycle management

func (*Adapter) StopService

func (a *Adapter) StopService(name string) error

func (*Adapter) SubscribeToServiceInstanceEvents

func (a *Adapter) SubscribeToServiceInstanceEvents() <-chan api.ServiceInstanceEvent

SubscribeToServiceInstanceEvents returns a channel for service instance events

func (*Adapter) SubscribeToStateChanges

func (a *Adapter) SubscribeToStateChanges() <-chan api.ServiceStateChangedEvent

type Config

type Config struct {
	Aggregator config.AggregatorConfig
	Yolo       bool
	ToolCaller ToolCaller // Optional: for ServiceClass-based services
}

Config holds the configuration for the orchestrator.

type CreateServiceRequest

type CreateServiceRequest struct {
	// ServiceClass to use
	ServiceClassName string `json:"serviceClassName"`

	// Name for the service instance (must be unique)
	Name string `json:"name"`

	// Arguments for service creation
	Args map[string]interface{} `json:"args"`

	// Whether to persist this service instance definition to YAML files
	Persist bool `json:"persist,omitempty"`

	// Optional: Whether this instance should be started automatically on system startup
	AutoStart bool `json:"autoStart,omitempty"`

	// Override default timeouts (future use)
	CreateTimeout *time.Duration `json:"createTimeout,omitempty"`
	DeleteTimeout *time.Duration `json:"deleteTimeout,omitempty"`
}

CreateServiceRequest represents a request to create a new ServiceClass-based service instance

type Orchestrator

type Orchestrator struct {
	// contains filtered or unexported fields
}

Orchestrator manages services using the unified service registry architecture. It serves as the single source of truth for all active services, both static and dynamic.

func New

func New(cfg Config) *Orchestrator

New creates a new orchestrator.

func (*Orchestrator) CreateServiceClassInstance

func (o *Orchestrator) CreateServiceClassInstance(ctx context.Context, req CreateServiceRequest) (*ServiceInstanceInfo, error)

CreateServiceClassInstance creates a new ServiceClass-based service instance

func (*Orchestrator) DeleteServiceClassInstance

func (o *Orchestrator) DeleteServiceClassInstance(ctx context.Context, name string) error

DeleteServiceClassInstance deletes a ServiceClass-based service instance

func (*Orchestrator) GetAllServices

func (o *Orchestrator) GetAllServices() []ServiceStatus

GetAllServices returns status for all services (both static and ServiceClass-based).

func (*Orchestrator) GetServiceClassInstance

func (o *Orchestrator) GetServiceClassInstance(name string) (*ServiceInstanceInfo, error)

GetServiceClassInstance returns information about a ServiceClass-based service instance

func (*Orchestrator) GetServiceRegistry

func (o *Orchestrator) GetServiceRegistry() services.ServiceRegistry

GetServiceRegistry returns the service registry.

func (*Orchestrator) GetServiceStatus

func (o *Orchestrator) GetServiceStatus(name string) (*ServiceStatus, error)

GetServiceStatus returns the status of a specific service.

func (*Orchestrator) GetToolCaller

func (o *Orchestrator) GetToolCaller() ToolCaller

GetToolCaller returns the current ToolCaller

func (*Orchestrator) ListServiceClassInstances

func (o *Orchestrator) ListServiceClassInstances() []ServiceInstanceInfo

ListServiceClassInstances returns information about all ServiceClass-based service instances

func (*Orchestrator) RestartService

func (o *Orchestrator) RestartService(name string) error

RestartService restarts a specific service by name

func (*Orchestrator) SetToolCaller

func (o *Orchestrator) SetToolCaller(toolCaller ToolCaller)

SetToolCaller sets the ToolCaller for ServiceClass-based services This is called after the aggregator is available

func (*Orchestrator) Start

func (o *Orchestrator) Start(ctx context.Context) error

Start initializes and starts all services (both static and ServiceClass-based).

func (*Orchestrator) StartService

func (o *Orchestrator) StartService(name string) error

StartService starts a specific service by name. For MCP servers, this method waits for the server to be fully registered with the aggregator before returning, ensuring that tools are available.

func (*Orchestrator) Stop

func (o *Orchestrator) Stop() error

Stop gracefully stops all services (both static and ServiceClass-based).

func (*Orchestrator) StopService

func (o *Orchestrator) StopService(name string) error

StopService stops a specific service by name

func (*Orchestrator) SubscribeToServiceInstanceEvents

func (o *Orchestrator) SubscribeToServiceInstanceEvents() <-chan ServiceInstanceEvent

SubscribeToServiceInstanceEvents returns a channel for receiving ServiceClass-based service instance events

func (*Orchestrator) SubscribeToStateChanges

func (o *Orchestrator) SubscribeToStateChanges() <-chan ServiceStateChangedEvent

SubscribeToStateChanges returns a channel for state change events.

type ServiceInstanceEvent

type ServiceInstanceEvent struct {
	Name        string                 `json:"name"`
	ServiceType string                 `json:"serviceType"`
	OldState    string                 `json:"oldState"`
	NewState    string                 `json:"newState"`
	OldHealth   string                 `json:"oldHealth"`
	NewHealth   string                 `json:"newHealth"`
	Error       string                 `json:"error,omitempty"`
	Timestamp   time.Time              `json:"timestamp"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
}

ServiceInstanceEvent represents a service instance state change event

type ServiceInstanceInfo

type ServiceInstanceInfo struct {
	Name             string                 `json:"name"`
	ServiceClassName string                 `json:"serviceClassName"`
	ServiceClassType string                 `json:"serviceClassType"`
	State            string                 `json:"state"`
	Health           string                 `json:"health"`
	LastError        string                 `json:"lastError,omitempty"`
	CreatedAt        time.Time              `json:"createdAt"`
	UpdatedAt        time.Time              `json:"updatedAt"`
	LastChecked      *time.Time             `json:"lastChecked,omitempty"`
	ServiceData      map[string]interface{} `json:"serviceData,omitempty"`
	CreationArgs     map[string]interface{} `json:"creationArgs"`
	Outputs          map[string]interface{} `json:"outputs,omitempty"`
}

ServiceInstanceInfo provides information about a ServiceClass-based service instance

type ServiceStateChangedEvent

type ServiceStateChangedEvent struct {
	Name        string
	ServiceType string
	OldState    string
	NewState    string
	Health      string
	Error       error
	Timestamp   int64
}

ServiceStateChangedEvent represents a service state change event.

type ServiceStatus

type ServiceStatus struct {
	Name   string
	Type   string
	State  string
	Health string
	Error  error
}

ServiceStatus represents the status of a service.

type StopReason

type StopReason int

StopReason tracks why a service was stopped.

const (
	StopReasonManual StopReason = iota
	StopReasonDependency
)

type ToolCaller

type ToolCaller interface {
	CallTool(ctx context.Context, toolName string, args map[string]interface{}) (map[string]interface{}, error)
}

ToolCaller represents the interface for calling aggregator tools This interface is implemented by the aggregator integration

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL