You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
3 years ago
|
package server
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
"log"
|
||
|
)
|
||
|
|
||
|
// this package creates coordinators responsible for keeping track of active clients and invoking managers
|
||
|
|
||
|
type Coordinator struct {
|
||
|
Type string // ["reactor","tui"]
|
||
|
IncomingClients <-chan *Client
|
||
|
Managers
|
||
|
Err chan error
|
||
|
}
|
||
|
|
||
|
type Managers struct {
|
||
|
Directory map[uint32](chan<- bool)
|
||
|
sync.Mutex
|
||
|
}
|
||
|
|
||
|
func NewCoordinator(t string,ch chan *Client, err chan error) *Coordinator {
|
||
|
return &Coordinator{Type: t,IncomingClients: ch,Err:err}
|
||
|
}
|
||
|
|
||
|
func FindNewManager(c *Client,ch chan bool, err chan error) {
|
||
|
switch c.Type {
|
||
|
case "reactor":
|
||
|
NewReactorManager(c,ch,err)
|
||
|
case "tui":
|
||
|
NewTUIManager(c,ch,err)
|
||
|
default:
|
||
|
log.Fatal(fmt.Sprintf("ERROR %v NOT FOUND",c.Type))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *Coordinator) Start() {
|
||
|
// on start we need to create channel listener
|
||
|
// on each new connection we want to check its id against our mapping
|
||
|
go c.Listen()
|
||
|
}
|
||
|
|
||
|
func (c *Coordinator) Listen() {
|
||
|
for {
|
||
|
cl := <-c.IncomingClients
|
||
|
go c.ClientHandler(cl)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *Coordinator) ClientHandler(cl *Client) {
|
||
|
// (creates and) notifies manager of client connection
|
||
|
c.Managers.Lock()
|
||
|
defer c.Managers.Unlock()
|
||
|
if m, exists := c.Managers.Directory[cl.Id]; exists {
|
||
|
// manager in memory
|
||
|
m <-true
|
||
|
} else {
|
||
|
// create channel and manager
|
||
|
ch := make(chan bool)
|
||
|
FindNewManager(cl, ch,c.Err)
|
||
|
c.Managers.Directory[cl.Id] = ch
|
||
|
// will block until manager is ready
|
||
|
ch <-true
|
||
|
}
|
||
|
}
|