Execution Context and Events¶
This reference covers the execution context, events, limits, and priorities that govern graph execution in SemanticKernel.Graph.
GraphExecutionContext¶
The GraphExecutionContext
maintains the execution state for a single graph run, tracking execution progress, managing resources, and providing coordination services.
Core Properties¶
public sealed class GraphExecutionContext
{
// Execution identification
public string ExecutionId { get; } // Unique execution identifier
public int ExecutionSeed { get; } // Seed for reproducible randomness
public Random Random { get; } // Seeded random generator
// Kernel and state
public Kernel Kernel { get; } // Semantic kernel instance
public IKernelWrapper KernelWrapper { get; } // Kernel wrapper
public GraphState GraphState { get; set; } // Current graph state
// Execution control
public CancellationToken CancellationToken { get; } // Effective cancellation token
public GraphExecutionOptions ExecutionOptions { get; } // Immutable execution options
// Timing and status
public DateTimeOffset StartTime { get; } // Execution start timestamp
public DateTimeOffset? EndTime { get; } // Execution end timestamp
public TimeSpan? Duration { get; } // Total execution duration
public GraphExecutionStatus Status { get; } // Current execution status
// Execution state
public bool IsPaused { get; } // Whether execution is paused
public string? PauseReason { get; } // Reason for pause
public IGraphNode? CurrentNode { get; } // Currently executing node
public IReadOnlyList<IGraphNode> ExecutionPath { get; } // Execution path taken
public int NodesExecuted { get; } // Number of nodes executed
// Work management
public DeterministicWorkQueue WorkQueue { get; } // Deterministic work queue
}
Execution Status¶
The GraphExecutionStatus
enum represents the current state of execution:
public enum GraphExecutionStatus
{
NotStarted = 0, // Execution has not started yet
Running = 1, // Execution is currently running
Completed = 2, // Execution completed successfully
Failed = 3, // Execution failed with an error
Cancelled = 4, // Execution was cancelled
Paused = 5 // Execution is paused awaiting continuation
}
State Management Methods¶
// Execution lifecycle
public void MarkAsStarted(IGraphNode startingNode) // Mark execution as started
public void MarkAsCompleted(FunctionResult result) // Mark execution as completed
public void MarkAsFailed(Exception error) // Mark execution as failed
public void MarkAsCancelled() // Mark execution as cancelled
// Node tracking
public void RecordNodeStarted(IGraphNode node) // Record node execution start
public void RecordNodeCompleted(IGraphNode node, FunctionResult result) // Record node completion
public void RecordNodeFailed(IGraphNode node, Exception exception) // Record node failure
// Work queue management
public void EnqueueNextNodes(IEnumerable<IGraphNode> candidates) // Enqueue next nodes
// Pause/resume control
public void Pause(string reason) // Pause execution
public void Resume() // Resume execution
public Task WaitIfPausedAsync(CancellationToken cancellationToken) // Wait if paused
Property Management¶
public void SetProperty<T>(string key, T value) // Set custom property
public T? GetProperty<T>(string key) // Get custom property
public bool TryGetProperty<T>(string key, out T? value) // Try get property
public void RemoveProperty(string key) // Remove property
Execution Events¶
The execution system emits real-time events that provide visibility into execution progress and state changes.
GraphExecutionEvent Base Class¶
All execution events inherit from GraphExecutionEvent
:
public abstract class GraphExecutionEvent
{
public string EventId { get; } // Unique event identifier
public string ExecutionId { get; } // Associated execution ID
public DateTimeOffset Timestamp { get; } // Event timestamp
public abstract GraphExecutionEventType EventType { get; } // Event type
public long HighPrecisionTimestamp { get; } // High-precision timestamp
public long HighPrecisionFrequency { get; } // Timer frequency
}
Event Types¶
The GraphExecutionEventType
enum defines all possible event types:
public enum GraphExecutionEventType
{
ExecutionStarted = 0, // Graph execution started
NodeStarted = 1, // Node execution started
NodeCompleted = 2, // Node execution completed successfully
NodeFailed = 3, // Node execution failed
ExecutionCompleted = 4, // Graph execution completed successfully
ExecutionFailed = 5, // Graph execution failed
ExecutionCancelled = 6, // Graph execution was cancelled
NodeEntered = 7, // Executor entered a node
NodeExited = 8, // Executor exited a node
ConditionEvaluated = 9, // Conditional expression evaluated
StateMergeConflictDetected = 10, // State merge conflict detected
CircuitBreakerStateChanged = 11, // Circuit breaker state changed
CircuitBreakerOperationAttempted = 12, // Circuit breaker operation attempted
CircuitBreakerOperationBlocked = 13, // Circuit breaker operation blocked
ResourceBudgetExhausted = 14, // Resource budget exhausted
RetryScheduled = 15, // Retry scheduled
NodeSkippedDueToErrorPolicy = 16 // Node skipped due to error policy
}
Key Event Classes¶
GraphExecutionStartedEvent¶
public sealed class GraphExecutionStartedEvent : GraphExecutionEvent
{
public IGraphNode StartNode { get; } // Starting node
public GraphState InitialState { get; } // Initial graph state
}
NodeExecutionStartedEvent¶
public sealed class NodeExecutionStartedEvent : GraphExecutionEvent
{
public IGraphNode Node { get; } // Node that started
public GraphState CurrentState { get; } // Current state
}
NodeExecutionCompletedEvent¶
public sealed class NodeExecutionCompletedEvent : GraphExecutionEvent
{
public IGraphNode Node { get; } // Node that completed
public FunctionResult Result { get; } // Execution result
public GraphState UpdatedState { get; } // Updated state
public TimeSpan ExecutionDuration { get; } // Execution duration
}
NodeExecutionFailedEvent¶
public sealed class NodeExecutionFailedEvent : GraphExecutionEvent
{
public IGraphNode Node { get; } // Node that failed
public Exception Exception { get; } // Exception that occurred
public GraphState CurrentState { get; } // Current state
public TimeSpan ExecutionDuration { get; } // Execution duration
}
Execution Limits and Safeguards¶
The execution system provides multiple layers of protection against runaway executions and resource exhaustion.
Execution Options¶
public sealed class GraphExecutionOptions
{
public bool EnableLogging { get; } // Whether logging is enabled
public bool EnableMetrics { get; } // Whether metrics are enabled
public int MaxExecutionSteps { get; } // Maximum execution steps
public bool ValidateGraphIntegrity { get; } // Whether to validate graph
public TimeSpan ExecutionTimeout { get; } // Overall execution timeout
public bool EnablePlanCompilation { get; } // Whether to compile plans
}
Default Limits¶
public static GraphExecutionOptions CreateDefault()
{
return new GraphExecutionOptions(
enableLogging: true,
enableMetrics: true,
maxExecutionSteps: 1000, // Default: 1000 steps
validateGraphIntegrity: true,
executionTimeout: TimeSpan.FromMinutes(10), // Default: 10 minutes
enablePlanCompilation: true
);
}
Execution Timeout¶
The system automatically enforces execution timeouts:
// Build effective cancellation token honoring overall execution timeout
if (ExecutionOptions.ExecutionTimeout > TimeSpan.Zero)
{
_executionTimeoutCts = new CancellationTokenSource(ExecutionOptions.ExecutionTimeout);
var linked = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _executionTimeoutCts.Token);
_effectiveCancellationToken = linked.Token;
}
Step Limits¶
Execution is automatically terminated if the maximum step count is exceeded:
// Respect per-execution options for max steps
var maxIterations = Math.Max(1, context.ExecutionOptions.MaxExecutionSteps);
var iterations = 0;
while (currentNode != null && iterations < maxIterations)
{
// ... execution logic
iterations++;
}
if (iterations >= maxIterations)
{
throw new InvalidOperationException($"Graph execution exceeded maximum steps ({maxIterations}). Possible infinite loop detected.");
}
Execution Priorities¶
The system supports priority-based resource allocation and scheduling through the ExecutionPriority
enum.
Priority Levels¶
public enum ExecutionPriority
{
Low = 0, // Low priority (consumes more resources)
Normal = 1, // Normal priority (default)
High = 2, // High priority (consumes fewer resources)
Critical = 3 // Critical priority (highest priority)
}
Priority-Based Resource Allocation¶
// Determine cost and priority
var priority = context.GraphState.KernelArguments.GetExecutionPriority() ?? _resourceOptions.DefaultPriority;
var nodeCost = 1.0;
// Priority affects resource consumption
var priorityFactor = priority switch
{
ExecutionPriority.Critical => 0.5, // 50% resource consumption
ExecutionPriority.High => 0.6, // 60% resource consumption
ExecutionPriority.Normal => 1.0, // 100% resource consumption
_ => 1.5 // 150% resource consumption
};
var adjustedCost = Math.Max(0.5, workCostWeight * priorityFactor);
Setting Execution Priority¶
Priorities can be set at the execution level:
// Set priority for the entire execution
arguments.SetExecutionPriority(ExecutionPriority.High);
// Set priority for specific nodes
arguments.SetNodePriority("nodeId", ExecutionPriority.Critical);
Deterministic Work Queue¶
The DeterministicWorkQueue
provides stable, reproducible scheduling for graph execution.
Key Features¶
public sealed class DeterministicWorkQueue
{
public string ExecutionId { get; } // Associated execution ID
public int Count { get; } // Pending work items
// Enqueue operations
public ScheduledNodeWorkItem Enqueue(IGraphNode node, int priority = 0)
public IReadOnlyList<ScheduledNodeWorkItem> EnqueueRange(IEnumerable<IGraphNode> nodes, int priority = 0)
// Dequeue operations
public bool TryDequeue(out ScheduledNodeWorkItem? item)
// Deterministic ordering
public IReadOnlyList<IGraphNode> OrderDeterministically(IEnumerable<IGraphNode> nodes)
// Work stealing (for parallel execution)
public IReadOnlyList<ScheduledNodeWorkItem> TryStealFrom(DeterministicWorkQueue victim, int maxItemsToSteal = 1, int minPriority = int.MinValue)
}
Deterministic Ordering¶
The queue ensures stable ordering across executions:
public IReadOnlyList<IGraphNode> OrderDeterministically(IEnumerable<IGraphNode> nodes)
{
return nodes
.Where(n => n != null)
.OrderBy(n => n.NodeId, StringComparer.Ordinal) // Primary: NodeId
.ThenBy(n => n.Name, StringComparer.Ordinal) // Secondary: Name
.ToList()
.AsReadOnly();
}
Work Item Structure¶
public sealed class ScheduledNodeWorkItem
{
public string WorkId { get; } // Unique work identifier
public string ExecutionId { get; } // Associated execution
public long SequenceNumber { get; } // Monotonic sequence
public IGraphNode Node { get; } // Node to execute
public int Priority { get; } // Execution priority
public DateTimeOffset ScheduledAt { get; } // Scheduling timestamp
}
Resource Governance¶
The execution context integrates with resource governance to manage CPU, memory, and API quotas.
Resource Acquisition¶
// Acquire resource permits before node execution
using var lease = _resourceGovernor != null
? await _resourceGovernor.AcquireAsync(nodeCost, priority, context.CancellationToken)
: default;
// Resource permits are automatically released when the lease is disposed
Resource Options¶
public sealed class GraphResourceOptions
{
public bool EnableResourceGovernance { get; set; } // Enable/disable governance
public double CpuHighWatermarkPercent { get; set; } // CPU threshold (default: 85%)
public double CpuSoftLimitPercent { get; set; } // Soft CPU limit (default: 70%)
public double MinAvailableMemoryMB { get; set; } // Min memory (default: 512MB)
public double BasePermitsPerSecond { get; set; } // Base rate (default: 50/s)
public int MaxBurstSize { get; set; } // Max burst (default: 100)
public ExecutionPriority DefaultPriority { get; set; } // Default priority
}
Usage Examples¶
Basic Execution Context¶
// Create execution context
var graphState = arguments.GetOrCreateGraphState();
var context = new GraphExecutionContext(kernel, graphState, cancellationToken);
// Monitor execution progress
Console.WriteLine($"Execution {context.ExecutionId} started at {context.StartTime}");
Console.WriteLine($"Current status: {context.Status}");
Console.WriteLine($"Nodes executed: {context.NodesExecuted}");
// Check execution limits
if (context.ExecutionOptions.MaxExecutionSteps > 0)
{
Console.WriteLine($"Max steps: {context.ExecutionOptions.MaxExecutionSteps}");
}
if (context.ExecutionOptions.ExecutionTimeout > TimeSpan.Zero)
{
Console.WriteLine($"Timeout: {context.ExecutionOptions.ExecutionTimeout}");
}
Setting Execution Priority¶
// Set high priority for critical operations
arguments.SetExecutionPriority(ExecutionPriority.High);
// Set specific node priorities
arguments.SetNodePriority("dataProcessing", ExecutionPriority.Critical);
arguments.SetNodePriority("logging", ExecutionPriority.Low);
Monitoring Execution Events¶
// Subscribe to execution events
eventStream.EventEmitted += (sender, @event) =>
{
switch (@event)
{
case NodeExecutionStartedEvent started:
Console.WriteLine($"Node {started.Node.Name} started executing");
break;
case NodeExecutionCompletedEvent completed:
Console.WriteLine($"Node {completed.Node.Name} completed in {completed.ExecutionDuration}");
break;
case NodeExecutionFailedEvent failed:
Console.WriteLine($"Node {failed.Node.Name} failed: {failed.Exception.Message}");
break;
}
};
Resource-Aware Execution¶
// Configure resource governance
var resourceOptions = new GraphResourceOptions
{
EnableResourceGovernance = true,
CpuHighWatermarkPercent = 80.0,
MinAvailableMemoryMB = 1024.0,
DefaultPriority = ExecutionPriority.Normal
};
// The executor will automatically manage resource allocation
// based on node costs and priorities
See Also¶
- Execution Model - Core execution concepts and lifecycle
- Resource Governance - Resource management and concurrency
- Streaming Execution - Real-time execution monitoring
- Error Handling - Error policies and recovery
- GraphExecutor API - Main executor interface