v1.10.0 - Sampler Orchestration Layer Simplification (2025-12-29)#
What Changed?#
This release completes Phase 3 of the Sampler modularization by simplifying the _base.py orchestration layer.
The 1,591-line monolithic class has been reduced to ~350 lines by fully delegating to specialized modules (EventReader, EventWriter, helpers, and iterators).
The Sampler class now focuses purely on orchestration and coordination via composition.
What’s New#
Orchestration Layer Simplification (_base.py)#
What it does: The Sampler class now acts as a pure orchestration layer that:
Creates and coordinates EventReader and EventWriter instances
Manages configuration initialization and workspace setup
Provides public API methods that delegate to specialized modules
Maintains all backward compatibility through composition pattern
Architecture:
Sampler (orchestration)
├── EventReader (_reader.py) - reads events from device
├── EventWriter (_writer.py) - writes CSV files
├── Helpers (_helpers.py) - type conversion and utilities
└── Iterators (_iterators.py) - acquisition loop control
Code example:
# Sampler now delegates to specialized modules
def acquire_by_count(self, file_path: Path, event_count: int):
"""Delegates to EventWriter.acquire_by_count()"""
self.writer.acquire_by_count(file_path, event_count)
def acquire_by_time(self, file_path: Path, duration: float, sleep_interval: float):
"""Delegates to EventWriter.acquire_by_time()"""
self.writer.acquire_by_time(file_path, duration, sleep_interval)
def run(self, mode: str = None, files: int = None):
"""Orchestrates multi-file acquisition with proper delegation"""
mode = mode or self.mode or "daq"
files = files or self.files
for fid in range(files):
file_path = self.timestamped_filename(fid, self.mac_address)
if mode == "daq":
self.acquire_by_count(file_path, self.events)
elif mode == "scan":
self.acquire_by_time(file_path, self.duration, sleep_interval=0.1)
Installation#
Quick Start#
# Get the release
git checkout v1.10.0
# Setup
task env:setup
# Run CLI
haniwers-v1 --help
What’s Different from the Last Version?#
✅ Added#
Orchestration pattern documentation in
_base.pydocstringsClear delegation of responsibilities across modules
🔧 Changed#
_base.py simplified: 1,591 lines → ~350 lines (78% reduction)
All reading logic delegated to EventReader
All writing logic delegated to EventWriter
Test focus shifted to orchestration and delegation behavior
Low-level method tests moved to appropriate module test files
🐛 Fixed#
No bug fixes in this release
Is It Safe to Upgrade?#
Backward Compatible: ✅ Yes
All existing imports and APIs continue to work without modification:
from haniwers.v1.daq.sampler import Samplerworks exactly as beforesampler.acquire_by_count(),sampler.acquire_by_time(),sampler.run()work identicallyAll 133 DAQ unit tests continue to pass
File I/O behavior unchanged (streaming and buffered modes both supported)
MAC address filename generation unchanged
Tests Passed#
✅ Builds without errors
✅ All 133 unit tests passing (DAQ module)
✅ Sampler functionality tests passing (10 tests covering orchestration)
✅ MAC address tests passing (3 essential tests)
✅ Reader module functionality verified
✅ Writer module functionality verified
✅ Helper functions verified
✅ Iterator functions verified
✅ Pre-commit hooks passing (ruff format, YAML, etc.)
Release Details#
Date: 2025-12-29
Version: v1.10.0
Files Changed: 2 (_base.py, test_sampler.py)
Lines Removed: 1,209 (deletion of redundant code in _base.py)
Commits:
3001845: refactor(daq/sampler): simplify _base.py to pure orchestration layer
8536b84: bump: version 1.9.9 → 1.10.0
Architecture Achievements#
Phase 3 completes the Single Responsibility Principle (SRP) implementation:
Module |
Lines |
Responsibility |
Status |
|---|---|---|---|
_helpers.py |
217 |
Type conversion, progress |
✓ Phase 2.1 |
_iterators.py |
162 |
Count/time-based iteration |
✓ Phase 2.1 |
_reader.py |
269 |
Event reading from device |
✓ Phase 2.2 |
_writer.py |
370 |
Event writing to CSV |
✓ Phase 2.2 |
_base.py |
350 |
Orchestration layer |
✓ Phase 3 |
Previous state: 1,591 lines in single file Current state: 1,368 lines across 5 specialized modules Benefit: Each module independently testable, clear responsibility boundaries
Next Steps#
Phase 4 (v1.11.0+ planned): Technical Debt Resolution#
Complete removal of deprecated models
Remove DaqConfig and ScanConfig models (deprecated since v1.5.0)
Final migration for users still using legacy models
Timeline: v1.11.0 scheduled for complete removal
TODO comment resolution
device.is_connected()method implementationcurve_fit stability improvements
Validation logic completion
Integration test stabilization
Fix flaky threshold scanning tests
Improve test fixture organization
v2 Migration Path#
This modularized v1 codebase provides:
Clean, reusable reader/writer/helper modules for v2
Clear orchestration patterns to follow
Foundation for subsystem integration (kazunoko/datemaki)
Stable v1 API for long-term maintenance
See project constitution for architectural principles guiding this refactoring.