v1.7.1 (2025-11-17)#
このリリースは、DAQ(データ取得)機能におけるファイルI/Oバッファリングの問題を修正します。
stream_mode=True で実行時にデータが実時間でディスクに書き込まれず、プロセス終了時にまとめて書き込まれていた問題を解決しました。
✨ v1.7.1 での改善点#
このマイルストーンは、以下を実現します。
リアルタイムファイル出力:
stream_mode=Trueでデータがディスクに即座に書き込まれるように修正データ安全性向上: プロセスクラッシュ時のデータ喪失リスクを軽減
監視可能性:
tail -fなどでリアルタイムに計測データを確認できるように改善100%テスト互換性: すべての既存テストが引き続きパス
🐛 修正内容#
ファイルバッファリング問題の根本原因#
症状: DAQで CSV ファイルは生成されるが、実行中はデータが見えず、Ctrl-C で中断すると初めてデータが表示される
原因: Python の CSV writer がファイル I/O バッファを使用しており、stream_mode=True のコード パスで各イベント書き込み後に明示的なフラッシュがなかった
解決方法: save_events() メソッドの stream_mode=True パス内で各イベント書き込み後に f.flush() を追加
変更内容#
# src/haniwers/v1/daq/sampler.py (line 598)
elif self.stream_mode:
for event in self.stream_events(source):
writer.writerow(event.to_list())
f.flush() # ← この1行を追加: 各イベント後にバッファをフラッシュ
📊 影響範囲#
項目 |
詳細 |
|---|---|
修正ファイル |
|
変更行数 |
1行追加 |
新規機能 |
なし(既存機能の修正) |
後方互換性 |
100%維持 |
テスト影響 |
なし(すべてのテストがパス) |
✅ 動作検証#
テスト結果#
$ poetry run pytest tests/v1/unit/daq/sampler/ -v
================================ test session starts ================================
collected 13 items
tests/v1/unit/daq/sampler/test_init_type_hints.py::... PASSED [ 7%]
tests/v1/unit/daq/sampler/test_sampler.py::... PASSED [100%]
================================ 13 passed in 0.80s =================================
リアルタイム出力動作確認#
修正前(バッファリング):
$ tail -f output.csv
# (データなし、Ctrl-C で中断するまで待機)
修正後(リアルタイム):
$ tail -f output.csv
timestamp,ch1,ch2,ch3,ch4,ch5,ch6,ch7
2025-11-17T14h32m45s,100,200,150,175,210,190,220
2025-11-17T14h32m46s,105,198,152,176,212,189,222
# (リアルタイムでデータが表示される)
🔧 技術詳細#
Stream Mode の動作#
stream_mode パラメータは DAQ の 2つの動作モードを制御します:
モード |
動作 |
フラッシュ |
用途 |
|---|---|---|---|
|
即座書き込み |
各イベント後 |
DAQ(デフォルト) |
|
一括書き込み |
ファイル終了時 |
閾値スキャン |
パフォーマンス考慮#
小規模イベント率 (<1000 events/s): フラッシュのオーバーヘッドは無視できる
高頻度イベント (>1000 events/s): バッチフラッシュ(N個イベントごと)の検討余地あり
デフォルト動作: データ安全性を優先(パフォーマンスより重視)
📚 使用例#
CLI での実行(デフォルト)#
# stream_mode=true (デフォルト) で実行
haniwers-v1 daq --config daq.toml
# 別のターミナルでリアルタイム監視
tail -f sandbox/20251117/data_*.csv
プログラマティック利用#
from pathlib import Path
from haniwers.v1.daq.device import Device
from haniwers.v1.daq.sampler import Sampler
from haniwers.v1.config.model import DeviceConfig, SamplerConfig
# 設定
device_cfg = DeviceConfig(port="/dev/ttyUSB0", baudrate=115200)
sampler_cfg = SamplerConfig(
stream_mode=True, # リアルタイム書き込みを有効化
workspace=Path("./data"),
events_per_file=1000
)
# デバイス接続
device = Device(device_cfg)
device.connect()
# DAQ 実行(リアルタイムでファイルに書き込み)
sampler = Sampler(device, sampler_cfg)
sampler.run(mode="count_based", files=5)
device.disconnect()
🔄 マイグレーション#
重要: すべての既存 CLI コマンドとオプションが変わりません。追加アクションは不要です。
ユーザー向け#
変更なし。すべてのコマンドが同じまま動作します。
開発者向け#
カスタム Sampler インスタンスを使用している場合、特別な対応は不要です。
# v1.7.0 で動作したコード
sampler = Sampler(device, config)
sampler.run(mode="daq", files=5)
# v1.7.1 でも同じまま動作(リアルタイム出力で強化)
sampler = Sampler(device, config)
sampler.run(mode="daq", files=5)
🎓 学習ポイント#
課題と解決#
問題検出: ユーザー報告 → コード追跡 → 根本原因特定
最小修正: 1行追加で問題解決(不必要な複雑化を回避)
品質保証: 既存テストで後方互換性を確認
ベストプラクティス#
ストリーミングモード: ファイル I/O は明示的にフラッシュする
データ安全性: クラッシュ時の喪失リスクより重視
監視可能性: リアルタイムファイル出力でデバッグを容易に
📦 インストール#
pip install haniwers==1.7.1
または最新版:
pip install --upgrade haniwers
🔗 関連リンク#
リリース担当: Claude Code リリース日: 2025-11-17 バージョン: 1.7.1 (PATCH update) 実装期間: 1セッション (問題特定から修正・テスト完了)