mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-12 16:43:29 +00:00
Backport of https://github.com/go-gitea/gitea/pull/38847, which fixes the stopwatch push flake in https://github.com/go-gitea/gitea/actions/runs/43200377380/job/131122930118. The stopwatch e2e test keeps its v28 flow, since main reworked it in a separate change. Assisted-by: Claude Code:claude-opus-5-5
72 lines
1.8 KiB
Go
72 lines
1.8 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package websocket
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
|
|
user_model "gitea.dev/models/user"
|
|
"gitea.dev/modules/json"
|
|
"gitea.dev/modules/setting"
|
|
notify_service "gitea.dev/services/notify"
|
|
"gitea.dev/services/pubsub"
|
|
)
|
|
|
|
type wsNotifier struct {
|
|
notify_service.NullNotifier
|
|
}
|
|
|
|
var _ notify_service.Notifier = &wsNotifier{}
|
|
|
|
func Init() error {
|
|
// the pubsub broker must be ready before the notifier starts publishing to it
|
|
if err := pubsub.Init(); err != nil {
|
|
return err
|
|
}
|
|
notify_service.RegisterNotifier(&wsNotifier{})
|
|
return nil
|
|
}
|
|
|
|
func UserData(ctx context.Context, user *user_model.User) (data [][]byte) {
|
|
for _, event := range [][]byte{notificationCountEvent(ctx, user.ID), stopwatchesEvent(ctx, user)} {
|
|
if event != nil {
|
|
data = append(data, event)
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
func EventForSession(brokerPayload []byte, sessionID string) []byte {
|
|
target, eventData, _ := bytes.Cut(brokerPayload, []byte("\n"))
|
|
if len(target) > 0 && string(target) != sessionID {
|
|
return nil
|
|
}
|
|
return eventData
|
|
}
|
|
|
|
// makeEventMessage prefixes the client JSON with its target session, empty for all sessions.
|
|
func makeEventMessage(eventType, targetSession string, eventData any) []byte {
|
|
buf := bytes.NewBufferString(targetSession + "\n")
|
|
err := json.MarshalWriteRelaxed(buf, &struct {
|
|
EventType string `json:"eventType"`
|
|
EventData any `json:"eventData,omitzero"`
|
|
}{eventType, eventData})
|
|
if err != nil {
|
|
setting.PanicInDevOrTesting("websocket: marshal event: %v", err)
|
|
return nil
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func publishUserEvent(userID int64, build func() []byte) {
|
|
topic := pubsub.UserTopic(userID)
|
|
if !pubsub.DefaultBroker.HasTopicSubscribers(topic) {
|
|
return
|
|
}
|
|
if event := build(); event != nil {
|
|
pubsub.DefaultBroker.Publish(topic, event)
|
|
}
|
|
}
|