Summary
This branch refactors the diff_targets function in src/network_toolkit/api/diff.py to improve code organization, fix parallel execution behavior, and ensure proper handling of session pools vs. fresh connections.
Current Status: Work in Progress
The branch contains initial refactoring work that needs completion and testing.
Changes Made
1. Refactored diff_targets function structure
Before: Used functools.partial with a module-level _perform_device_diff function for parallel execution.
After: Moved _perform_device_diff inside diff_targets as a nested function (closure) to:
- Simplify access to
options and other local variables
- Avoid passing multiple parameters through
partial
- Improve code locality and readability
2. Improved parallel execution control
Added conditional parallel execution based on session pool availability:
if is_config or is_command:
if len(devices) > 1 and options.session_pool is None:
batched = execute_parallel(devices, _perform_device_diff)
results = [item for batch in batched for item in batch]
else:
for dev in devices:
results.extend(_perform_device_diff(dev))
Rationale: When a session pool is provided, sessions should be reused rather than creating parallel fresh connections. This avoids connection exhaustion and respects the pool's purpose.
3. Separated config vs command handling in device-to-device mode
Refactored the device-to-device comparison (2 devices, no baseline) to have separate code paths for:
- Config diffs (
/export compact)
- Command diffs (arbitrary
/ commands)
This improves clarity and allows for mode-specific label formatting.
4. Added helper functions
_save_current_artifact(): Closure-based wrapper for artifact saving
_is_missing_baseline_error(): Centralized error classification for missing baselines
5. Improved result sorting
Changed from sorting by device only to sorting by (device, subject) tuple for more consistent output ordering.
6. Tests for parallel execution
Added tests/api/test_diff_parallel.py with tests for:
- Parallel execution triggering and result sorting
- Device-to-device parallel comparison
TODO / Remaining Work
Related Files
src/network_toolkit/api/diff.py - Main refactoring
src/network_toolkit/api/execution.py - Parallel execution helper (order-preserving fix from main)
src/network_toolkit/api/state_diff.py - Heuristic diffing (from main)
src/network_toolkit/api/state_diff_patterns.py - Regex patterns for heuristic diffing (from main)
tests/api/test_diff_parallel.py - New parallel execution tests
Design Decisions
Why move _perform_device_diff inside the function?
The original design used functools.partial to bind options and sequence_manager to a module-level function. This had several issues:
- Required importing
partial
- Made the function signature complex
- Separated related code
The nested function approach is more Pythonic and keeps related code together.
Why conditionally skip parallel execution with session pools?
Session pools are designed for connection reuse across operations. Running parallel operations with a session pool could:
- Cause race conditions if the pool isn't thread-safe
- Defeat the purpose of pooling by overwhelming the pool
- Lead to connection exhaustion
When no session pool is provided, parallel execution creates independent connections which is safe and efficient.
🤖 Generated with Claude Code
Summary
This branch refactors the
diff_targetsfunction insrc/network_toolkit/api/diff.pyto improve code organization, fix parallel execution behavior, and ensure proper handling of session pools vs. fresh connections.Current Status: Work in Progress
The branch contains initial refactoring work that needs completion and testing.
Changes Made
1. Refactored
diff_targetsfunction structureBefore: Used
functools.partialwith a module-level_perform_device_difffunction for parallel execution.After: Moved
_perform_device_diffinsidediff_targetsas a nested function (closure) to:optionsand other local variablespartial2. Improved parallel execution control
Added conditional parallel execution based on session pool availability:
Rationale: When a session pool is provided, sessions should be reused rather than creating parallel fresh connections. This avoids connection exhaustion and respects the pool's purpose.
3. Separated config vs command handling in device-to-device mode
Refactored the device-to-device comparison (2 devices, no baseline) to have separate code paths for:
/export compact)/commands)This improves clarity and allows for mode-specific label formatting.
4. Added helper functions
_save_current_artifact(): Closure-based wrapper for artifact saving_is_missing_baseline_error(): Centralized error classification for missing baselines5. Improved result sorting
Changed from sorting by device only to sorting by
(device, subject)tuple for more consistent output ordering.6. Tests for parallel execution
Added
tests/api/test_diff_parallel.pywith tests for:TODO / Remaining Work
StateDifferheuristic diffing logic--heuristic/-H) integration works correctlyRelated Files
src/network_toolkit/api/diff.py- Main refactoringsrc/network_toolkit/api/execution.py- Parallel execution helper (order-preserving fix from main)src/network_toolkit/api/state_diff.py- Heuristic diffing (from main)src/network_toolkit/api/state_diff_patterns.py- Regex patterns for heuristic diffing (from main)tests/api/test_diff_parallel.py- New parallel execution testsDesign Decisions
Why move
_perform_device_diffinside the function?The original design used
functools.partialto bindoptionsandsequence_managerto a module-level function. This had several issues:partialThe nested function approach is more Pythonic and keeps related code together.
Why conditionally skip parallel execution with session pools?
Session pools are designed for connection reuse across operations. Running parallel operations with a session pool could:
When no session pool is provided, parallel execution creates independent connections which is safe and efficient.
🤖 Generated with Claude Code