mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-25 03:58:30 +00:00
Re-add bunched request caching with a lazy janitor
And this time, only one lock is held at a time during the response.
This commit is contained in:
parent
377afb7a6b
commit
d518759fa0
2 changed files with 81 additions and 4 deletions
|
@ -379,12 +379,82 @@ type BunchSubscriberList struct {
|
|||
Members []BunchSubscriber
|
||||
}
|
||||
|
||||
type CacheStatus byte
|
||||
const (
|
||||
CacheStatusNotFound = iota
|
||||
CacheStatusFound
|
||||
CacheStatusExpired
|
||||
)
|
||||
|
||||
var PendingBunchedRequests map[BunchedRequest]*BunchSubscriberList = make(map[BunchedRequest]*BunchSubscriberList)
|
||||
var PendingBunchLock sync.Mutex
|
||||
var CachedBunchedRequests map[BunchedRequest]BunchedResponse = make(map[BunchedRequest]BunchedResponse)
|
||||
var CachedBunchLock sync.RWMutex
|
||||
var BunchCacheCleanupSignal *sync.Cond = sync.NewCond(&CachedBunchLock)
|
||||
var BunchCacheLastCleanup time.Time
|
||||
|
||||
func bunchCacheJanitor() {
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(30*time.Minute)
|
||||
BunchCacheCleanupSignal.Signal()
|
||||
}
|
||||
}()
|
||||
|
||||
CachedBunchLock.Lock()
|
||||
for {
|
||||
// Unlocks CachedBunchLock, waits for signal, re-locks
|
||||
BunchCacheCleanupSignal.Wait()
|
||||
|
||||
if BunchCacheLastCleanup.After(time.Now().Add(-1*time.Second)) {
|
||||
// skip if it's been less than 1 second
|
||||
continue
|
||||
}
|
||||
|
||||
// CachedBunchLock is held here
|
||||
keepIfAfter := time.Now().Add(-5*time.Minute)
|
||||
for req, resp := range CachedBunchedRequests {
|
||||
if !resp.Timestamp.After(keepIfAfter) {
|
||||
delete(CachedBunchedRequests, req)
|
||||
}
|
||||
}
|
||||
BunchCacheLastCleanup = time.Now()
|
||||
// Loop and Wait(), which re-locks
|
||||
}
|
||||
}
|
||||
|
||||
func HandleBunchedRemoteCommand(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rmsg ClientMessage, err error) {
|
||||
br := BunchedRequestFromCM(&msg)
|
||||
|
||||
cacheStatus := func() byte {
|
||||
CachedBunchLock.RLock()
|
||||
defer CachedBunchLock.RUnlock()
|
||||
bresp, ok := CachedBunchedRequests[br]
|
||||
if ok && bresp.Timestamp.After(time.Now().Add(-5*time.Minute)) {
|
||||
client.MsgChannelKeepalive.Add(1)
|
||||
go func() {
|
||||
var rmsg ClientMessage
|
||||
rmsg.Command = SuccessCommand
|
||||
rmsg.MessageID = msg.MessageID
|
||||
rmsg.origArguments = bresp.Response
|
||||
rmsg.parseOrigArguments()
|
||||
client.MessageChannel <- rmsg
|
||||
client.MsgChannelKeepalive.Done()
|
||||
}()
|
||||
return CacheStatusFound
|
||||
} else if ok {
|
||||
return CacheStatusExpired
|
||||
}
|
||||
return CacheStatusNotFound
|
||||
}()
|
||||
|
||||
if cacheStatus == CacheStatusFound {
|
||||
return ClientMessage{Command: AsyncResponseCommand}, nil
|
||||
} else if cacheStatus == CacheStatusExpired {
|
||||
// Wake up the lazy janitor
|
||||
BunchCacheCleanupSignal.Signal()
|
||||
}
|
||||
|
||||
PendingBunchLock.Lock()
|
||||
defer PendingBunchLock.Unlock()
|
||||
list, ok := PendingBunchedRequests[br]
|
||||
|
@ -399,18 +469,24 @@ func HandleBunchedRemoteCommand(conn *websocket.Conn, client *ClientInfo, msg Cl
|
|||
PendingBunchedRequests[br] = &BunchSubscriberList{Members: []BunchSubscriber{{Client: client, MessageID: msg.MessageID}}}
|
||||
|
||||
go func(request BunchedRequest) {
|
||||
resp, err := SendRemoteCommandCached(string(request.Command), request.Param, AuthInfo{})
|
||||
respStr, err := SendRemoteCommandCached(string(request.Command), request.Param, AuthInfo{})
|
||||
|
||||
var msg ClientMessage
|
||||
if err == nil {
|
||||
msg.Command = SuccessCommand
|
||||
msg.origArguments = resp
|
||||
msg.origArguments = respStr
|
||||
msg.parseOrigArguments()
|
||||
} else {
|
||||
msg.Command = ErrorCommand
|
||||
msg.Arguments = err.Error()
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
CachedBunchLock.Lock()
|
||||
CachedBunchedRequests[request] = BunchedResponse{Response: respStr, Timestamp: time.Now()}
|
||||
CachedBunchLock.Unlock()
|
||||
}
|
||||
|
||||
PendingBunchLock.Lock()
|
||||
bsl := PendingBunchedRequests[request]
|
||||
delete(PendingBunchedRequests, request)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue