|
|
|
@ -1,59 +1,45 @@
|
|
|
|
|
package server
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"sync"
|
|
|
|
|
"log"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// this package creates coordinators responsible for keeping track of active clients and invoking managers
|
|
|
|
|
type CreateManager interface {
|
|
|
|
|
NewManager(*Client, *System, chan error) GeneralManager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type GeneralManager interface {
|
|
|
|
|
Start()
|
|
|
|
|
GetPort() int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Coordinator struct {
|
|
|
|
|
Type string // ["reactor","tui"]
|
|
|
|
|
IncomingClients <-chan *Client
|
|
|
|
|
*Managers
|
|
|
|
|
Sys *System
|
|
|
|
|
CreateManager
|
|
|
|
|
Err chan error
|
|
|
|
|
Pc chan int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Managers struct {
|
|
|
|
|
Directory map[uint32](chan<- *Client)
|
|
|
|
|
Directory map[uint32]GeneralManager
|
|
|
|
|
sync.Mutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewCoordinator(t string,ch chan *Client, sys *System,pc chan int, err chan error) *Coordinator {
|
|
|
|
|
d := make(map[uint32](chan<- *Client))
|
|
|
|
|
// interface stuff
|
|
|
|
|
func NewCoordinator(manager CreateManager, sys *System,err chan error) *Coordinator {
|
|
|
|
|
d := make(map[uint32]GeneralManager)
|
|
|
|
|
m := &Managers{Directory:d}
|
|
|
|
|
c := &Coordinator{Type: t,IncomingClients: ch,Err:err}
|
|
|
|
|
c.Managers = m
|
|
|
|
|
c := &Coordinator{Err:err}
|
|
|
|
|
c.CreateManager = manager
|
|
|
|
|
c.Sys = sys
|
|
|
|
|
c.Pc = pc
|
|
|
|
|
c.Managers = m
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FindNewManager(c *Client,ch chan *Client, sys *System, pc chan int, err chan error) {
|
|
|
|
|
switch c.Type {
|
|
|
|
|
case "reactor":
|
|
|
|
|
NewReactorManager(c,ch,sys,err)
|
|
|
|
|
case "tui":
|
|
|
|
|
NewTUIManager(c,"192.1.168.136",ch,sys,pc,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) {
|
|
|
|
@ -62,13 +48,46 @@ func (c *Coordinator) ClientHandler(cl *Client) {
|
|
|
|
|
defer c.Managers.Unlock()
|
|
|
|
|
if m, exists := c.Managers.Directory[cl.Id]; exists {
|
|
|
|
|
// manager in memory
|
|
|
|
|
m <-cl
|
|
|
|
|
go m.Start()
|
|
|
|
|
} else {
|
|
|
|
|
// create channel and manager
|
|
|
|
|
ch := make(chan *Client)
|
|
|
|
|
FindNewManager(cl, ch, c.Sys, c.Pc, c.Err)
|
|
|
|
|
c.Managers.Directory[cl.Id] = ch
|
|
|
|
|
// will block until manager is ready
|
|
|
|
|
ch <-cl
|
|
|
|
|
m := c.NewManager(cl, c.Sys, c.Err)
|
|
|
|
|
c.Managers.Directory[cl.Id] = m
|
|
|
|
|
go m.Start()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// tui port grabber
|
|
|
|
|
|
|
|
|
|
// reactor coordinator
|
|
|
|
|
type reactorCoordinator struct {
|
|
|
|
|
//empty unexported for method
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *reactorCoordinator) NewManager(cl *Client, sys *System, err chan error) GeneralManager {
|
|
|
|
|
return NewReactorManager(cl,sys,err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewReactorCoordinator(sys *System, err chan error) *Coordinator {
|
|
|
|
|
return NewCoordinator(&reactorCoordinator{}, sys, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//tui coordinator
|
|
|
|
|
type tuiCoordinator struct {
|
|
|
|
|
//can add fields as needed
|
|
|
|
|
Ip string
|
|
|
|
|
Port map[uint32]int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *tuiCoordinator) NewManager(cl *Client, sys *System, err chan error) GeneralManager {
|
|
|
|
|
return NewTUIManager(t.Ip,cl,sys,err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewTUICoordinator(ip string, sys *System, err chan error) *Coordinator {
|
|
|
|
|
p := make(map[uint32]int)
|
|
|
|
|
return NewCoordinator(&tuiCoordinator{Ip:ip,Port:p}, sys, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) GetTUIPort(cl *Client) int {
|
|
|
|
|
m := c.Managers.Directory[cl.Id]
|
|
|
|
|
return m.GetPort()
|
|
|
|
|
}
|
|
|
|
|