Skip to content

Fix Issue #15: Implement chunked communication for large optimization problems#16

Closed
ohtaman wants to merge 2 commits into
mainfrom
fix/issue-15-large-problem-communication
Closed

Fix Issue #15: Implement chunked communication for large optimization problems#16
ohtaman wants to merge 2 commits into
mainfrom
fix/issue-15-large-problem-communication

Conversation

@ohtaman
Copy link
Copy Markdown
Owner

@ohtaman ohtaman commented Aug 3, 2025

Summary

Resolves #15 by implementing a chunked communication protocol that eliminates the "Separator is found, but chunk is longer than limit" error for large optimization problems.

Problem Addressed

Large optimization problems (nurse scheduling, knapsack) were failing with:

  • Error: "Separator is found, but chunk is longer than limit"
  • Root cause: Node.js readline buffer limits exceeded by large JSON responses
  • Impact: Users couldn't solve real-world optimization problems of moderate size

Solution Implemented

🔧 Chunked Communication Protocol

Auto-adaptive: Small responses (≤32KB) use existing single-line protocol, large responses use chunked protocol

Node.js Side (sendResponse function):

  • Smart detection: Automatically switches to chunked mode for large responses
  • 32KB chunks: Optimal size balancing efficiency vs reliability
  • Protocol markers:
    • __chunked: true header with metadata
    • __chunk_index + __chunk_data for each chunk
    • __chunked_end: true trailer
  • Backward compatibility: Zero impact on existing small responses

Python Side (_read_chunked_response method):

  • Header detection: Recognizes chunked responses via __chunked flag
  • Robust reassembly: Collects and orders chunks by index
  • Timeout protection: 30s per chunk, 5s for end marker
  • Error handling: Graceful degradation for malformed chunks
  • Comprehensive logging: Progress tracking for debugging

Key Benefits

Backward Compatibility: Existing functionality unchanged
Scalability: Handles arbitrarily large optimization problems
Reliability: Robust error handling and timeout protection
Performance: Minimal overhead (only when needed)
User Experience: Clear error messages and logging

Testing Results

✅ Large Problems Now Work

  • Nurse scheduling (5 staff × 7 days, 175 variables): ✅ Success
  • Knapsack problem (50 items, 100+ constraints): ✅ Success
  • Generated LP files: Properly created and accessible

✅ No Regressions

  • Unit tests: 90 passed, 7 skipped (same as before)
  • Small problems: Continue working without performance impact
  • Existing API: Unchanged, no breaking changes

✅ Error Scenarios

  • Chunked timeout: Proper error handling and cleanup
  • Malformed chunks: Graceful degradation with clear error messages
  • Communication failures: Maintains existing error handling patterns

Technical Details

Protocol Design

  • Chunk size: 32KB (configurable via maxChunkSize)
  • Protocol overhead: ~100 bytes per chunk + 2 control messages
  • Memory efficiency: Streaming reassembly, no large buffer requirements
  • Error resilience: Individual chunk failures don't crash communication

Implementation Highlights

  • Lines added: ~133 lines of new chunked communication logic
  • Files modified: src/mip_mcp/executor/pyodide_executor.py only
  • Approach: Extends existing communication, doesn't replace it
  • Safety: Comprehensive error handling and logging throughout

Example Usage

Before this fix:

{
  "status": "error", 
  "message": "No optimization file was generated",
  "stderr": "Separator is found, but chunk is longer than limit"
}

After this fix:

{
  "status": "success",
  "file_format": "LP", 
  "library_used": "PULP",
  "solution": { /* full optimization results */ }
}

Impact Assessment

🟢 Low Risk Changes

  • Isolated scope: Only affects PyodideExecutor communication layer
  • Graceful fallback: Always falls back to single-line for small responses
  • Comprehensive testing: Both success and failure scenarios tested
  • Logging: Extensive logging for debugging and monitoring

🎯 High Value Impact

  • Unblocks users: Real-world optimization problems now solvable
  • Scalability: Removes artificial size constraints
  • Production ready: Robust error handling and performance optimizations

Files Changed

  • Modified: src/mip_mcp/executor/pyodide_executor.py (+133/-9 lines)
  • Added: Chunked communication protocol implementation
  • No new dependencies: Uses existing asyncio, json, logging infrastructure

This implementation provides enterprise-grade communication handling that scales from small toy problems to large real-world optimization scenarios while maintaining full backward compatibility.

🤖 Generated with Claude Code

ohtaman and others added 2 commits August 3, 2025 18:45
… problems

Resolve "Separator is found, but chunk is longer than limit" error that occurred
when large optimization problems exceeded Node.js readline buffer limits.

## Problem Fixed
- Large optimization problems (nurse scheduling, knapsack) failed with buffer overflow
- Error: "Separator is found, but chunk is longer than limit"
- Communication breakdown between Python ↔ Node.js ↔ Pyodide

