Merge branch 'cassandra-2.2' into cassandra-3.0

This commit is contained in:
Sylvain Lebresne 2016-02-02 14:59:41 +01:00
commit b087b4c7d5
3 changed files with 58 additions and 34 deletions

View File

@ -59,6 +59,7 @@ Merged from 2.2:
* Verify tables in pseudo-system keyspaces at startup (CASSANDRA-10761)
* (cqlsh) encode input correctly when saving history
Merged from 2.1:
* test_bulk_round_trip_blogposts is failing occasionally (CASSANDRA-10938)
* Fix isJoined return true only after becoming cluster member (CASANDRA-11007)
* Fix bad gossip generation seen in long-running clusters (CASSANDRA-10969)
* Avoid NPE when incremental repair fails (CASSANDRA-10909)

View File

@ -1107,7 +1107,7 @@ class ExportSession(object):
session.default_timeout = export_process.options.copy['pagetimeout']
export_process.printdebugmsg("Created connection to %s with page size %d and timeout %d seconds per page"
% (session.hosts, session.default_fetch_size, session.default_timeout))
% (cluster.contact_points, session.default_fetch_size, session.default_timeout))
self.cluster = cluster
self.session = session
@ -1176,16 +1176,20 @@ class ExportProcess(ChildProcess):
token_range, info = self.inmsg.get()
self.start_request(token_range, info)
def report_error(self, err, token_range=None):
@staticmethod
def get_error_message(err, print_traceback=False):
if isinstance(err, str):
msg = err
elif isinstance(err, BaseException):
msg = "%s - %s" % (err.__class__.__name__, err)
if self.debug:
if print_traceback:
traceback.print_exc(err)
else:
msg = str(err)
return msg
def report_error(self, err, token_range=None):
msg = self.get_error_message(err, print_traceback=self.debug)
self.printdebugmsg(msg)
self.outmsg.put((token_range, Exception(msg)))
@ -1194,48 +1198,67 @@ class ExportProcess(ChildProcess):
Begin querying a range by executing an async query that
will later on invoke the callbacks attached in attach_callbacks.
"""
session = self.get_session(info['hosts'])
metadata = session.cluster.metadata.keyspaces[self.ks].tables[self.table]
query = self.prepare_query(metadata.partition_key, token_range, info['attempts'])
future = session.execute_async(query)
self.attach_callbacks(token_range, future, session)
session = self.get_session(info['hosts'], token_range)
if session:
metadata = session.cluster.metadata.keyspaces[self.ks].tables[self.table]
query = self.prepare_query(metadata.partition_key, token_range, info['attempts'])
future = session.execute_async(query)
self.attach_callbacks(token_range, future, session)
def num_requests(self):
return sum(session.num_requests() for session in self.hosts_to_sessions.values())
def get_session(self, hosts):
def get_session(self, hosts, token_range):
"""
We select a host to connect to. If we have no connections to one of the hosts
yet then we select this host, else we pick the one with the smallest number
of requests.
We return a session connected to one of the hosts passed in, which are valid replicas for
the token range. We sort replicas by favouring those without any active requests yet or with the
smallest number of requests. If we fail to connect we report an error so that the token will
be retried again later.
:return: An ExportSession connected to the chosen host.
"""
new_hosts = [h for h in hosts if h not in self.hosts_to_sessions]
if new_hosts:
host = new_hosts[0]
new_cluster = Cluster(
contact_points=(host,),
port=self.port,
cql_version=self.cql_version,
protocol_version=self.protocol_version,
auth_provider=self.auth_provider,
ssl_options=ssl_settings(host, self.config_file) if self.ssl else None,
load_balancing_policy=TokenAwarePolicy(WhiteListRoundRobinPolicy(hosts)),
default_retry_policy=ExpBackoffRetryPolicy(self),
compression=None,
control_connection_timeout=self.connect_timeout,
connect_timeout=self.connect_timeout)
# sorted replicas favouring those with no connections yet
hosts = sorted(hosts,
key=lambda hh: 0 if hh not in self.hosts_to_sessions else self.hosts_to_sessions[hh].requests)
session = ExportSession(new_cluster, self)
self.hosts_to_sessions[host] = session
return session
else:
host = min(hosts, key=lambda hh: self.hosts_to_sessions[hh].requests)
errors = []
ret = None
for host in hosts:
try:
ret = self.connect(host)
except Exception, e:
errors.append(self.get_error_message(e))
if ret:
if errors:
self.printdebugmsg("Warning: failed to connect to some replicas: %s" % (errors,))
return ret
self.report_error("Failed to connect to all replicas %s for %s, errors: %s" % (hosts, token_range, errors))
return None
def connect(self, host):
if host in self.hosts_to_sessions.keys():
session = self.hosts_to_sessions[host]
session.add_request()
return session
new_cluster = Cluster(
contact_points=(host,),
port=self.port,
cql_version=self.cql_version,
protocol_version=self.protocol_version,
auth_provider=self.auth_provider,
ssl_options=ssl_settings(host, self.config_file) if self.ssl else None,
load_balancing_policy=WhiteListRoundRobinPolicy([host]),
default_retry_policy=ExpBackoffRetryPolicy(self),
compression=None,
control_connection_timeout=self.connect_timeout,
connect_timeout=self.connect_timeout)
session = ExportSession(new_cluster, self)
self.hosts_to_sessions[host] = session
return session
def attach_callbacks(self, token_range, future, session):
def result_callback(rows):
if future.has_more_pages:

View File

@ -17,6 +17,7 @@
*/
package org.apache.cassandra.transport;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import io.netty.channel.Channel;
@ -24,7 +25,6 @@ import org.apache.cassandra.auth.IAuthenticator;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
import org.cliffc.high_scale_lib.NonBlockingHashMap;
public class ServerConnection extends Connection
{
@ -34,7 +34,7 @@ public class ServerConnection extends Connection
private final ClientState clientState;
private volatile State state;
private final ConcurrentMap<Integer, QueryState> queryStates = new NonBlockingHashMap<>();
private final ConcurrentMap<Integer, QueryState> queryStates = new ConcurrentHashMap<>();
public ServerConnection(Channel channel, int version, Connection.Tracker tracker)
{