func NewLocalConnection(rmId common.RMId, bootCount uint32, topology *server.Topology, cm paxos.ConnectionManager) *LocalConnection { namespace := make([]byte, common.KeyLen) binary.BigEndian.PutUint32(namespace[12:16], bootCount) binary.BigEndian.PutUint32(namespace[16:20], uint32(rmId)) lc := &LocalConnection{ rmId: rmId, connectionManager: cm, namespace: namespace, submitter: NewSimpleTxnSubmitter(rmId, bootCount, topology, cm), nextTxnNumber: 0, nextVarNumber: 0, } var head *cc.ChanCellHead head, lc.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan localConnectionMsg, n) cell.Open = func() { lc.queryChan = queryChan } cell.Close = func() { close(queryChan) } lc.enqueueQueryInner = func(msg localConnectionMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) go lc.actorLoop(head) return lc }
// Create a new connection. The hostPort parameter can be either // hostname:port or ip:port. If port is not provided the default port // of 7894 is used. This will block until a connection is established // and ready to use, or an error occurs. func NewConnection(hostPort, username string, password []byte) (*Connection, error) { if _, _, err := net.SplitHostPort(hostPort); err != nil { hostPort = fmt.Sprintf("%v:%v", hostPort, common.DefaultPort) _, _, err = net.SplitHostPort(hostPort) if err != nil { return nil, err } } tcpAddr, err := net.ResolveTCPAddr("tcp", hostPort) if err != nil { return nil, err } socket, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { return nil, err } if err = socket.SetKeepAlive(true); err != nil { return nil, err } if err = socket.SetKeepAlivePeriod(time.Second); err != nil { return nil, err } conn := &Connection{ nextVUUId: 0, nextTxnId: 0, socket: socket, cache: newCache(), rng: rand.New(rand.NewSource(time.Now().UnixNano())), username: username, password: password, } var head *cc.ChanCellHead head, conn.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan connectionMsg, n) cell.Open = func() { conn.queryChan = queryChan } cell.Close = func() { close(queryChan) } conn.enqueueQueryInner = func(msg connectionMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) go conn.actorLoop(head) if err = conn.awaitReady(); err != nil { return nil, err } return conn, nil }
func NewConnectionManager(rmId common.RMId, bootCount uint32, procs int, db *db.Databases, nodeCertPrivKeyPair *certs.NodeCertificatePrivateKeyPair, port uint16, ss ShutdownSignaller, config *configuration.Configuration) (*ConnectionManager, *TopologyTransmogrifier) { cm := &ConnectionManager{ RMId: rmId, BootCount: bootCount, NodeCertificatePrivateKeyPair: nodeCertPrivKeyPair, servers: make(map[string]*connectionManagerMsgServerEstablished), rmToServer: make(map[common.RMId]*connectionManagerMsgServerEstablished), connCountToClient: make(map[uint32]paxos.ClientConnection), desired: nil, } cm.serverConnSubscribers.subscribers = make(map[paxos.ServerConnectionSubscriber]server.EmptyStruct) cm.serverConnSubscribers.ConnectionManager = cm topSubs := make([]map[eng.TopologySubscriber]server.EmptyStruct, eng.TopologyChangeSubscriberTypeLimit) for idx := range topSubs { topSubs[idx] = make(map[eng.TopologySubscriber]server.EmptyStruct) } topSubs[eng.ConnectionManagerSubscriber][cm] = server.EmptyStructVal cm.topologySubscribers.subscribers = topSubs cm.topologySubscribers.ConnectionManager = cm var head *cc.ChanCellHead head, cm.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan connectionManagerMsg, n) cell.Open = func() { cm.queryChan = queryChan } cell.Close = func() { close(queryChan) } cm.enqueueQueryInner = func(msg connectionManagerMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) cd := &connectionManagerMsgServerEstablished{ send: cm.Send, established: true, rmId: rmId, bootCount: bootCount, } cm.rmToServer[cd.rmId] = cd cm.servers[cd.host] = cd lc := client.NewLocalConnection(rmId, bootCount, cm) cm.Dispatchers = paxos.NewDispatchers(cm, rmId, uint8(procs), db, lc) transmogrifier, localEstablished := NewTopologyTransmogrifier(db, cm, lc, port, ss, config) cm.Transmogrifier = transmogrifier go cm.actorLoop(head) <-localEstablished return cm, transmogrifier }
func (conn *Connection) start() { var head *cc.ChanCellHead head, conn.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan connectionMsg, n) cell.Open = func() { conn.queryChan = queryChan } cell.Close = func() { close(queryChan) } conn.enqueueQueryInner = func(msg connectionMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) conn.rng = rand.New(rand.NewSource(time.Now().UnixNano())) conn.established = false conn.connectionDelay.init(conn) conn.connectionDial.init(conn) conn.connectionAwaitHandshake.init(conn) conn.connectionAwaitServerHandshake.init(conn) conn.connectionAwaitClientHandshake.init(conn) conn.connectionRun.init(conn) if conn.socket == nil { conn.currentState = &conn.connectionDial } else { conn.currentState = &conn.connectionAwaitHandshake } go conn.actorLoop(head) }
func NewListener(listenPort int, cm *ConnectionManager) (*Listener, error) { tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf(":%v", listenPort)) if err != nil { return nil, err } ln, err := net.ListenTCP("tcp", tcpAddr) if err != nil { return nil, err } l := &Listener{ connectionManager: cm, listener: ln, } var head *cc.ChanCellHead head, l.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan listenerMsg, n) cell.Open = func() { l.queryChan = queryChan } cell.Close = func() { close(queryChan) } l.enqueueQueryInner = func(msg listenerMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) go l.acceptLoop() go l.actorLoop(head) return l, nil }
func NewConnectionManager(rmId common.RMId, bootCount uint32, procs int, disk *mdbs.MDBServer, passwordHash [sha256.Size]byte) (*ConnectionManager, *client.LocalConnection) { cm := &ConnectionManager{ RMId: rmId, BootCount: bootCount, passwordHash: passwordHash, servers: make(map[string]*Connection), rmToServer: make(map[common.RMId]*connectionWithBootCount), connCountToClient: make(map[uint32]paxos.ClientConnection), desired: nil, senders: make(map[paxos.Sender]server.EmptyStruct), } var head *cc.ChanCellHead head, cm.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan connectionManagerMsg, n) cell.Open = func() { cm.queryChan = queryChan } cell.Close = func() { close(queryChan) } cm.enqueueQueryInner = func(msg connectionManagerMsg, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) lc := client.NewLocalConnection(rmId, bootCount, server.BlankTopology, cm) cm.Dispatchers = paxos.NewDispatchers(cm, rmId, uint8(procs), disk, lc) cm.rmToServer[rmId] = &connectionWithBootCount{connectionSend: cm, bootCount: bootCount} go cm.actorLoop(head) cm.ClientEstablished(0, lc) return cm, lc }
func newExecutor() *Executor { exe := &Executor{} var head *cc.ChanCellHead head, exe.cellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan executorQuery, n) cell.Open = func() { exe.queryChan = queryChan } cell.Close = func() { close(queryChan) } exe.enqueue = func(msg executorQuery, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) go exe.loop(head) return exe }
func NewMDBServer(path string, openFlags, filemode uint, mapSize uint64, numReaders int, commitLatency time.Duration, dbiStruct interface{}) (*MDBServer, error) { if numReaders < 1 { numReaders = runtime.GOMAXPROCS(0) / 2 // with 0, just returns current value if numReaders < 1 { numReaders = 1 } } server := &MDBServer{ readers: make([]*mdbReader, numReaders), rwtxn: &RWTxn{}, batchedTxn: make([]*readWriteTransactionFuture, 0, 32), // MAGIC NUMBER txnDuration: commitLatency, } var writerHead *cc.ChanCellHead writerHead, server.writerCellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan mdbQuery, n) cell.Open = func() { server.writerChan = queryChan } cell.Close = func() { close(queryChan) } server.writerEnqueueQueryInner = func(msg mdbQuery, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) var readerHead *cc.ChanCellHead readerHead, server.readerCellTail = cc.NewChanCellTail( func(n int, cell *cc.ChanCell) { queryChan := make(chan mdbQuery, n) cell.Open = func() { server.readerChan = queryChan } cell.Close = func() { close(queryChan) } server.readerEnqueueQueryInner = func(msg mdbQuery, curCell *cc.ChanCell, cont cc.CurCellConsumer) (bool, cc.CurCellConsumer) { if curCell == cell { select { case queryChan <- msg: return true, nil default: return false, nil } } else { return false, cont } } }) resultChan := make(chan error, 0) go server.actor(path, openFlags, filemode, mapSize, dbiStruct, resultChan, writerHead, readerHead) result := <-resultChan if result == nil { return server, nil } else { return nil, result } }