mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-04 11:44:00 +00:00
Moved rate.Limiter into its own package
This commit is contained in:
parent
7be7fc5c3a
commit
1da392f5b3
7 changed files with 22 additions and 23 deletions
|
@ -119,7 +119,6 @@ func commandLineConsole() {
|
||||||
if cl.Send(msg) {
|
if cl.Send(msg) {
|
||||||
kickCount++
|
kickCount++
|
||||||
}
|
}
|
||||||
kickCount++
|
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("Kicked %d clients", kickCount), nil
|
return fmt.Sprintf("Kicked %d clients", kickCount), nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package server // import "bitbucket.org/stendec/frankerfacez/socketserver/server"
|
package server // import "github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LastSavedMessage contains a reply to a command along with an expiration time.
|
// LastSavedMessage contains a reply to a command along with an expiration time.
|
||||||
|
@ -135,7 +136,7 @@ func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rateLimitFromRequest(r *http.Request) (RateLimit, error) {
|
func rateLimitFromRequest(r *http.Request) (rate.Limiter, error) {
|
||||||
if r.FormValue("rateCount") != "" {
|
if r.FormValue("rateCount") != "" {
|
||||||
c, err := strconv.ParseInt(r.FormValue("rateCount"), 10, 32)
|
c, err := strconv.ParseInt(r.FormValue("rateCount"), 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -145,9 +146,9 @@ func rateLimitFromRequest(r *http.Request) (RateLimit, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "rateTime")
|
return nil, errors.Wrap(err, "rateTime")
|
||||||
}
|
}
|
||||||
return NewRateLimit(int(c), d), nil
|
return rate.NewRateLimit(int(c), d), nil
|
||||||
}
|
}
|
||||||
return Unlimited(), nil
|
return rate.Unlimited(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBackendCachedPublish handles the /cached_pub route.
|
// HTTPBackendCachedPublish handles the /cached_pub route.
|
||||||
|
@ -213,7 +214,7 @@ func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
close(ch)
|
close(ch)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
count = -1
|
count = -1
|
||||||
case <-ch:
|
case <-ch:
|
||||||
}
|
}
|
||||||
|
@ -278,7 +279,7 @@ func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||||
close(ch)
|
close(ch)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
count = -1
|
count = -1
|
||||||
case <-ch:
|
case <-ch:
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package server
|
package rate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A RateLimit supports a constant number of Performed() calls every
|
// A Limiter supports a constant number of Performed() calls every
|
||||||
// time a given unit of time passes.
|
// time a certain amount of time passes.
|
||||||
//
|
//
|
||||||
// Calls to Performed() when no "action tokens" are available will block
|
// Calls to Performed() when no "action tokens" are available will block
|
||||||
// until one is available.
|
// until one is available.
|
||||||
type RateLimit interface {
|
type Limiter interface {
|
||||||
// Run begins emitting tokens for the ratelimiter.
|
// Run begins emitting tokens for the ratelimiter.
|
||||||
// A call to Run must be followed by a call to Close.
|
// A call to Run must be followed by a call to Close.
|
||||||
Run()
|
Run()
|
||||||
|
@ -29,8 +29,8 @@ type timeRateLimit struct {
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a new RateLimit with the given count and duration.
|
// Construct a new Limiter with the given count and duration.
|
||||||
func NewRateLimit(count int, period time.Duration) RateLimit {
|
func NewRateLimit(count int, period time.Duration) Limiter {
|
||||||
return &timeRateLimit{
|
return &timeRateLimit{
|
||||||
count: count,
|
count: count,
|
||||||
period: period,
|
period: period,
|
||||||
|
@ -67,8 +67,8 @@ type unlimited struct{}
|
||||||
|
|
||||||
var unlimitedInstance unlimited
|
var unlimitedInstance unlimited
|
||||||
|
|
||||||
// Unlimited returns a RateLimit that never blocks. The Run() and Close() calls are no-ops.
|
// Unlimited returns a Limiter that never blocks. The Run() and Close() calls are no-ops.
|
||||||
func Unlimited() RateLimit {
|
func Unlimited() Limiter {
|
||||||
return unlimitedInstance
|
return unlimitedInstance
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package server
|
package rate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -1,12 +1,11 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
// This is the scariest code I've written yet for the server.
|
|
||||||
// If I screwed up the locking, I won't know until it's too late.
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/FrankerFaceZ/FrankerFaceZ/socketserver/server/rate"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SubscriberList struct {
|
type SubscriberList struct {
|
||||||
|
@ -60,7 +59,7 @@ func SubscribeGlobal(client *ClientInfo) {
|
||||||
GlobalSubscriptionLock.Unlock()
|
GlobalSubscriptionLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func PublishToChannel(channel string, msg ClientMessage, rl RateLimit) (count int) {
|
func PublishToChannel(channel string, msg ClientMessage, rl rate.Limiter) (count int) {
|
||||||
var found []*ClientInfo
|
var found []*ClientInfo
|
||||||
|
|
||||||
ChatSubscriptionLock.RLock()
|
ChatSubscriptionLock.RLock()
|
||||||
|
@ -82,7 +81,7 @@ func PublishToChannel(channel string, msg ClientMessage, rl RateLimit) (count in
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func PublishToMultiple(channels []string, msg ClientMessage, rl RateLimit) (count int) {
|
func PublishToMultiple(channels []string, msg ClientMessage, rl rate.Limiter) (count int) {
|
||||||
var found []*ClientInfo
|
var found []*ClientInfo
|
||||||
|
|
||||||
ChatSubscriptionLock.RLock()
|
ChatSubscriptionLock.RLock()
|
||||||
|
@ -107,7 +106,7 @@ func PublishToMultiple(channels []string, msg ClientMessage, rl RateLimit) (coun
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
func PublishToAll(msg ClientMessage, rl RateLimit) (count int) {
|
func PublishToAll(msg ClientMessage, rl rate.Limiter) (count int) {
|
||||||
var found []*ClientInfo
|
var found []*ClientInfo
|
||||||
|
|
||||||
GlobalSubscriptionLock.RLock()
|
GlobalSubscriptionLock.RLock()
|
||||||
|
|
|
@ -108,7 +108,7 @@ type ClientInfo struct {
|
||||||
// True if the client has already sent the 'ready' command
|
// True if the client has already sent the 'ready' command
|
||||||
ReadyComplete bool
|
ReadyComplete bool
|
||||||
|
|
||||||
// Server-initiated messages should be sent via the Send() method
|
// Server-initiated messages should be sent via the Send() method.
|
||||||
MessageChannel chan<- ClientMessage
|
MessageChannel chan<- ClientMessage
|
||||||
|
|
||||||
// Closed when the client is shutting down.
|
// Closed when the client is shutting down.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue