systemdの再起動中、ソケットアクティベーションなら接続は拒否されず、待たされる

稼働中のデーモンをリクエストを落とさずに入れ替える手順書です。小さなTCPサーバーを本物のsystemdで動かして試しました。単純なrestartは毎回、接続の拒否かリセットを起こしました。SO_REUSEPORTで新旧を並べる方法は拒否ゼロでしたが、一部の回でリセットが出て、カーネルの設定でそれが消えました。ソケットアクティベーションはエラーなしでした。処理中リクエストのドレインとTimeoutStopSecの関係、新バージョンを確認して巻き戻すリリース切り替えも扱います。

2026年10月3日 | 17 min

サービスが起動した更新プロセスは、setsidしてもsystemdに殺される

自分自身を更新するデーモンが、更新用のヘルパーを起動してから自分のユニットを再起動すると、落とし穴があります。ヘルパーはサービスのcgroupの中で起動し、再起動時にsystemdがそのcgroupの中身を全部終了させるからです。使い捨てのsystemdで試すと、setsidしたヘルパーは最後のログ行を出す前に消え、KillMode=processでは生き残るものの次のインスタンスに紛れ込み、systemd-runなら独立したユニットとして最後まで動きました。証拠、直し方、試していないことを書きます。

2026年9月28日 | 12 min

Durable Object のアラームは、失敗しても6回再試行して終わる

Durable Object のアラームは1つだけで、少なくとも1回実行され、失敗するハンドラーはバックオフ付きで最大6回再試行されます。それが尽きると、オブジェクトを再び起こすものは何もありません。この3つに耐えるリース失効の台帳を、コードに注釈をつけて見ていきます。真実を持つ表、アラームを再設定するコンストラクター、2回実行されても困らない副作用です。ローカルの workerd で動かし、制限は Cloudflare の文書から引用しています。

2026年9月24日 | 11 min

APNs が保持する通知は1アプリ1件だけなので、プッシュはヒントとして設計する

端末がオフラインのとき、アプリが終了されたとき、送信が多すぎるときにプッシュがどうなるかを、AppleとGoogleは文書で説明しています。通知は置き換えられ、捨てられ、順序が入れ替わり、遅れます。文書に書かれた失敗モードの表と、ペイロードを適用するクライアントが収束せず、カーソルから取得するクライアントが収束することを示す小さなシミュレーションを紹介します。

2026年9月19日 | 10 min

バックグラウンドから戻ったWebSocketのOPENは、確かめるまで主張にすぎない

AppleとAndroidの公式ドキュメントには、バックグラウンドのアプリは一時停止され、ネットワークが止められ、既存の接続が閉じられうると書かれています。つまり、フォアグラウンドに戻ったときの readyState === OPEN は、最後に処理したイベントの記憶にすぎません。この記事では、その記述から「確認する、作り直す、取りこぼしを取り戻す」という小さなルーチンを導き、Linux上の凍結プロセスという代役で動かします。実機では試していない点も、はっきり書きます。

2026年9月12日 | 14 min

HTTP/2で1本がタイムアウトしたら、閉じるのは接続ではなくストリーム

たくさんのリクエストを同時に流している1本の接続で、1つのリクエストの期限が来たとき、接続ごと閉じるべきか、そのリクエストだけを閉じるべきか。小さなNodeの実験では、HTTP/2のセッションを閉じると無関係な2本が失敗し、ストリームだけをキャンセルすると同じTCP接続のまま2本とも完了しました。ただし、TCPの1パケットの遅れは接続上の全ストリームを止めます。その場合に接続の生死を確かめる方法として、PINGを使った確認も試します。

2026年9月8日 | 17 min

カーソル・有限ログ・スナップショットで、再接続したイベントストリームを再開する

再接続したクライアントが、状態を取りこぼさず、重複せず、履歴を読み直さずに追いつく方法を、「全部読み直す」から「上限つきのログとスナップショットのフォールバック」まで、版0から版4まで段階的に組み立てます。ブラウザの EventSource が再接続時と non-200 応答のときに実際に何をするか、スナップショットの順序のバグ、決定木も扱います。

2026年9月4日 | 15 min

リトライで二重に処理される。「ちょうど1回」は作れない

リクエストがタイムアウトしたとき、クライアントはリクエストが失われたのか、確認応答だけが失われたのかを区別できません。だから「ちょうど1回」の配送は作れず、実際にできるのは「少なくとも1回の配送」と「重複を除く受け手」の組み合わせです。不安定なネットワークでの実験、正しく見えて89件を重複させるバグ、原子的な重複排除ストア、ジッターのシミュレーションで確かめます。

2026年8月28日 | 15 min

死んだTCPの相手に気づくまで、書く側は約15分、読むだけの側は無期限

TCP は、相手がいなくなったことを教えてくれません。読み取り側は永遠にブロックし、書き込み側は十数分も再送を続け、SO_KEEPALIVE は未確認のデータがあるあいだ何もしません。この記事では、root 不要の1ファイルの Linux 実験環境を作り、何もしない、keepalive、TCP_USER_TIMEOUT、アプリケーションのハートビートという順に仕組みを積み上げて、気づくまでの時間を測ります。NAT と RFC がどこに関わるかも整理します。

2026年8月23日 | 19 min

pingなしの生存確認とアイドル時のスリープ

一定間隔の keepalive は、接続が忙しいときでも双方向に1メッセージずつ使います。受信したフレームをすべて生存の証拠として扱い、静かな接続だけを確認し、既存のハートビートで待機中のホストに切断してよいかを伝えれば、その大半を減らせます。代償は、上限のある復帰の遅延です。

2026年8月18日 | 9 min