1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-09-16 18:06:55 +00:00

Fix 'sub' commands after 'ready'

This commit is contained in:
Kane York 2016-04-28 14:39:20 -07:00
parent 801a57a1fa
commit 822e298d5d
5 changed files with 65 additions and 49 deletions

View file

@ -174,15 +174,7 @@ func C2SReady(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg
// } // }
client.Mutex.Lock() client.Mutex.Lock()
if client.MakePendingRequests != nil { client.ReadyComplete = true
if !client.MakePendingRequests.Stop() {
// Timer already fired, GetSubscriptionBacklog() has started
rmsg.Command = SuccessCommand
return
}
}
client.PendingSubscriptionsBacklog = nil
client.MakePendingRequests = nil
client.Mutex.Unlock() client.Mutex.Unlock()
client.MsgChannelKeepalive.Add(1) client.MsgChannelKeepalive.Add(1)
@ -204,13 +196,18 @@ func C2SSubscribe(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (
client.Mutex.Lock() client.Mutex.Lock()
AddToSliceS(&client.CurrentChannels, channel) AddToSliceS(&client.CurrentChannels, channel)
if usePendingSubscrptionsBacklog {
client.PendingSubscriptionsBacklog = append(client.PendingSubscriptionsBacklog, channel)
}
client.Mutex.Unlock() client.Mutex.Unlock()
SubscribeChannel(client, channel) SubscribeChannel(client, channel)
if client.ReadyComplete {
client.MsgChannelKeepalive.Add(1)
go func() {
SendBacklogForChannel(client, channel)
client.MsgChannelKeepalive.Done()
}()
}
return ResponseSuccess, nil return ResponseSuccess, nil
} }

View file

@ -56,7 +56,7 @@ func authorizationJanitor_do() {
if !cullTime.After(v.EnteredAt) { if !cullTime.After(v.EnteredAt) {
newPendingAuths = append(newPendingAuths, v) newPendingAuths = append(newPendingAuths, v)
} else { } else {
v.Callback(v.Client, false) go v.Callback(v.Client, false)
} }
} }
@ -64,12 +64,13 @@ func authorizationJanitor_do() {
} }
func (client *ClientInfo) StartAuthorization(callback AuthCallback) { func (client *ClientInfo) StartAuthorization(callback AuthCallback) {
if callback == nil {
return // callback must not be nil
}
var nonce [32]byte var nonce [32]byte
_, err := rand.Read(nonce[:]) _, err := rand.Read(nonce[:])
if err != nil { if err != nil {
go func(client *ClientInfo, callback AuthCallback) { go callback(client, false)
callback(client, false)
}(client, callback)
return return
} }
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
@ -153,11 +154,9 @@ func submitAuth(user, challenge string) {
} }
auth.Client.Mutex.Unlock() auth.Client.Mutex.Unlock()
if auth.Callback != nil { if !usernameChanged {
if !usernameChanged { auth.Callback(auth.Client, true)
auth.Callback(auth.Client, true) } else {
} else { auth.Callback(auth.Client, false)
auth.Callback(auth.Client, false)
}
} }
} }

View file

