Job-status WebSocket events appear to be broadcast to every connected client
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 45/100
調査の方向性
Start with backend/main.go, backend/controllers/websocket.go, backend/controllers/job_queue.go, and frontend/src/components/HomePage.tsx to trace connection registration and job-status handling. Reproduce the suggested two-session flow if the local Docker/OAuth environment can be started, then confirm the intended ownership model with maintainers. Done means the intended behavior is decided and verified, with a two-connection regression test if scoping is required.
索引モデルが issue の本文から書いたものです。
説明
Summary
The frontend opens a job-status WebSocket at /ws?clientID=<uuid>, but the backend does not appear to read clientID (or any other user identifier) when registering the connection.
Authenticated sockets are stored in a process-wide clients map. JobStatusManager writes each JobStatus to every connection. JobStatus only contains a job name and a status string.
The home page treats incoming success events as belonging to the current user (toasts, and for most jobs a /tasks refetch).
The behavior is confirmed from the current source code, but has not yet been reproduced in two live authenticated sessions.
Current behavior (from source)
GET /wsis handled byAuthenticatedWebSocketHandler(backend/main.go).- After a valid session, the connection is stored as
clients[ws] = truewith no user/uuid key (backend/controllers/websocket.go). - The query string (
clientID) is not read in that handler. - Mutation handlers enqueue work on
GlobalJobQueue.AddJob/processJobsemitqueued,in-progress, andsuccessorfailureviaBroadcastJobStatus(backend/controllers/job_queue.go). JobStatusManagerranges overclientsandWriteJSONs the same payload to each socket.- Payload shape is only
{ "job": "...", "status": "..." }. HomePage.tsxconnects withws?clientID=${userInfo.uuid}and, onstatus === "success":- refetches tasks unless
job === "Edit Task"; - shows a success toast for
Add Task,Edit Task,Complete Task, andDelete Task.
- refetches tasks unless
If two users have /home open, the source implies User B would receive User A's job-status messages and could toast/refetch as if the job were B's.
Expected behavior
I am not assuming a specific design. Two reasonable options:
- Job-status events are only delivered to the user who queued the job (the unused
clientIDquery param suggests this may have been intended), or - Global broadcast is intentional (e.g. single-user / self-hosted assumption).
Please confirm which of these is intended.
Technical evidence
Backend
backend/main.go—mux.HandleFunc("/ws", controllers.AuthenticatedWebSocketHandler(store))backend/controllers/websocket.goJobStatus— fieldsJob,StatusonlyAuthenticatedWebSocketHandler— session check,Upgrade,clients[ws] = true; nor.URL.Query()/clientIDBroadcastJobStatus— send on the globalbroadcastchannelJobStatusManager—for client := range clients { client.WriteJSON(jobStatus) }
backend/controllers/job_queue.go—AddJob/processJobscallBroadcastJobStatuswithqueued/in-progress/success/failure- Example job name:
add_task.gousesName: "Add Task"
Frontend
frontend/src/components/HomePage.tsx—getWebSocketURL(\ws?clientID=${userInfo.uuid}`)andsocket.onmessage`frontend/src/components/utils/URLs.ts—getWebSocketURL(builds the URL; does not scope events)frontend/src/components/HomeComponents/Tasks/hooks.ts—fetchTaskwarriorTasks(GET/taskswith the current page's user headers)
A GET /tasks from that path calls FetchTasksFromTaskwarrior (including rm -rf /root/.task and task sync) on the backend. That is only relevant if B actually refetches because of A's event.
Suggested reproduction (not yet run here)
- Two browsers/profiles, two logged-in users, both on
/home. - DevTools → Network → WS on both; confirm URLs like
/ws?clientID=<A-uuid>and/ws?clientID=<B-uuid>. - User A adds a task.
- Compare WS frames on A and B.
- Check whether B shows
Task added successfully!and whether B issuesGET /taskswith B's session headers (do not log encryption secrets).
Predicted frames if fan-out matches the source:
{"job":"Add Task","status":"queued"}
{"job":"Add Task","status":"in-progress"}
{"job":"Add Task","status":"success"}
Runtime reproduction limitation
This was not reproduced with two live authenticated browser sessions. The local environment could not start the full Docker/OAuth stack (Docker engine not running, no backend/.env / frontend/.env).
Please treat the two-user UI outcome as unverified until someone captures those WS frames.
Questions for maintainers
- Should
/wsjob-status events be limited to the user who queued the job, or is broadcasting to every authenticated socket intentional? - If scoping is desired, should the unused
clientIDquery parameter be the key, or should the handler use the session UUID instead (so the client cannot pick another id)? - Should
JobStatusinclude a user/job owner field, or should routing stay entirely server-side?
Possible direction (not implemented)
If global broadcast is not intended:
- Associate each WebSocket with the session UUID at upgrade time (prefer session over the query string).
- Send
JobStatusonly to matching connections (and include the owner on theJobif needed). - Keep
HomePagetoasts/refetch only for events that belong to that user. - Add a test with two connections and different ids that a job for A is not written to B.
Happy to help with a two-session capture or a patch once the intended behavior is clear.
- 主要言語
- TypeScript
- スター
- 37
- フォーク
- 76
- 平均マージ
- 3日 7時間
- マージ済み PR(30日)
- 2
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
CCExtractor/ccsync のほかの issue
-
GET /tasks is not serialized and Taskwarrior data isolation may race through shared /root/.taskオープン
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
CCExtractor/ccsync#471 · コメント 3 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
CCExtractor/ccsync#440 · コメント 3 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
CCExtractor/ccsync#433 · コメント 2 件 ·
-
enhancement frontend
難易度 2/5 1〜3時間 初心者へのやさしさ 48/100
CCExtractor/ccsync#425 ·
-
backend complex enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
CCExtractor/ccsync#367 · コメント 2 件 ·
CCExtractor/ccsync の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
solana-foundation/solana-com#2245 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
`document.cookie` with `max-age=0` does not delete the cookie対応中かも @BartInTheField が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
capricorn86/happy-dom#2460 ·
メンテナーはふだん 2 日以内に返信