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

Source cleanup, and some string copies

This commit is contained in:
Kane York 2016-01-17 18:01:21 -08:00
parent 387ada9c9c
commit 7654dcdf8d
10 changed files with 47 additions and 89 deletions

View file

@ -17,7 +17,7 @@ import (
// The Commands sent from Client -> Server and Server -> Client are disjoint sets.
type Command string
// CommandHandler is a RPC handler assosciated with a Command.
// CommandHandler is a RPC handler associated with a Command.
type CommandHandler func(*websocket.Conn, *ClientInfo, ClientMessage) (ClientMessage, error)
var commandHandlers = map[Command]CommandHandler{
@ -43,10 +43,10 @@ var commandHandlers = map[Command]CommandHandler{
func internCommands() {
CommandPool = NewStringPool()
CommandPool._Intern_Setup(HelloCommand)
CommandPool._Intern_Setup(string(HelloCommand))
CommandPool._Intern_Setup("ping")
CommandPool._Intern_Setup(SetUserCommand)
CommandPool._Intern_Setup(ReadyCommand)
CommandPool._Intern_Setup(string(SetUserCommand))
CommandPool._Intern_Setup(string(ReadyCommand))
CommandPool._Intern_Setup("sub")
CommandPool._Intern_Setup("unsub")
CommandPool._Intern_Setup("track_follow")
@ -155,8 +155,8 @@ func C2SSetUser(conn *websocket.Conn, client *ClientInfo, msg ClientMessage) (rm
}
client.Mutex.Lock()
client.TwitchUsername = username
client.UsernameValidated = false
client.TwitchUsername = username
client.Mutex.Unlock()
if Configuration.SendAuthToNewClients {
@ -262,7 +262,7 @@ func C2STrackFollow(conn *websocket.Conn, client *ClientInfo, msg ClientMessage)
now := time.Now()
followEventsLock.Lock()
followEvents = append(followEvents, followEvent{client.TwitchUsername, channel, following, now})
followEvents = append(followEvents, followEvent{User: client.TwitchUsername, Channel: channel, NowFollowing: following, Timestamp: now})
followEventsLock.Unlock()
return ResponseSuccess, nil

View file

@ -60,7 +60,7 @@ var Configuration *ConfigFile
var janitorsOnce sync.Once
var CommandPool StringPool
var CommandPool *StringPool
// SetupServerAndHandle starts all background goroutines and registers HTTP listeners on the given ServeMux.
// Essentially, this function completely preps the server for a http.ListenAndServe call.
@ -573,7 +573,7 @@ func MarshalClientMessage(clientMessage interface{}) (payloadType int, data []by
return websocket.TextMessage, []byte(dataStr), nil
}
// Convenience method: Parse the arguments of the ClientMessage as a single string.
// ArgumentsAsString parses the arguments of the ClientMessage as a single string.
func (cm *ClientMessage) ArgumentsAsString() (string1 string, err error) {
var ok bool
string1, ok = cm.Arguments.(string)
@ -585,7 +585,7 @@ func (cm *ClientMessage) ArgumentsAsString() (string1 string, err error) {
}
}
// Convenience method: Parse the arguments of the ClientMessage as a single int.
// ArgumentsAsInt parses the arguments of the ClientMessage as a single int.
func (cm *ClientMessage) ArgumentsAsInt() (int1 int64, err error) {
var ok bool
var num float64
@ -599,7 +599,7 @@ func (cm *ClientMessage) ArgumentsAsInt() (int1 int64, err error) {
}
}
// Convenience method: Parse the arguments of the ClientMessage as an array of two strings.
// ArgumentsAsTwoStrings parses the arguments of the ClientMessage as an array of two strings.
func (cm *ClientMessage) ArgumentsAsTwoStrings() (string1, string2 string, err error) {
var ok bool
var ary []interface{}
@ -630,7 +630,7 @@ func (cm *ClientMessage) ArgumentsAsTwoStrings() (string1, string2 string, err e
}
}
// Convenience method: Parse the arguments of the ClientMessage as an array of a string and an int.
// ArgumentsAsStringAndInt parses the arguments of the ClientMessage as an array of a string and an int.
func (cm *ClientMessage) ArgumentsAsStringAndInt() (string1 string, int int64, err error) {
var ok bool
var ary []interface{}
@ -663,7 +663,7 @@ func (cm *ClientMessage) ArgumentsAsStringAndInt() (string1 string, int int64, e
}
}
// Convenience method: Parse the arguments of the ClientMessage as an array of a string and an int.
// ArgumentsAsStringAndBool parses the arguments of the ClientMessage as an array of a string and an int.
func (cm *ClientMessage) ArgumentsAsStringAndBool() (str string, flag bool, err error) {
var ok bool
var ary []interface{}

View file

@ -32,6 +32,7 @@ func (p *StringPool) Intern(s string) Command {
if exists {
return ss
}
p.lookup[s] = Command(string([]byte(s)))
return s
ss = Command(string([]byte(s))) // make a copy
p.lookup[s] = ss
return ss
}

View file

@ -4,7 +4,6 @@ import (
"bytes"
"crypto/rand"
"encoding/base64"
"errors"
irc "github.com/fluffle/goirc/client"
"log"
"strings"
@ -87,10 +86,6 @@ const AuthChannelName = "frankerfacezauthorizer"
const AuthChannel = "#" + AuthChannelName
const AuthCommand = "AUTH"
const DEBUG = "DEBUG"
var errChallengeNotFound = errors.New("did not find a challenge solved by that message")
// is_init_func
func ircConnection() {

View file

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/http"
"sort"
"strconv"
"strings"
"sync"
@ -33,36 +32,37 @@ var S2CCommandsCacheInfo = map[Command]PushCommandCacheInfo{
type BacklogCacheType int
const (
// This is not a cache type.
// CacheTypeInvalid is the sentinel value.
CacheTypeInvalid BacklogCacheType = iota
// This message cannot be cached.
// CacheTypeNever is a message that cannot be cached.
CacheTypeNever
// Save only the last copy of this message, and always send it when the backlog is requested.
// CacheTypeLastOnly means to 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 means to save the last copy of this message,
// and always send it when the backlog is requested, but do not clean it periodically.
CacheTypePersistent
)
type MessageTargetType int
const (
// This is not a message target.
// MsgTargetTypeInvalid is the sentinel value.
MsgTargetTypeInvalid MessageTargetType = iota
// This message is targeted to all users in a chat
// MsgTargetTypeChat is a message is targeted to all users in a particular chat.
MsgTargetTypeChat
// This message is targeted to all users in multiple chats
// MsgTargetTypeMultichat is a message is targeted to all users in multiple chats.
MsgTargetTypeMultichat
// This message is sent to all FFZ users.
// MsgTargetTypeGlobal is a message sent to all FFZ users.
MsgTargetTypeGlobal
)
// note: see types.go for methods on these
// Returned by BacklogCacheType.UnmarshalJSON()
// ErrorUnrecognizedCacheType is returned by BacklogCacheType.UnmarshalJSON()
var ErrorUnrecognizedCacheType = errors.New("Invalid value for cachetype")
// Returned by MessageTargetType.UnmarshalJSON()
// ErrorUnrecognizedTargetType is returned by MessageTargetType.UnmarshalJSON()
var ErrorUnrecognizedTargetType = errors.New("Invalid value for message target")
type LastSavedMessage struct {
@ -72,11 +72,11 @@ type LastSavedMessage struct {
// map is command -> channel -> data
// CacheTypeLastOnly. Cleaned up by reaper goroutine every ~hour.
// CachedLastMessages is of CacheTypeLastOnly. Cleaned up by reaper goroutine every ~hour.
var CachedLastMessages = make(map[Command]map[string]LastSavedMessage)
var CachedLSMLock sync.RWMutex
// CacheTypePersistent. Never cleaned.
// PersistentLastMessages is of CacheTypePersistent. Never cleaned.
var PersistentLastMessages = make(map[Command]map[string]LastSavedMessage)
var PersistentLSMLock sync.RWMutex
@ -135,50 +135,11 @@ func SendBacklogForNewClient(client *ClientInfo) {
CachedLSMLock.RUnlock()
}
// insertionSort implements insertion sort.
// CacheTypeTimestamps should use insertion sort for O(N) average performance.
// (The average case is the array is still sorted after insertion of the new item.)
func insertionSort(ary sort.Interface) {
for i := 1; i < ary.Len(); i++ {
for j := i; j > 0 && ary.Less(j, j-1); j-- {
ary.Swap(j, j-1)
}
}
}
type timestampArray interface {
Len() int
GetTime(int) time.Time
}
func findFirstNewMessage(ary timestampArray, disconnectTime time.Time) (idx int) {
len := ary.Len()
i := len
// Walk backwards until we find GetTime() before disconnectTime
step := 1
for i > 0 {
i -= step
if i < 0 {
i = 0
}
if !ary.GetTime(i).After(disconnectTime) {
break
}
step = int(float64(step)*1.5) + 1
}
// Walk forwards until we find GetTime() after disconnectTime
for i < len && !ary.GetTime(i).After(disconnectTime) {
i++
}
if i == len {
return -1
}
return i
}
func SaveLastMessage(which map[Command]map[string]LastSavedMessage, locker sync.Locker, cmd Command, channel string, timestamp time.Time, data string, deleting bool) {
locker.Lock()
defer locker.Unlock()
@ -195,7 +156,7 @@ func SaveLastMessage(which map[Command]map[string]LastSavedMessage, locker sync.
if deleting {
delete(chanMap, channel)
} else {
chanMap[channel] = LastSavedMessage{timestamp, data}
chanMap[channel] = LastSavedMessage{Timestamp: timestamp, Data: data}
}
}
@ -224,7 +185,8 @@ func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {
}
}
// Publish a message to clients, and update the in-server cache for the message.
// HTTPBackendCachedPublish handles the /cached_pub route.
// It publishes a message to clients, and then updates the in-server cache for the message.
// notes:
// `scope` is implicit in the command
func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {

View file

@ -73,7 +73,7 @@ func commandCounter() {
}
}
// StatsDataVersion
// StatsDataVersion is the version of the StatsData struct.
const StatsDataVersion = 5
const pageSize = 4096

View file

@ -99,7 +99,9 @@ func UnsubscribeSingleChat(client *ClientInfo, channelName string) {
ChatSubscriptionLock.RUnlock()
}
// Unsubscribe the client from all channels, AND clear the CurrentChannels / WatchingChannels fields.
// UnsubscribeAll will unsubscribe the client from all channels,
// AND clear the CurrentChannels / WatchingChannels fields.
//
// Locks:
// - read lock to top-level maps
// - write lock to SubscriptionInfos

View file

@ -30,9 +30,9 @@ func TestSubscriptionAndPublish(t *testing.T) {
const TestData3 = false
var TestData4 = []interface{}{"str1", "str2", "str3"}
S2CCommandsCacheInfo[TestCommandChan] = PushCommandCacheInfo{CacheTypeLastOnly, MsgTargetTypeChat}
S2CCommandsCacheInfo[TestCommandMulti] = PushCommandCacheInfo{CacheTypeLastOnly, MsgTargetTypeMultichat}
S2CCommandsCacheInfo[TestCommandGlobal] = PushCommandCacheInfo{CacheTypeLastOnly, MsgTargetTypeGlobal}
S2CCommandsCacheInfo[TestCommandChan] = PushCommandCacheInfo{Caching: CacheTypeLastOnly, Target: MsgTargetTypeChat}
S2CCommandsCacheInfo[TestCommandMulti] = PushCommandCacheInfo{Caching: CacheTypeLastOnly, Target: MsgTargetTypeMultichat}
S2CCommandsCacheInfo[TestCommandGlobal] = PushCommandCacheInfo{Caching: CacheTypeLastOnly, Target: MsgTargetTypeGlobal}
var server *httptest.Server
var urls TURLs

View file

@ -9,8 +9,6 @@ import (
"time"
)
const CryptoBoxKeyLength = 32
const NegativeOne = ^uint64(0)
type ConfigFile struct {
@ -94,7 +92,7 @@ type ClientInfo struct {
// If it seems to be a performance problem, we can split this.
Mutex sync.Mutex
// TODO(riking) - does this need to be protected cross-thread?
// Info about the client's username and whether or not we have verified it.
AuthInfo
RemoteAddr net.Addr
@ -187,15 +185,15 @@ func BacklogCacheTypeByName(name string) (bct BacklogCacheType) {
return
}
// Implements Stringer
// String implements Stringer
func (bct BacklogCacheType) String() string { return bct.Name() }
// Implements json.Marshaler
// MarshalJSON implements json.Marshaler
func (bct BacklogCacheType) MarshalJSON() ([]byte, error) {
return json.Marshal(bct.Name())
}
// Implements json.Unmarshaler
// UnmarshalJSON implements json.Unmarshaler
func (bct *BacklogCacheType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)
@ -240,15 +238,15 @@ func MessageTargetTypeByName(name string) (mtt MessageTargetType) {
return
}
// Implements Stringer
// String implements Stringer
func (mtt MessageTargetType) String() string { return mtt.Name() }
// Implements json.Marshaler
// MarshalJSON implements json.Marshaler
func (mtt MessageTargetType) MarshalJSON() ([]byte, error) {
return json.Marshal(mtt.Name())
}
// Implements json.Unmarshaler
// UnmarshalJSON implements json.Unmarshaler
func (mtt *MessageTargetType) UnmarshalJSON(data []byte) error {
var str string
err := json.Unmarshal(data, &str)

View file

@ -17,7 +17,7 @@ import (
"io"
)
// uuidHash implements a hash for uuid.UUID by XORing the random bits.
// UuidHash implements a hash for uuid.UUID by XORing the random bits.
type UuidHash uuid.UUID
func (u UuidHash) Sum64() uint64 {