ugs.more blocks until event arrives

main
Bel LaPointe 2024-12-15 11:05:39 -07:00
parent 0d44fd56ed
commit 39c9eae7ad
2 changed files with 33 additions and 22 deletions

View File

@ -6,12 +6,14 @@ import (
"fmt" "fmt"
"io" "io"
"log" "log"
"time"
) )
type UserGameServer struct { type UserGameServer struct {
ID string ID string
Session Session Session Session
games Games games Games
lastPoll time.Time
} }
func NewUserGameServer(ctx context.Context, session Session, games Games) (*UserGameServer, error) { func NewUserGameServer(ctx context.Context, session Session, games Games) (*UserGameServer, error) {
@ -29,6 +31,28 @@ func NewUserGameServer(ctx context.Context, session Session, games Games) (*User
}, nil }, nil
} }
func (ugs *UserGameServer) More(ctx context.Context) error {
defer func() {
ugs.lastPoll = time.Now()
}()
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Second * 1):
}
if events, err := ugs.games.GameEvents(ctx, ugs.ID, ugs.lastPoll); err != nil {
return err
} else if len(events) == 0 {
continue
}
return nil
}
}
func (ugs *UserGameServer) Listen(ctx context.Context, can context.CancelFunc, reader func(context.Context) ([]byte, error)) { func (ugs *UserGameServer) Listen(ctx context.Context, can context.CancelFunc, reader func(context.Context) ([]byte, error)) {
defer can() defer can()
if err := ugs.listen(ctx, reader); err != nil && ctx.Err() == nil { if err := ugs.listen(ctx, reader); err != nil && ctx.Err() == nil {

View File

@ -9,7 +9,6 @@ import (
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/coder/websocket" "github.com/coder/websocket"
) )
@ -25,35 +24,21 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
} }
defer c.CloseNow() defer c.CloseNow()
gameServer, err := NewUserGameServer(r.Context(), s.Session(r.Context()), s.games) ugs, err := NewUserGameServer(r.Context(), s.Session(r.Context()), s.games)
if err != nil { if err != nil {
return err return err
} }
game := gameServer.ID game := ugs.ID
ctx, can := context.WithCancel(r.Context()) ctx, can := context.WithCancel(r.Context())
defer can() defer can()
go gameServer.Listen(ctx, can, func(ctx context.Context) ([]byte, error) { go ugs.Listen(ctx, can, func(ctx context.Context) ([]byte, error) {
_, b, err := c.Read(ctx) _, b, err := c.Read(ctx)
return b, err return b, err
}) })
var last time.Time for ugs.More(ctx) == nil {
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Second * 1):
}
if events, err := s.games.GameEvents(ctx, game, last); err != nil {
return err
} else if len(events) == 0 {
continue
}
last = time.Now()
gameState, err := s.games.GameState(ctx, game) gameState, err := s.games.GameState(ctx, game)
if err != nil { if err != nil {
return err return err
@ -162,4 +147,6 @@ func (s *S) serveWS(w http.ResponseWriter, r *http.Request) error {
return err return err
} }
} }
return ctx.Err()
} }