Job-status WebSocket events appear to be broadcast to every connected client
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 37
- Fork
- 76
- Merge trung bình
- 3 ngày 7 giờ
- Pull request đã merge (30 ngày)
- 2
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của CCExtractor/ccsync
-
GET /tasks is not serialized and Taskwarrior data isolation may race through shared /root/.taskĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
CCExtractor/ccsync#471 · 3 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
CCExtractor/ccsync#440 · 3 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
CCExtractor/ccsync#433 · 2 bình luận ·
-
enhancement frontend
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 48/100
CCExtractor/ccsync#425 ·
-
backend complex enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
CCExtractor/ccsync#367 · 2 bình luận ·
Tất cả issue của CCExtractor/ccsync
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
solana-foundation/solana-com#2245 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
`document.cookie` with `max-age=0` does not delete the cookieCó thể đã có người làm @BartInTheField đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
capricorn86/happy-dom#2460 ·
Maintainer thường phản hồi trong vòng 2 ngày