// NewSession wraps an existing Node. func NewSession(cfg ClusterConfig) (*Session, error) { // Check that hosts in the ClusterConfig is not empty if len(cfg.Hosts) < 1 { return nil, ErrNoHosts } s := &Session{ cons: cfg.Consistency, prefetch: 0.25, cfg: cfg, pageSize: cfg.PageSize, stmtsLRU: &preparedLRU{lru: lru.New(cfg.MaxPreparedStmts)}, quit: make(chan struct{}), } s.nodeEvents = newEventDebouncer("NodeEvents", s.handleNodeEvent) s.schemaEvents = newEventDebouncer("SchemaEvents", s.handleSchemaEvent) s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo) s.hostSource = &ringDescriber{ session: s, closeChan: make(chan bool), } if cfg.PoolConfig.HostSelectionPolicy == nil { cfg.PoolConfig.HostSelectionPolicy = RoundRobinHostPolicy() } s.pool = cfg.PoolConfig.buildPool(s) s.policy = cfg.PoolConfig.HostSelectionPolicy s.executor = &queryExecutor{ pool: s.pool, policy: cfg.PoolConfig.HostSelectionPolicy, } if err := s.init(); err != nil { // TODO(zariel): dont wrap this error in fmt.Errorf, return a typed error s.Close() return nil, fmt.Errorf("gocql: unable to create session: %v", err) } if s.pool.Size() == 0 { // TODO(zariel): move this to init s.Close() return nil, ErrNoConnectionsStarted } return s, nil }
func initStmtsLRU(max int) { if stmtsLRU.lru != nil { stmtsLRU.Max(max) } else { stmtsLRU.lru = lru.New(max) } }
// NewSession wraps an existing Node. func NewSession(cfg ClusterConfig) (*Session, error) { //Check that hosts in the ClusterConfig is not empty if len(cfg.Hosts) < 1 { return nil, ErrNoHosts } //Adjust the size of the prepared statements cache to match the latest configuration stmtsLRU.Lock() initStmtsLRU(cfg.MaxPreparedStmts) stmtsLRU.Unlock() s := &Session{ cons: cfg.Consistency, prefetch: 0.25, cfg: cfg, pageSize: cfg.PageSize, } pool, err := cfg.PoolConfig.buildPool(s) if err != nil { return nil, err } s.pool = pool // See if there are any connections in the pool if pool.Size() == 0 { s.Close() return nil, ErrNoConnectionsStarted } s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo) // I think it might be a good idea to simplify this and make it always discover // hosts, maybe with more filters. if cfg.DiscoverHosts { s.hostSource = &ringDescriber{ session: s, dcFilter: cfg.Discovery.DcFilter, rackFilter: cfg.Discovery.RackFilter, closeChan: make(chan bool), } } if !cfg.disableControlConn { s.control = createControlConn(s) s.control.reconnect(false) // need to setup host source to check for rpc_address in system.local localHasRPCAddr, err := checkSystemLocal(s.control) if err != nil { log.Printf("gocql: unable to verify if system.local table contains rpc_address, falling back to connection address: %v", err) } if cfg.DiscoverHosts { s.hostSource.localHasRpcAddr = localHasRPCAddr } } if cfg.DiscoverHosts { s.hostSource.refreshRing() go s.hostSource.run(cfg.Discovery.Sleep) } return s, nil }
// NewSession wraps an existing Node. func NewSession(cfg ClusterConfig) (*Session, error) { //Check that hosts in the ClusterConfig is not empty if len(cfg.Hosts) < 1 { return nil, ErrNoHosts } s := &Session{ cons: cfg.Consistency, prefetch: 0.25, cfg: cfg, pageSize: cfg.PageSize, stmtsLRU: &preparedLRU{lru: lru.New(cfg.MaxPreparedStmts)}, } connCfg, err := connConfig(s) if err != nil { s.Close() return nil, fmt.Errorf("gocql: unable to create session: %v", err) } s.connCfg = connCfg s.nodeEvents = newEventDeouncer("NodeEvents", s.handleNodeEvent) s.schemaEvents = newEventDeouncer("SchemaEvents", s.handleSchemaEvent) s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo) // I think it might be a good idea to simplify this and make it always discover // hosts, maybe with more filters. s.hostSource = &ringDescriber{ session: s, closeChan: make(chan bool), } pool := cfg.PoolConfig.buildPool(s) if cfg.PoolConfig.HostSelectionPolicy == nil { cfg.PoolConfig.HostSelectionPolicy = RoundRobinHostPolicy() } s.pool = pool s.policy = cfg.PoolConfig.HostSelectionPolicy s.executor = &queryExecutor{ pool: pool, policy: cfg.PoolConfig.HostSelectionPolicy, } var hosts []*HostInfo if !cfg.disableControlConn { s.control = createControlConn(s) if err := s.control.connect(cfg.Hosts); err != nil { s.Close() return nil, fmt.Errorf("gocql: unable to create session: %v", err) } // need to setup host source to check for broadcast_address in system.local localHasRPCAddr, _ := checkSystemLocal(s.control) s.hostSource.localHasRpcAddr = localHasRPCAddr var err error if cfg.DisableInitialHostLookup { // TODO: we could look at system.local to get token and other metadata // in this case. hosts, err = addrsToHosts(cfg.Hosts, cfg.Port) } else { hosts, _, err = s.hostSource.GetHosts() } if err != nil { s.Close() return nil, fmt.Errorf("gocql: unable to create session: %v", err) } } else { // we dont get host info hosts, err = addrsToHosts(cfg.Hosts, cfg.Port) } for _, host := range hosts { if s.cfg.HostFilter == nil || s.cfg.HostFilter.Accept(host) { if existingHost, ok := s.ring.addHostIfMissing(host); ok { existingHost.update(host) } s.handleNodeUp(net.ParseIP(host.Peer()), host.Port(), false) } } if cfg.ReconnectInterval > 0 { go s.reconnectDownedHosts(cfg.ReconnectInterval) } // TODO(zariel): we probably dont need this any more as we verify that we // can connect to one of the endpoints supplied by using the control conn. // See if there are any connections in the pool if s.pool.Size() == 0 { s.Close() return nil, ErrNoConnectionsStarted } s.useSystemSchema = hosts[0].Version().Major >= 3 return s, nil }
// NewSession wraps an existing Node. func NewSession(cfg ClusterConfig) (*Session, error) { //Check that hosts in the ClusterConfig is not empty if len(cfg.Hosts) < 1 { return nil, ErrNoHosts } //Adjust the size of the prepared statements cache to match the latest configuration stmtsLRU.Lock() initStmtsLRU(cfg.MaxPreparedStmts) stmtsLRU.Unlock() s := &Session{ cons: cfg.Consistency, prefetch: 0.25, cfg: cfg, pageSize: cfg.PageSize, } connCfg, err := connConfig(s) if err != nil { s.Close() return nil, fmt.Errorf("gocql: unable to create session: %v", err) } s.connCfg = connCfg s.nodeEvents = newEventDeouncer("NodeEvents", s.handleNodeEvent) s.routingKeyInfoCache.lru = lru.New(cfg.MaxRoutingKeyInfo) // I think it might be a good idea to simplify this and make it always discover // hosts, maybe with more filters. s.hostSource = &ringDescriber{ session: s, closeChan: make(chan bool), } s.pool = cfg.PoolConfig.buildPool(s) var hosts []*HostInfo if !cfg.disableControlConn { s.control = createControlConn(s) if err := s.control.connect(cfg.Hosts); err != nil { s.Close() return nil, err } // need to setup host source to check for broadcast_address in system.local localHasRPCAddr, _ := checkSystemLocal(s.control) s.hostSource.localHasRpcAddr = localHasRPCAddr hosts, _, err = s.hostSource.GetHosts() if err != nil { s.Close() return nil, err } } else { // we dont get host info hosts = make([]*HostInfo, len(cfg.Hosts)) for i, hostport := range cfg.Hosts { // TODO: remove duplication addr, portStr, err := net.SplitHostPort(JoinHostPort(hostport, cfg.Port)) if err != nil { s.Close() return nil, fmt.Errorf("NewSession: unable to parse hostport of addr %q: %v", hostport, err) } port, err := strconv.Atoi(portStr) if err != nil { s.Close() return nil, fmt.Errorf("NewSession: invalid port for hostport of addr %q: %v", hostport, err) } hosts[i] = &HostInfo{peer: addr, port: port, state: NodeUp} } } for _, host := range hosts { s.handleNodeUp(net.ParseIP(host.Peer()), host.Port(), false) } // TODO(zariel): we probably dont need this any more as we verify that we // can connect to one of the endpoints supplied by using the control conn. // See if there are any connections in the pool if s.pool.Size() == 0 { s.Close() return nil, ErrNoConnectionsStarted } return s, nil }