@ -29,6 +29,9 @@ var S2CCommandsCacheInfo = map[Command]PushCommandCacheInfo{
"viewers": {CacheTypeLastOnly, MsgTargetTypeChat}, "viewers": {CacheTypeLastOnly, MsgTargetTypeChat},
} }
var PersistentCachingCommands = []Command{"follow_sets", "follow_buttons"}
var HourlyCachingCommands = []Command{"srl_race", "chatters", "viewers"}
type BacklogCacheType int type BacklogCacheType int
const ( const (
@ -101,8 +104,8 @@ func SendBacklogForNewClient(client *ClientInfo) {
client.Mutex.Unlock() client.Mutex.Unlock()
PersistentLSMLock.RLock() PersistentLSMLock.RLock()
for _, cmd := range GetCommandsOfType(PushCommandCacheInfo{CacheTypePersistent, MsgTargetTypeChat}) { for _, cmd := range GetCommandsOfType(CacheTypePersistent) {
chanMap := CachedLastMessages[cmd] chanMap := PersistentLastMessages[cmd]
if chanMap == nil { if chanMap == nil {
continue continue
} }
@ -118,7 +121,7 @@ func SendBacklogForNewClient(client *ClientInfo) {
PersistentLSMLock.RUnlock() PersistentLSMLock.RUnlock()
CachedLSMLock.RLock() CachedLSMLock.RLock()
for _, cmd := range GetCommandsOfType(PushCommandCacheInfo{CacheTypeLastOnly, MsgTargetTypeChat}) { for _, cmd := range GetCommandsOfType(CacheTypeLastOnly) {
chanMap := CachedLastMessages[cmd] chanMap := CachedLastMessages[cmd]
if chanMap == nil { if chanMap == nil {
continue continue
@ -135,6 +138,36 @@ func SendBacklogForNewClient(client *ClientInfo) {
CachedLSMLock.RUnlock() CachedLSMLock.RUnlock()
} }
func SendBacklogForChannel(client *ClientInfo, channel string) {
PersistentLSMLock.RLock()
for _, cmd := range GetCommandsOfType(CacheTypePersistent) {
chanMap := PersistentLastMessages[cmd]
if chanMap == nil {
continue
}
if msg, ok := chanMap[channel]; ok {
msg := ClientMessage{MessageID: -1, Command: cmd, origArguments: msg.Data}
msg.parseOrigArguments()
client.MessageChannel <- msg
}
}
PersistentLSMLock.RUnlock()
CachedLSMLock.RLock()
for _, cmd := range GetCommandsOfType(CacheTypeLastOnly) {
chanMap := CachedLastMessages[cmd]
if chanMap == nil {
continue
}
if msg, ok := chanMap[channel]; ok {
msg := ClientMessage{MessageID: -1, Command: cmd, origArguments: msg.Data}
msg.parseOrigArguments()
client.MessageChannel <- msg
}
}
CachedLSMLock.RUnlock()
}
type timestampArray interface { type timestampArray interface {
Len() int Len() int
GetTime(int) time.Time GetTime(int) time.Time
@ -144,13 +177,13 @@ func SaveLastMessage(which map[Command]map[string]LastSavedMessage, locker sync.
locker.Lock() locker.Lock()
defer locker.Unlock() defer locker.Unlock()
chanMap, ok := CachedLastMessages[cmd] chanMap, ok := which[cmd]
if !ok { if !ok {
if deleting { if deleting {
return return
} }
chanMap = make(map[string]LastSavedMessage) chanMap = make(map[string]LastSavedMessage)
CachedLastMessages[cmd] = chanMap which[cmd] = chanMap
} }
if deleting { if deleting {
@ -160,14 +193,14 @@ func SaveLastMessage(which map[Command]map[string]LastSavedMessage, locker sync.
} }
} }
func GetCommandsOfType(match PushCommandCacheInfo) []Command { func GetCommandsOfType(match BacklogCacheType) []Command {
var ret []Command if match == CacheTypePersistent {
for cmd, info := range S2CCommandsCacheInfo { return PersistentCachingCommands
if info == match { } else if match == CacheTypeLastOnly {
ret = append(ret, cmd) return HourlyCachingCommands
} } else {
panic("unknown caching type")
} }
return ret
} }
func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) { func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {

View file

@ -111,11 +111,6 @@ func UnsubscribeAll(client *ClientInfo) {
return // no need to remove from a high-contention list when the server is closing return // no need to remove from a high-contention list when the server is closing
} }
client.Mutex.Lock()
client.PendingSubscriptionsBacklog = nil
client.PendingSubscriptionsBacklog = nil
client.Mutex.Unlock()
GlobalSubscriptionLock.Lock() GlobalSubscriptionLock.Lock()
RemoveFromSliceCl(&GlobalSubscriptionInfo, client) RemoveFromSliceCl(&GlobalSubscriptionInfo, client)
GlobalSubscriptionLock.Unlock() GlobalSubscriptionLock.Unlock()

View file

@ -104,14 +104,8 @@ type ClientInfo struct {
// Protected by Mutex. // Protected by Mutex.
CurrentChannels []string CurrentChannels []string
// List of channels that we have not yet checked current chat-related channel info for. // True if the client has already sent the 'ready' command
// This lets us batch the backlog requests. ReadyComplete bool
// Protected by Mutex.
PendingSubscriptionsBacklog []string
// A timer that, when fired, will make the pending backlog requests.
// Usually nil. Protected by Mutex.
MakePendingRequests *time.Timer
// Server-initiated messages should be sent here // Server-initiated messages should be sent here
// This field will be nil before it is closed. // This field will be nil before it is closed.
@ -157,8 +151,6 @@ func (cv *ClientVersion) Equal(cv2 *ClientVersion) bool {
return cv.Major == cv2.Major && cv.Minor == cv2.Minor && cv.Revision == cv2.Revision return cv.Major == cv2.Major && cv.Minor == cv2.Minor && cv.Revision == cv2.Revision
} }
const usePendingSubscrptionsBacklog = false
func (bct BacklogCacheType) Name() string { func (bct BacklogCacheType) Name() string {
switch bct { switch bct {
case CacheTypeInvalid: case CacheTypeInvalid: