Пример #1
0
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
}
Пример #2
0
// 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
}
Пример #3
0
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
}
Пример #4
0
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)
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
	}
}