Table of Contents

v1.3.0 "Ōtō" - Response Acknowledgment

Release Date: July 25, 2025
Code Name: "Ōtō" (応答 - Response/Acknowledgment)
Type: Minor Release


🎯 Overview

Version 1.3.0 introduces comprehensive response acknowledgment across all WebSocket operations, replacing empty Task returns with ActionResult responses. This release also modernizes streaming operations by adopting ChannelReader for improved performance and adds machine information capabilities to the client interface.

🛠️ Technical Details

ActionResult Response Pattern

All WebSocket event handlers now return ActionResult instead of empty Task, providing:

  • Acknowledgment Feedback: Clients can confirm successful operation completion
  • Error Reporting: Detailed error information when operations fail
  • Operation Status: Clear success/failure indication with descriptive messages

Channel-Based Streaming

Streaming operations have been upgraded from IAsyncEnumerable to ChannelReader:

  • Better Performance: More efficient memory usage and throughput
  • Improved Backpressure: Built-in flow control mechanisms
  • Resource Management: Better cleanup and disposal patterns

🔄 Changes

Response Acknowledgment

  • Event Handlers: All stream-related events updated to expect ActionResult responses
  • Interface Updates: IJiroClient, IJiroHubServer, and JiroClientBase aligned with new pattern

Streaming Infrastructure

  • ChannelReader Integration: All streaming methods now use ChannelReader<T> instead of IAsyncEnumerable<T>
  • Performance Optimization: Reduced memory allocation and improved throughput
  • Enhanced Control: Better flow control and cancellation support

Enhanced Event Coverage

  • RemoveSessionRequested: Added event handler with proper RemoveSessionRequest parameter
  • UpdateSessionRequested: Added event handler returning ActionResult for acknowledgment
  • MachineInfoRequested: New event for machine information retrieval from clients
  • Complete Coverage: All hub client methods now have corresponding event implementations

Documentation Enhancements

  • XML Documentation: Added comprehensive parameter and return value documentation
  • ActionResult Details: Detailed documentation for the new response model
  • Usage Examples: Updated examples reflecting the new patterns

💻 Usage Examples

ActionResult Response Pattern implementation

// Event handler now returns ActionResult
LogsStreamRequested += async (request) =>
{
    try
    {
        await ProcessLogsStream(request);
        return new ActionResult 
        { 
            IsSuccess = true, 
            Message = "Logs stream processed successfully" 
        };
    }
    catch (Exception ex)
    {
        return new ActionResult 
        { 
            IsSuccess = false, 
            Message = "Failed to process logs stream",
            Errors = new[] { ex.Message }
        };
    }
};

Channel-Based Streaming implementation

// Using ChannelReader for streaming (fire-and-forget)
public async Task ReceiveLogsStreamAsync(string requestId, ChannelReader<LogEntry> stream)
{
    try
    {
        await foreach (var logEntry in stream.ReadAllAsync())
        {
            await ProcessLogEntry(logEntry);
        }
        
        logger.LogInformation("Stream {RequestId} processed successfully", requestId);
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Failed to process stream {RequestId}", requestId);
    }
}

Enhanced Event Handling

// Session management with proper request objects
RemoveSessionRequested += async (removeRequest) =>
{
    var result = await sessionManager.RemoveSessionAsync(removeRequest);
    return new ActionResult 
    { 
        IsSuccess = result.Success, 
        Message = result.Message 
    };
};

UpdateSessionRequested += async (updateRequest) =>
{
    var result = await sessionManager.UpdateSessionAsync(updateRequest);
    return new ActionResult 
    { 
        IsSuccess = result.Success, 
        Message = result.Message 
    };
};

// New machine information event
MachineInfoRequested += async (infoRequest) =>
{
    var machineInfo = await systemService.GetMachineInfoAsync(infoRequest);
    return new MachineInfoResponse 
    { 
        RequestId = infoRequest.RequestId,
        Data = machineInfo
    };
};

🚀 Deployment

Breaking Changes

  • Stream Parameters: Streaming methods now expect ChannelReader<T> instead of IAsyncEnumerable<T>
  • Event Returns: Stream request events now return Task<ActionResult> for acknowledgment
  • Session Events: RemoveSessionRequested now takes RemoveSessionRequest instead of string
  • New Events: Implementations must handle the new MachineInfoRequested event

Migration Guide

// Before v1.3.0
public event Func<GetLogsRequest, Task> LogsStreamRequested;
public event Func<string, Task<ActionResult>> RemoveSessionRequested;
public async Task ReceiveLogsStreamAsync(string requestId, IAsyncEnumerable<LogEntry> stream) { }

// After v1.3.0
public event Func<GetLogsRequest, Task<ActionResult>> LogsStreamRequested;
public event Func<RemoveSessionRequest, Task<ActionResult>> RemoveSessionRequested;
public event Func<MachineInfoRequest, Task<MachineInfoResponse>> MachineInfoRequested;
public async Task ReceiveLogsStreamAsync(string requestId, ChannelReader<LogEntry> stream) 
{
    // Process stream (fire-and-forget)
    await ProcessStream(requestId, stream);
}

🔮 Future Considerations

  • Distributed Tracing: ActionResult foundation enables future distributed tracing integration
  • Performance Monitoring: Response patterns facilitate operation performance tracking
  • Error Analytics: Structured error reporting enables better failure analysis
  • Flow Control: Channel-based streaming prepares for advanced flow control features

Note: This release introduces breaking changes to streaming interfaces. Please review the migration guide and update your event handlers to return ActionResult responses. The new channel-based streaming provides significant performance improvements and better resource management.