Fix possible concurrency issues
This commit is contained in:
+24
-5
@@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
// An App
|
// An App
|
||||||
type Application struct {
|
type Application struct {
|
||||||
sync.Mutex
|
sync.RWMutex
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
AppID string
|
AppID string
|
||||||
@@ -32,8 +32,8 @@ type Application struct {
|
|||||||
WebHooks bool
|
WebHooks bool
|
||||||
URLWebHook string
|
URLWebHook string
|
||||||
|
|
||||||
channels map[string]*channel.Channel `json:"-"`
|
channels map[string]*channel.Channel
|
||||||
connections map[string]*connection.Connection `json:"-"`
|
connections map[string]*connection.Connection
|
||||||
|
|
||||||
Stats *expvar.Map `json:"-"`
|
Stats *expvar.Map `json:"-"`
|
||||||
}
|
}
|
||||||
@@ -71,6 +71,9 @@ func NewApplication(
|
|||||||
|
|
||||||
// Channels returns the full list of channels
|
// Channels returns the full list of channels
|
||||||
func (a *Application) Channels() []*channel.Channel {
|
func (a *Application) Channels() []*channel.Channel {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
var channels []*channel.Channel
|
var channels []*channel.Channel
|
||||||
|
|
||||||
for _, c := range a.channels {
|
for _, c := range a.channels {
|
||||||
@@ -82,6 +85,9 @@ func (a *Application) Channels() []*channel.Channel {
|
|||||||
|
|
||||||
// Only Presence channels
|
// Only Presence channels
|
||||||
func (a *Application) PresenceChannels() []*channel.Channel {
|
func (a *Application) PresenceChannels() []*channel.Channel {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
var channels []*channel.Channel
|
var channels []*channel.Channel
|
||||||
|
|
||||||
for _, c := range a.channels {
|
for _, c := range a.channels {
|
||||||
@@ -95,6 +101,9 @@ func (a *Application) PresenceChannels() []*channel.Channel {
|
|||||||
|
|
||||||
// Only Private channels
|
// Only Private channels
|
||||||
func (a *Application) PrivateChannels() []*channel.Channel {
|
func (a *Application) PrivateChannels() []*channel.Channel {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
var channels []*channel.Channel
|
var channels []*channel.Channel
|
||||||
|
|
||||||
for _, c := range a.channels {
|
for _, c := range a.channels {
|
||||||
@@ -108,6 +117,9 @@ func (a *Application) PrivateChannels() []*channel.Channel {
|
|||||||
|
|
||||||
// Only Public channels
|
// Only Public channels
|
||||||
func (a *Application) PublicChannels() []*channel.Channel {
|
func (a *Application) PublicChannels() []*channel.Channel {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
var channels []*channel.Channel
|
var channels []*channel.Channel
|
||||||
|
|
||||||
for _, c := range a.channels {
|
for _, c := range a.channels {
|
||||||
@@ -142,15 +154,16 @@ func (a *Application) Disconnect(socketID string) {
|
|||||||
|
|
||||||
// Remove from Application
|
// Remove from Application
|
||||||
a.Lock()
|
a.Lock()
|
||||||
defer a.Unlock()
|
|
||||||
|
|
||||||
_, exists := a.connections[conn.SocketID]
|
_, exists := a.connections[conn.SocketID]
|
||||||
|
a.Unlock()
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.Lock()
|
||||||
delete(a.connections, conn.SocketID)
|
delete(a.connections, conn.SocketID)
|
||||||
|
a.Unlock()
|
||||||
|
|
||||||
a.Stats.Add("TotalConnections", -1)
|
a.Stats.Add("TotalConnections", -1)
|
||||||
}
|
}
|
||||||
@@ -168,6 +181,9 @@ func (a *Application) Connect(conn *connection.Connection) {
|
|||||||
|
|
||||||
// Find a Connection on this Application
|
// Find a Connection on this Application
|
||||||
func (a *Application) FindConnection(socketID string) (*connection.Connection, error) {
|
func (a *Application) FindConnection(socketID string) (*connection.Connection, error) {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
conn, exists := a.connections[socketID]
|
conn, exists := a.connections[socketID]
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
@@ -256,6 +272,9 @@ func (a *Application) FindOrCreateChannelByChannelID(n string) *channel.Channel
|
|||||||
|
|
||||||
// Find the Channel by Channel ID
|
// Find the Channel by Channel ID
|
||||||
func (a *Application) FindChannelByChannelID(n string) (*channel.Channel, error) {
|
func (a *Application) FindChannelByChannelID(n string) (*channel.Channel, error) {
|
||||||
|
a.RLock()
|
||||||
|
defer a.RUnlock()
|
||||||
|
|
||||||
c, exists := a.channels[n]
|
c, exists := a.channels[n]
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package connection
|
package connection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/golang/glog"
|
log "github.com/golang/glog"
|
||||||
@@ -17,6 +18,8 @@ type Socket interface {
|
|||||||
|
|
||||||
// Connection An user connection
|
// Connection An user connection
|
||||||
type Connection struct {
|
type Connection struct {
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
SocketID string
|
SocketID string
|
||||||
Socket Socket
|
Socket Socket
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
@@ -31,6 +34,9 @@ func New(socketID string, s Socket) *Connection {
|
|||||||
|
|
||||||
// Publish the message to websocket attached to this client
|
// Publish the message to websocket attached to this client
|
||||||
func (conn *Connection) Publish(m interface{}) {
|
func (conn *Connection) Publish(m interface{}) {
|
||||||
|
conn.Lock()
|
||||||
|
defer conn.Unlock()
|
||||||
|
|
||||||
if err := conn.Socket.WriteJSON(m); err != nil {
|
if err := conn.Socket.WriteJSON(m); err != nil {
|
||||||
log.Errorf("error writing json into Socket, %+v", err)
|
log.Errorf("error writing json into Socket, %+v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user