1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-02 16:08:31 +00:00

Let's start caching some of the backlog data on the server

This commit is contained in:
Kane York 2015-10-26 10:07:15 -07:00
parent 8918b9ac3a
commit ae1306387e
4 changed files with 214 additions and 7 deletions

View file

@ -74,14 +74,16 @@ func HBackendPublishRequest(w http.ResponseWriter, r *http.Request) {
cmd := formData.Get("cmd")
json := formData.Get("args")
chat := formData.Get("chat")
watchChannel := formData.Get("channel")
channel := formData.Get("channel")
scope := formData.Get("scope")
cm := ClientMessage{MessageID: -1, Command: Command(cmd), origArguments: json}
var count int
if chat != "" {
count = PublishToChat(chat, cm)
} else if watchChannel != "" {
count = PublishToWatchers(watchChannel, cm)
if scope == "chat" {
count = PublishToChat(channel, cm)
} else if scope == "channel" {
count = PublishToWatchers(channel, cm)
} else if scope == "global" {
count = PublishToAll(cm)
} else {
w.WriteHeader(400)
fmt.Fprint(w, "Need to specify either chat or channel")

View file

@ -1 +1,89 @@
package server
import (
"errors"
"fmt"
"net/http"
)
// this value is just docs right now
var ServerInitiatedCommands = []string{
/// Global updates & notices
"update_news", // timecache:global
"message", // timecache:global
"reload_ff", // timecache:global
/// Emote updates
"reload_badges", // timecache:global
"set_badge", // timecache:multichat
"reload_set", // timecache:multichat
"load_set", // TODO what are the semantics of this?
/// User auth
"do_authorize", // nocache:single
/// Channel data
// extra emote sets included in the chat
"follow_sets", // mustcache:chat
// extra follow buttons below the stream
"follow_buttons", // mustcache:watching
// SRL race data
"srl_race", // cachelast:watching
/// Chatter/viewer counts
"chatters", // cachelast:watching
"viewers", // cachelast:watching
}
var _ = ServerInitiatedCommands
type BacklogCacheType int
const (
// This is not a cache type.
CacheTypeInvalid BacklogCacheType = iota
// This message cannot be cached.
CacheTypeNever
// Save the last 24 hours of this message.
// If a client indicates that it has reconnected, replay the messages sent after the disconnect.
CacheTypeTimestamps
// Save only the last copy of this message, and always send it when the backlog is requested.
CacheTypeLastOnly
// Save this backlog data to disk with its timestamp.
// Send it when the backlog is requested, or after a reconnect if it was updated.
CacheTypePersistent
)
type MessageTargetType int
const (
// This is not a message target.
MsgTargetTypeInvalid MessageTargetType = iota
// This message is targeted to a single TODO(user or connection)
MsgTargetTypeSingle
// This message is targeted to all users in a chat
MsgTargetTypeChat
// This message is targeted to all users in multiple chats
MsgTargetTypeMultichat
// This message is targeted to all users watching a stream
MsgTargetTypeWatching
// This message is sent to all FFZ users.
MsgTargetTypeGlobal
)
// Returned by BacklogCacheType.UnmarshalJSON()
var ErrorUnrecognizedCacheType = errors.New("Invalid value for cachetype")
// Returned by MessageTargetType.UnmarshalJSON()
var ErrorUnrecognizedTargetType = errors.New("Invalid value for message target")
// note: see types.go for methods on these
func HBackendSaveBacklog(w http.ResponseWriter, r *http.Request) {
formData, err := UnsealRequest(r.Form)
if err != nil {
w.WriteHeader(403)
fmt.Fprintf(w, "Error: %v", err)
return
}
}

View file

@ -54,6 +54,8 @@ func HandleHello(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (r
client.ClientID = uuid.NewV4()
}
SubscribeGlobal(client)
return ClientMessage{
Arguments: client.ClientID.String(),
}, nil

View file

@ -84,5 +84,120 @@ type ClientInfo struct {
// Server-initiated messages should be sent here
// Never nil.
MessageChannel chan <- ClientMessage
MessageChannel chan<- ClientMessage
}
func (bct BacklogCacheType) Name() string {
switch bct {
case CacheTypeInvalid:
return ""
case CacheTypeNever:
return "never"
case CacheTypeTimestamps:
return "timed"
case CacheTypeLastOnly:
return "last"
case CacheTypePersistent:
return "persist"
}
panic("Invalid BacklogCacheType value")
}
var CacheTypesByName = map[string]BacklogCacheType{
"never": CacheTypeNever,
"timed": CacheTypeTimestamps,
"last": CacheTypeLastOnly,
"persist": CacheTypePersistent,
}
func BacklogCacheTypeByName(name string) (bct BacklogCacheType) {
// CacheTypeInvalid is the zero value so it doesn't matter
bct, _ = CacheTypesByName[name]
return
}
// Implements Stringer
func (bct BacklogCacheType) String() string { return bct.Name() }
// Implements json.Marshaler
func (bct BacklogCacheType) MarshalJSON() ([]byte, error) {
return json.Marshal(bct.Name())
}
// Implements json.Unmarshaler
func (pbct *BacklogCacheType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)
if err != nil {
return err
}
if str == "" {
*pbct = CacheTypeInvalid
return nil
}
val := BacklogCacheTypeByName(str)
if val != CacheTypeInvalid {
*pbct = val
return nil
}
return ErrorUnrecognizedCacheType
}
func (mtt MessageTargetType) Name() string {
switch mtt {
case MsgTargetTypeInvalid:
return ""
case MsgTargetTypeSingle:
return "single"
case MsgTargetTypeChat:
return "chat"
case MsgTargetTypeMultichat:
return "multichat"
case MsgTargetTypeWatching:
return "channel"
case MsgTargetTypeGlobal:
return "global"
}
panic("Invalid MessageTargetType value")
}
var TargetTypesByName = map[string]MessageTargetType{
"single": MsgTargetTypeSingle,
"chat": MsgTargetTypeChat,
"multichat": MsgTargetTypeMultichat,
"channel": MsgTargetTypeWatching,
"global": MsgTargetTypeGlobal,
}
func MessageTargetTypeByName(name string) (mtt MessageTargetType) {
// MsgTargetTypeInvalid is the zero value so it doesn't matter
mtt, _ = TargetTypesByName[name]
return
}
// Implements Stringer
func (mtt MessageTargetType) String() string { return mtt.Name() }
// Implements json.Marshaler
func (mtt MessageTargetType) MarshalJSON() ([]byte, error) {
return json.Marshal(mtt.Name())
}
// Implements json.Unmarshaler
func (pmtt *MessageTargetType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)
if err != nil {
return err
}
if str == "" {
*pmtt = MsgTargetTypeInvalid
return nil
}
mtt := MessageTargetTypeByName(str)
if mtt != MsgTargetTypeInvalid {
*pmtt = mtt
return nil
}
return ErrorUnrecognizedTargetType
}