Changed slices to maps in app, channel

This commit is contained in:
claudemiro
2015-01-12 21:41:22 -03:00
parent e2412827cf
commit 387a2ae28d
6 changed files with 73 additions and 52 deletions
+2 -2
View File
@@ -9,9 +9,9 @@ IPÊ
- [ ] Escrever testes automatizados - [ ] Escrever testes automatizados
- [ ] SSL - [ ] SSL
- [ ] Expvar - Canais, inscritos - [ ] Expvar - Canais, inscritos
- [ ] Otimizações [0/3] - [-] Otimizações [1/3]
- [ ] Refatorar partes do código, remover repetições - [ ] Refatorar partes do código, remover repetições
- [ ] Alterar tipos de dados de slices para mapas em alguns locais. - [X] Alterar tipos de dados de slices para mapas em alguns locais.
- [ ] Remover Canais vazios com uma go routine - Uma especie de coletor de lixo - [ ] Remover Canais vazios com uma go routine - Uma especie de coletor de lixo
- [ ] Segurança, tempo de expiração, etc - [ ] Segurança, tempo de expiração, etc
- [X] Dados extra na conexão do usuário. Ver Websockets onOpen - [X] Dados extra na conexão do usuário. Ver Websockets onOpen
+48 -24
View File
@@ -25,24 +25,56 @@ type App struct {
WebHooks bool WebHooks bool
URLWebHook string URLWebHook string
PublicChannels []*Channel `json:"-"` Channels map[string]*Channel `json:"-"`
PresenceChannels []*Channel `json:"-"`
PrivateChannels []*Channel `json:"-"`
Subscribers map[string]*Subscriber `json:"-"` Subscribers map[string]*Subscriber `json:"-"`
} }
// Returns a list of all channels in this app // Alloc memory for Subscribers and Channels
func (a *App) AllChannels() []*Channel { func (a *App) Init() {
a.Subscribers = make(map[string]*Subscriber)
a.Channels = make(map[string]*Channel)
}
// Only Presence channels
func (a *App) PresenceChannels() []*Channel {
var channels []*Channel var channels []*Channel
channels = append(channels, a.PrivateChannels...) for _, c := range a.Channels {
channels = append(channels, a.PresenceChannels...) if c.IsPresence() {
channels = append(channels, a.PublicChannels...) channels = append(channels, c)
}
}
return channels return channels
} }
// Only Private channels
func (a *App) PrivateChannels() []*Channel {
var channels []*Channel
for _, c := range a.Channels {
if c.IsPrivate() {
channels = append(channels, c)
}
}
return channels
}
// Only Public channels
func (a *App) PublicChannels() []*Channel {
var channels []*Channel
for _, c := range a.Channels {
if c.IsPublic() {
channels = append(channels, c)
}
}
return channels
}
// Disconnect Socket
func (a *App) Disconnect(socketID string) { func (a *App) Disconnect(socketID string) {
log.Infof("Disconnecting socket %+v", socketID) log.Infof("Disconnecting socket %+v", socketID)
@@ -54,7 +86,7 @@ func (a *App) Disconnect(socketID string) {
} }
// Unsubscribe from channels // Unsubscribe from channels
for _, c := range a.AllChannels() { for _, c := range a.Channels {
if c.IsSubscribed(s) { if c.IsSubscribed(s) {
c.Unsubscribe(a, s) c.Unsubscribe(a, s)
} }
@@ -72,7 +104,7 @@ func (a *App) Disconnect(socketID string) {
a.Unlock() a.Unlock()
} }
// Create a new Subscriber // Connect a new Subscriber
func (a *App) Connect(s *Subscriber) { func (a *App) Connect(s *Subscriber) {
log.Infof("Adding a new Subscriber %s to app %s", s.SocketID, a.Name) log.Infof("Adding a new Subscriber %s to app %s", s.SocketID, a.Name)
a.Lock() a.Lock()
@@ -97,15 +129,7 @@ func (a *App) AddChannel(c *Channel) {
log.Infof("Adding a new channel %s to app %s", c.ChannelID, a.Name) log.Infof("Adding a new channel %s to app %s", c.ChannelID, a.Name)
a.Lock() a.Lock()
a.Channels[c.ChannelID] = c
if c.IsPresence() {
a.PresenceChannels = append(a.PresenceChannels, c)
} else if c.IsPrivate() {
a.PrivateChannels = append(a.PrivateChannels, c)
} else {
a.PublicChannels = append(a.PublicChannels, c)
}
a.Unlock() a.Unlock()
} }
@@ -125,10 +149,10 @@ func (a *App) FindOrCreateChannelByChannelID(n string) *Channel {
// Find the channel by channel ID // Find the channel by channel ID
func (a *App) FindChannelByChannelID(n string) (*Channel, error) { func (a *App) FindChannelByChannelID(n string) (*Channel, error) {
for _, c := range a.AllChannels() { c, exists := a.Channels[n]
if c.ChannelID == n {
return c, nil if exists {
} return c, nil
} }
return nil, errors.New("Channel does not exists") return nil, errors.New("Channel does not exists")
+3 -2
View File
@@ -15,9 +15,10 @@ type ConfigFile struct {
// Error for App not found // Error for App not found
var AppNotFoundError = errors.New("App not found") var AppNotFoundError = errors.New("App not found")
func (c *ConfigFile) Initialize() { // Initialize Apps
func (c *ConfigFile) Init() {
for _, app := range c.Apps { for _, app := range c.Apps {
app.Subscribers = make(map[string]*Subscriber) app.Init()
} }
} }
+15 -19
View File
@@ -9,7 +9,6 @@ import (
"errors" "errors"
"strings" "strings"
"sync" "sync"
"time" "time"
log "github.com/golang/glog" log "github.com/golang/glog"
@@ -47,7 +46,7 @@ type Channel struct {
CreatedAt time.Time CreatedAt time.Time
ChannelID string ChannelID string
Subscriptions []*Subscription Subscriptions map[string]*Subscription
} }
// Return true if the channel has at least one subscriber // Return true if the channel has at least one subscriber
@@ -60,6 +59,11 @@ func (c *Channel) IsPresenceOrPrivate() bool {
return c.IsPresence() || c.IsPrivate() return c.IsPresence() || c.IsPrivate()
} }
// Check if the type of the channel is public
func (c *Channel) IsPublic() bool {
return !c.IsPresence() && !c.IsPrivate()
}
// Check if the type of the channel is presence // Check if the type of the channel is presence
func (c *Channel) IsPresence() bool { func (c *Channel) IsPresence() bool {
return strings.HasPrefix(c.ChannelID, "presence-") return strings.HasPrefix(c.ChannelID, "presence-")
@@ -86,7 +90,7 @@ func (c *Channel) Subscribe(a *App, s *Subscriber, data string) {
log.Infof("Subscribing %s to channel %s", s.SocketID, c.ChannelID) log.Infof("Subscribing %s to channel %s", s.SocketID, c.ChannelID)
c.Lock() c.Lock()
c.Subscriptions = append(c.Subscriptions, NewSubscription(s, data)) c.Subscriptions[s.SocketID] = NewSubscription(s, data)
c.Unlock() c.Unlock()
if c.IsPresence() { if c.IsPresence() {
@@ -116,12 +120,8 @@ func (c *Channel) Subscribe(a *App, s *Subscriber, data string) {
// IsSubscribed check if the user is subscribed // IsSubscribed check if the user is subscribed
func (c *Channel) IsSubscribed(s *Subscriber) bool { func (c *Channel) IsSubscribed(s *Subscriber) bool {
for _, subs := range c.Subscriptions { _, exists := c.Subscriptions[s.SocketID]
if subs.Subscriber == s { return exists
return true
}
}
return false
} }
// Remove the subscriber from the channel // Remove the subscriber from the channel
@@ -132,17 +132,13 @@ func (c *Channel) Unsubscribe(a *App, s *Subscriber) error {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
index := -1 _, exists := c.Subscriptions[s.SocketID]
for i, subs := range c.Subscriptions {
if subs.Subscriber == s { if !exists {
index = i
break
}
}
if index == -1 {
return errors.New("Subscription not found") return errors.New("Subscription not found")
} }
c.Subscriptions = append(c.Subscriptions[:index], c.Subscriptions[index+1:]...)
delete(c.Subscriptions, s.SocketID)
if c.IsPresence() { if c.IsPresence() {
// Publish pusher_internal:member_removed // Publish pusher_internal:member_removed
@@ -162,7 +158,7 @@ func (c *Channel) Unsubscribe(a *App, s *Subscriber) error {
func NewChannel(channelID string) *Channel { func NewChannel(channelID string) *Channel {
log.Infof("Creating a new channel: %s", channelID) log.Infof("Creating a new channel: %s", channelID)
return &Channel{ChannelID: channelID, CreatedAt: time.Now()} return &Channel{ChannelID: channelID, CreatedAt: time.Now(), Subscriptions: make(map[string]*Subscription)}
} }
// This function generate a sequencial ID // This function generate a sequencial ID
+1 -1
View File
@@ -33,7 +33,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
Conf.Initialize() Conf.Init()
router := NewRouter() router := NewRouter()
+4 -4
View File
@@ -136,7 +136,7 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
switch filter { switch filter {
case "presence-": case "presence-":
for _, c := range app.PresenceChannels { for _, c := range app.PresenceChannels() {
if requestedUserCount { if requestedUserCount {
channels[c.ChannelID] = struct { channels[c.ChannelID] = struct {
UserCount int `json:"user_count"` UserCount int `json:"user_count"`
@@ -148,15 +148,15 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
} }
} }
case "public-": case "public-":
for _, c := range app.PublicChannels { for _, c := range app.PublicChannels() {
channels[c.ChannelID] = struct{}{} channels[c.ChannelID] = struct{}{}
} }
case "private-": case "private-":
for _, c := range app.PrivateChannels { for _, c := range app.PrivateChannels() {
channels[c.ChannelID] = struct{}{} channels[c.ChannelID] = struct{}{}
} }
default: default:
for _, c := range app.AllChannels() { for _, c := range app.Channels {
channels[c.ChannelID] = struct{}{} channels[c.ChannelID] = struct{}{}
} }
} }