記事キューは、3つの別々のドラフトが調査・生成・検証・保存されている間、不透明なGeneratingスピナーを1つ表示していました。
それは技術的には正しいものの、実用的には役に立たないものでした。サーバーはインターフェースが示す以上の情報を把握していたため、私はスピナーをサーバー送信イベントで駆動されるライブ3スロットステッパーに置き換えました。
実際の作業をストリーミング
POST /api/articles/drafts/queue は現在、SSE経由で進捗をストリーミングします。各イベントは現在のスロットに対して意味のある状態を報告します:調査中、生成中、リンクの検証、または完了。
ダッシュボードはこれらのイベントを GenerationProgress を通じてレンダリングします。スピナーを眺めて何かが起きているかどうかを推測するのではなく、調査中にソース数が出現し、生成後にドラフトのタイトルが到着し、ドラフトが実際に存在したときにのみ完了が通知されるのを確認できます。
最後の詳細が重要です。slot_done は実際の draft_id を運び、正直なタイミングで発火します。永続化が完了する前に完了状態を表示するのは進捗報告ではありません。それは読み込みインジケーター付きの虚構です。
進捗は実際の作業に到達する必要があった
ルートにSSEを追加するのは簡単な部分でした。有用な進捗は生成パスのより深い場所から発信する必要がありました。
実際の段階が発生する backfill と generate_article_payload に progress_cb をスレッド化しました。これにより、イベントはタイマーや装飾的なパーセンテージで進捗を推定するルートではなく、実行されている作業に結びついたものになります。
73パーセント完了のような偽の主張はありません。記事生成はきれいな線形作業単位を提供しません。名前付きの段階と具体的な成果物の方がより正直です:ソースが見つかった、タイトルが生成された、リンクが検証された、ドラフトが永続化された。
失敗は完了した作業を保持すべき
キュー充填は現在、ドラフトを1スロットずつ挿入します。スロット3が失敗した場合、スロット1と2は永続化され表示されたままになります。
以前は、キュー充填を1つの不可分な操作として扱うことでインターフェースはシンプルになりましたが、有用な完了した作業を破棄したり、後続の失敗の背後に隠したりすることもありました。スロットごとの永続化により、部分的な成功が一級の地位を得ます。
エラーは関連するステッパースロット内に留まります。ユーザーは他のスロットの進捗と結果を失うことなく、どのドラフトが失敗したかを確認できます。これはキュー全体を1つの赤いバナーに折りたたむよりもはるかに優れた失敗モデルです。
互換性のトレードオフ
SSEはブラウザ体験を大幅に向上させますが、すべてのクライアントがストリームを期待するわけではありません。SSEを消費しないクライアントのためにJSONフォールバックを保持しました。
これにより2つのレスポンスパスを維持する必要があります。余分なサーフェスエリアですが、既存のすべてのクライアントにストリーミングを採用させることは、ダッシュボードの改善を不要な互換性の破壊に変えることになります。両方のクライアントが存在する間は、このトレードオフは価値があります。
違う方法でやるなら
コールバックをスタック全体にスレッド化する前に、進捗イベントスキーマを定義するでしょう。段階、ペイロードフィールド、エラー形状、完了セマンティクスが本当の契約です。そこから始めれば、特にスロットが完了する正確なタイミングについて、バックエンドとダッシュボードの収束がより速くなるでしょう。
より広い教訓はシンプルです:サーバーが何が起きているかを知っているなら、インターフェースは何かが起きていることだけを知っているふりをするべきではありません。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.