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.
71 lines
1.6 KiB
Go
71 lines
1.6 KiB
Go
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 {
|
|
d := make(map[uint32](chan<- bool))
|
|
m := &Managers{Directory:d}
|
|
c := &Coordinator{Type: t,IncomingClients: ch,Err:err}
|
|
c.Managers = m
|
|
return c
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|