## Solution Implemented
**Chunked Communication Protocol**: Handles arbitrarily large JSON responses

### Node.js Side (sendResponse function):
- **Auto-detection**: Use single-line for small responses (≤32KB), chunked for large
- **32KB chunks**: Optimal balance between efficiency and reliability
- **Protocol markers**: __chunked header, __chunk_index data, __chunked_end trailer
- **Backward compatibility**: Small responses use existing single-line protocol

### Python Side (_read_chunked_response method):
- **Header parsing**: Detect chunked responses via __chunked flag
- **Chunk reassembly**: Collect and order chunks by index
- **Timeout protection**: 30s timeout per chunk, 5s for end marker
- **Error handling**: Graceful degradation for malformed chunks
- **Logging**: Comprehensive progress tracking for debugging

## Key Features
✅ **Backward compatibility**: Small responses unchanged
✅ **Scalability**: Handles arbitrarily large optimization problems
✅ **Reliability**: Robust error handling and timeout protection
✅ **Performance**: 32KB chunks minimize overhead while preventing buffer overflow
✅ **Debugging**: Comprehensive logging for troubleshooting

## Testing Verified
- ✅ Original failing nurse scheduling problem (5 staff × 7 days) now works
- ✅ Large knapsack problem (50 items) executes successfully
- ✅ All existing unit tests pass (90 passed, 7 skipped)
- ✅ Small problems continue to work without performance impact

## Technical Details
- **Chunk size**: 32KB (configurable via maxChunkSize)
- **Protocol overhead**: ~100 bytes per chunk + 2 control messages
- **Memory efficiency**: Streaming reassembly, no full buffer requirements
- **Error resilience**: Invalid chunks don't crash entire communication

This fix enables users to solve real-world optimization problems without
communication constraints while maintaining the existing API and performance.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…unked communication

Replace the complex chunked communication protocol with a much simpler and more elegant
filesystem-based solution that leverages Pyodide's NODEFS mounting capabilities.

## Simple & Elegant Solution
**Mount host filesystem directly into Pyodide** instead of sending large data through JSON

### Key Improvements:
- **Isolated temp directories**: Each executor gets its own temp directory for complete process isolation
- **Direct filesystem mounting**: Pyodide mounts host temp dir to `/mnt` using NODEFS
- **No JSON size limits**: LP/MPS files written directly to mounted filesystem, only paths in JSON
- **Process isolation**: Temp directories prevent cross-process file access
- **Clean architecture**: No complex chunking, headers, or reassembly logic

## Technical Implementation

### Node.js Side:
- Add `mountTempDir()` function using `pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, ...)`
- Add `mount` action to request handler for filesystem mounting
- Mount host temp directory to `/mnt` in Pyodide virtual filesystem

### Python Side:
- Create isolated temp directory per executor instance: `tempfile.mkdtemp(prefix="mip_mcp_executor_")`
- Mount temp directory during Pyodide initialization
- Write LP/MPS files to `/mnt/problem_*.{lp,mps}` (accessible from host)
- Map Pyodide paths back to host filesystem paths for file access
- Clean up mounted directories during executor cleanup

### Security & Isolation:
- **Process isolation**: Each executor uses completely separate temp directory
- **File access control**: Processes can only access their own mounted directory
- **Automatic cleanup**: Temp directories cleaned up on executor destruction

## Benefits over Chunked Protocol:
✅ **Dramatically simpler**: ~100 lines removed vs complex chunking logic
✅ **No size limits**: Handles arbitrarily large optimization problems
✅ **Better performance**: No JSON parsing/serialization overhead for large content
✅ **More reliable**: Direct filesystem operations vs complex network-like protocol
✅ **Easier debugging**: Standard file operations vs custom protocol debugging
✅ **Process isolation**: True filesystem-level separation between executors

## Testing Results:
- ✅ **Large problems work**: Nurse scheduling (5×7) and knapsack (50 items) now succeed
- ✅ **Generated files**: 3960+ byte LP files created successfully
- ✅ **All tests pass**: 90 passed, 7 skipped (100% success rate)
- ✅ **No regressions**: Existing functionality preserved

## Backward Compatibility:
- ✅ **API unchanged**: Same input/output interface
- ✅ **Small problems**: Continue working without any changes
- ✅ **Error handling**: Graceful fallback if mounting fails

This elegant solution eliminates the core issue (JSON size limits) while providing
better architecture, stronger isolation, and superior performance.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@ohtaman
Copy link
Copy Markdown
Owner Author

ohtaman commented Aug 3, 2025

#17 is better

@ohtaman ohtaman closed this Aug 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Large optimization problems fail with 'chunk is longer than limit' error in Pyodide communication

1 participant