ポーリング
Polling
システムが外部機器や別プログラムに対して、「新しいデータはある?」「処理は終わった?」と一定間隔で定期的に問い合わせを行い、状態の変化や更新を監視する通信方式のこと。
🐾 猫で例えると?
給餌器の前で待つアメショ。ここで、少し待ってはお皿をのぞき、「もうご飯は出たかな」と確かめる動きを繰り返すと想像してみましょう。自分から一定間隔で確認に行くのがポーリングです。単にじっと待つことや、機械のほうから「出たよ」と知らせてもらうこととは違います。Webでも、処理が終わったかを数秒おきに問い合わせる場面で使われます。
💻 アプリ・Web開発における「ポーリング」とは?
ポーリングは、通信ネットワークやプログラム間で状態を確認するための非常に古典的でシンプルな手法です。例えば、ブラウザ(クライアント)がサーバーに対して、「新しいメッセージは届いている?」「ファイルのアップロード処理は終わった?」と、10秒に1回などの間隔で自動的にAjaxリクエストを送信するような仕組みがこれにあたります。
サーバー側からクライアントに直接「終わったよ!」と知らせる仕組みを実装するのが技術的に難しい場合や、古いシステムと連携する場合に、実装が簡単であるという理由で現在でも広く使われています。
⚠️ ポーリングの仕組みと注意点
ポーリングの最大のメリットは「実装がとにかく簡単」であることです。定期的にタイマーを回してAPIを叩くだけで実現できます。しかし、その一方で「無駄が多い」という大きなデメリットを抱えているのが特徴です。
無駄なリクエストによるサーバーへの負荷(空振り)
ポーリングでは、新しいデータがなくても設定された間隔で必ず問い合わせが発生します。
// ブラウザ用。APIが { isCompleted: boolean } を返す前提
// 終了条件と試行上限を持ち、前の要求が終わってから次を予約する
async function checkStatus(attempt = 0) {
try {
const response = await fetch("/api/job-status");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
if (data.isCompleted) {
console.log("完了しました");
return;
}
if (attempt >= 29) {
console.log("確認を終了しました。必要なら手動で再確認してください");
return;
}
setTimeout(() => checkStatus(attempt + 1), 10000);
} catch (error) {
console.error("状態を確認できませんでした", error);
}
}
checkStatus(); 一定間隔の setInterval では、応答が遅いと前の問い合わせが終わる前に次が始まることがあります。この例は応答後に次を予約するため、要求が重なりません。実サービスでは要求自体のタイムアウトや、画面を離れたときの中止も設計します。
🛠️ ポーリングを賢く使うためのポイント
現場でポーリングを採用する場合は、システムに過剰な負荷をかけないような工夫が必要です。
- 適切な間隔を設定する: 短すぎる間隔はサーバーへの過度な負荷に繋がります。アメショのおやつへの凄まじい圧のようにならないよう、業務要件に合わせた無理のない間隔に設定しましょう。
- ロングポーリングを検討する: 通常のポーリングの進化版として、サーバー側で新しいデータが発生するまでレスポンスを保留する手法もあります。これにより空振りの回数を減らすことができます。
- 通知方式を要件で選ぶ: 更新頻度が低く数秒の遅れを許容するなら、ポーリングは扱いやすい選択です。即時性が必要ならSSEやWebSocketなども比較し、切断・再接続や運用コストを含めて決めます。
ご飯の機械を何度も確かめるアメショのように、ポーリングは繰り返し状態を問い合わせます。間隔を短くすると変化に早く気づけますが、問い合わせも増えます。どれくらいの遅れまで許せるかを決めてから、間隔や別の通知方法を選びましょう。