generated from PenaSide/GolangTemplate
75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
|
package sse
|
|||
|
|
|||
|
import (
|
|||
|
"container/ring"
|
|||
|
"encoding/json"
|
|||
|
"time"
|
|||
|
|
|||
|
"github.com/google/uuid"
|
|||
|
)
|
|||
|
|
|||
|
const (
|
|||
|
RedisKeySSEEvents = "sse_events"
|
|||
|
)
|
|||
|
|
|||
|
type SSEEvent struct {
|
|||
|
UserID string
|
|||
|
EventType string
|
|||
|
Data json.RawMessage
|
|||
|
Timestamp time.Time
|
|||
|
}
|
|||
|
|
|||
|
type SSEConnection struct {
|
|||
|
ID string
|
|||
|
UserID string
|
|||
|
DeviceID string
|
|||
|
Channel chan SSEEvent
|
|||
|
}
|
|||
|
|
|||
|
func NewSSEConnection(userID, deviceID string) *SSEConnection {
|
|||
|
return &SSEConnection{
|
|||
|
ID: uuid.New().String(),
|
|||
|
UserID: userID,
|
|||
|
DeviceID: deviceID,
|
|||
|
Channel: make(chan SSEEvent, 100),
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// todo Миша: прост довольно много мест, где можно ошибиться.
|
|||
|
// например я вот вижу вариант, что нам в мэпе нужно копировать не deep, а чисто саму мэпу.
|
|||
|
//пусть ключи указывают на те же значения, это не страшно. но я же могу в этом вопросе сильно ошибиться.
|
|||
|
//мало ли, вдруг переприсваивание мэпы по факту сохранит ссылку на массив бакетов?
|
|||
|
//ну т.е. если мы присвоим куда то уже существующую мэпу, мы будем редактировать изначальную
|
|||
|
//и нужен какой то метод и глубокого и неглубокого копирования одновременно. копирование на пол-шишечки
|
|||
|
|
|||
|
type SSEConnectionMap map[string][]*SSEConnection
|
|||
|
|
|||
|
type SSEConnectionRingBuffer struct {
|
|||
|
ring *ring.Ring
|
|||
|
}
|
|||
|
|
|||
|
func NewSSEConnectionRingBuffer(size int) *SSEConnectionRingBuffer {
|
|||
|
return &SSEConnectionRingBuffer{
|
|||
|
ring: ring.New(size),
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (r *SSEConnectionRingBuffer) GetCurrent() SSEConnectionMap {
|
|||
|
if r.ring.Value == nil {
|
|||
|
return make(SSEConnectionMap)
|
|||
|
}
|
|||
|
return r.ring.Value.(SSEConnectionMap)
|
|||
|
}
|
|||
|
|
|||
|
func (r *SSEConnectionRingBuffer) Rotate() {
|
|||
|
r.ring = r.ring.Next()
|
|||
|
}
|
|||
|
|
|||
|
func (r *SSEConnectionRingBuffer) GetNext() SSEConnectionMap {
|
|||
|
next := r.ring.Next()
|
|||
|
if next.Value == nil {
|
|||
|
next.Value = make(SSEConnectionMap)
|
|||
|
}
|
|||
|
return next.Value.(SSEConnectionMap)
|
|||
|
}
|