feat: live module and jenkins pipeline to harbor deploy
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package live
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
bizlive "kra/internal/biz/live"
|
||||
)
|
||||
|
||||
type streamState struct {
|
||||
stream *bizlive.Stream
|
||||
users map[uint]struct{}
|
||||
}
|
||||
|
||||
type streamRepo struct {
|
||||
mu sync.RWMutex
|
||||
streams map[string]*streamState
|
||||
}
|
||||
|
||||
func NewStreamRepo() bizlive.StreamRepo {
|
||||
return &streamRepo{streams: make(map[string]*streamState)}
|
||||
}
|
||||
|
||||
func (r *streamRepo) Get(_ context.Context, streamID string) (*bizlive.Stream, error) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
state := r.streams[streamID]
|
||||
if state == nil {
|
||||
return &bizlive.Stream{StreamID: streamID, UpdatedAt: time.Now()}, nil
|
||||
}
|
||||
return clone(state.stream), nil
|
||||
}
|
||||
|
||||
func (r *streamRepo) List(_ context.Context) ([]*bizlive.Stream, error) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
items := make([]*bizlive.Stream, 0, len(r.streams))
|
||||
for _, state := range r.streams {
|
||||
if state.stream.PublisherOnline {
|
||||
items = append(items, clone(state.stream))
|
||||
}
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool { return items[i].StreamID < items[j].StreamID })
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *streamRepo) RegisterPublisher(_ context.Context, streamID string, userID uint) (*bizlive.Stream, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
state := r.streams[streamID]
|
||||
if state == nil {
|
||||
if len(r.streams) >= bizlive.MaxStreams {
|
||||
return nil, bizlive.ErrMaxStreams
|
||||
}
|
||||
state = &streamState{stream: &bizlive.Stream{StreamID: streamID}, users: make(map[uint]struct{})}
|
||||
r.streams[streamID] = state
|
||||
}
|
||||
if state.stream.PublisherOnline {
|
||||
return nil, bizlive.ErrPublisherExists
|
||||
}
|
||||
state.stream.PublisherID = userID
|
||||
state.stream.PublisherOnline = true
|
||||
state.stream.UpdatedAt = time.Now()
|
||||
return clone(state.stream), nil
|
||||
}
|
||||
|
||||
func (r *streamRepo) UnregisterPublisher(_ context.Context, streamID string, userID uint) error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
state := r.streams[streamID]
|
||||
if state == nil || !state.stream.PublisherOnline || state.stream.PublisherID != userID {
|
||||
return bizlive.ErrPublisherNotFound
|
||||
}
|
||||
state.stream.PublisherID = 0
|
||||
state.stream.PublisherOnline = false
|
||||
state.stream.UpdatedAt = time.Now()
|
||||
if len(state.users) == 0 {
|
||||
delete(r.streams, streamID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *streamRepo) RegisterSubscriber(_ context.Context, streamID string, userID uint) (*bizlive.Stream, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
state := r.streams[streamID]
|
||||
if state == nil {
|
||||
if len(r.streams) >= bizlive.MaxStreams {
|
||||
return nil, bizlive.ErrMaxStreams
|
||||
}
|
||||
state = &streamState{stream: &bizlive.Stream{StreamID: streamID}, users: make(map[uint]struct{})}
|
||||
r.streams[streamID] = state
|
||||
}
|
||||
if _, exists := state.users[userID]; exists {
|
||||
return nil, bizlive.ErrSubscriberExists
|
||||
}
|
||||
state.users[userID] = struct{}{}
|
||||
state.stream.SubscriberCount = len(state.users)
|
||||
state.stream.UpdatedAt = time.Now()
|
||||
return clone(state.stream), nil
|
||||
}
|
||||
|
||||
func (r *streamRepo) UnregisterSubscriber(_ context.Context, streamID string, userID uint) error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
state := r.streams[streamID]
|
||||
if state == nil {
|
||||
return bizlive.ErrSubscriberNotFound
|
||||
}
|
||||
if _, exists := state.users[userID]; !exists {
|
||||
return bizlive.ErrSubscriberNotFound
|
||||
}
|
||||
delete(state.users, userID)
|
||||
state.stream.SubscriberCount = len(state.users)
|
||||
state.stream.UpdatedAt = time.Now()
|
||||
if !state.stream.PublisherOnline && len(state.users) == 0 {
|
||||
delete(r.streams, streamID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func clone(stream *bizlive.Stream) *bizlive.Stream {
|
||||
if stream == nil {
|
||||
return nil
|
||||
}
|
||||
value := *stream
|
||||
return &value
|
||||
}
|
||||
Reference in New Issue
Block a user