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)
|
||
}
|