Network Commands

Network Commands

The Matrix Communication Framework provides a command system for declarative remote procedure invocation between distributed services.

Command Definition

<ServiceNode Name="OrderService">
    <!-- Define commands at service level -->
    <ServiceNode.Commands>
        <NetworkCommand Name="CreateOrder" 
                       Path="/orders/create"
                       ResponseType="{x:Type OrderResponse}">
            <NetworkCommand.Parameters>
                <Parameter Name="orderId" Type="string" Required="true"/>
                <Parameter Name="items" Type="List<OrderItem>" Required="true"/>
                <Parameter Name="customerId" Type="string" Required="true"/>
            </NetworkCommand.Parameters>
        </NetworkCommand>

        <NetworkCommand Name="CancelOrder"
                       Path="/orders/cancel"
                       CanExecute="CanCancelOrder">
            <NetworkCommand.Parameters>
                <Parameter Name="orderId" Type="string" Required="true"/>
                <Parameter Name="reason" Type="string" Required="false"/>
            </NetworkCommand.Parameters>
        </NetworkCommand>
    </ServiceNode.Commands>

    <!-- Command bindings -->
    <ServiceNode.CommandBindings>
        <CommandBinding Command="CreateOrder" 
                       Executed="OnCreateOrder"
                       CanExecute="CanCreateOrder"/>
    </ServiceNode.CommandBindings>
</ServiceNode>

Command Implementation

public class NetworkCommand : CommunicationElement
{
    public static readonly DependencyProperty PathProperty =
        DependencyProperty.Register(
            "Path",
            typeof(string),
            typeof(NetworkCommand)
        );

    public static readonly DependencyProperty ParametersProperty =
        DependencyProperty.Register(
            "Parameters",
            typeof(CommandParameterCollection),
            typeof(NetworkCommand)
        );

    public static readonly DependencyProperty ResponseTypeProperty =
        DependencyProperty.Register(
            "ResponseType",
            typeof(Type),
            typeof(NetworkCommand)
        );

    public string Path
    {
        get => (string)GetValue(PathProperty);
        set => SetValue(PathProperty, value);
    }

    public CommandParameterCollection Parameters
    {
        get => (CommandParameterCollection)GetValue(ParametersProperty);
        set => SetValue(ParametersProperty, value);
    }

    public Type ResponseType
    {
        get => (Type)GetValue(ResponseTypeProperty);
        set => SetValue(ResponseTypeProperty, value);
    }

    public async Task<object> ExecuteAsync(IDictionary<string, object> parameters)
    {
        ValidateParameters(parameters);
        
        var message = new CommandMessage
        {
            CommandPath = Path,
            Parameters = parameters,
            Timestamp = DateTimeOffset.UtcNow
        };

        return await _dispatcher.SendCommandAsync(message);
    }
}

Command Binding System

public class NetworkCommandBinding : CommunicationElement
{
    private readonly INetworkDispatcher _dispatcher;
    private readonly ICommandValidator _validator;

    public async Task<bool> CanExecuteAsync(NetworkCommand command, object parameter)
    {
        // Check network availability
        if (!await _dispatcher.IsAvailableAsync(command.Path))
            return false;

        // Validate parameters
        if (!_validator.ValidateParameters(command, parameter))
            return false;

        // Check custom conditions
        return await InvokeCanExecuteAsync(command, parameter);
    }

    public async Task ExecuteAsync(NetworkCommand command, object parameter)
    {
        try
        {
            // Pre-execution hooks
            await OnCommandExecutingAsync(command, parameter);

            // Execute command
            var result = await command.ExecuteAsync(
                ConvertToParameters(parameter)
            );

            // Post-execution hooks
            await OnCommandExecutedAsync(command, result);
        }
        catch (NetworkException ex)
        {
            await HandleCommandFailureAsync(command, ex);
        }
    }
}

Command Usage

public class OrderProcessor : ServiceNode
{
    private readonly NetworkCommand _createOrderCommand;
    private readonly ILogger<OrderProcessor> _logger;

    public OrderProcessor(ILogger<OrderProcessor> logger)
    {
        _logger = logger;
        _createOrderCommand = FindCommand("CreateOrder");
    }

    private async Task<bool> CanCreateOrder(object parameter)
    {
        var order = parameter as OrderRequest;
        if (order == null) return false;

        // Check business rules
        if (!await ValidateInventoryAsync(order.Items))
            return false;

        // Check customer status
        return await ValidateCustomerAsync(order.CustomerId);
    }

    private async Task OnCreateOrder(object parameter)
    {
        var order = parameter as OrderRequest;
        
        try
        {
            var response = await _createOrderCommand.ExecuteAsync(
                new Dictionary<string, object>
                {
                    ["orderId"] = Guid.NewGuid().ToString(),
                    ["items"] = order.Items,
                    ["customerId"] = order.CustomerId
                }
            );

            await ProcessOrderResponseAsync(response as OrderResponse);
        }
        catch (CommandExecutionException ex)
        {
            _logger.LogError(ex, "Failed to create order");
            throw;
        }
    }
}

Best Practices

  1. Command Design

    • Keep commands focused and atomic
    • Define clear parameter contracts
    • Implement proper validation
    • Handle partial failures
    • Support command composition
  2. Error Handling

    • Implement retry policies
    • Handle timeouts gracefully
    • Provide detailed error information
    • Support compensation actions
    • Log command execution
  3. Performance

    • Cache command metadata
    • Batch related commands
    • Optimize parameter serialization
    • Monitor execution times
    • Implement circuit breakers
  4. Security

    • Validate command sources
    • Authorize command execution
    • Encrypt sensitive parameters
    • Audit command usage
    • Implement rate limiting