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

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
}
}