Skip to content

Commit 78f5542

Browse files
committed
compression: better handle configuration problems
1. Throw an exception on cluster initialization when concrete compression is configured, but library is not available 2. Log an error only once at cluster initialization if compression is True, but no library is available. 3. Throw an exception on cluster initialization if compression is something else but string and bool
1 parent 5225556 commit 78f5542

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

cassandra/cluster.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from itertools import groupby, count, chain
3030
import json
3131
import logging
32-
from typing import Optional
32+
from typing import Optional, Union
3333
from warnings import warn
3434
from random import random
3535
import re
@@ -51,7 +51,7 @@
5151
from cassandra.connection import (ConnectionException, ConnectionShutdown,
5252
ConnectionHeartbeat, ProtocolVersionUnsupported,
5353
EndPoint, DefaultEndPoint, DefaultEndPointFactory,
54-
SniEndPointFactory, ConnectionBusy)
54+
SniEndPointFactory, ConnectionBusy, locally_supported_compressions)
5555
from cassandra.cqltypes import UserType
5656
import cassandra.cqltypes as types
5757
from cassandra.encoder import Encoder
@@ -686,7 +686,7 @@ class Cluster(object):
686686
Used for testing new protocol features incrementally before the new version is complete.
687687
"""
688688

689-
compression = True
689+
compression: Union[bool, str] = True
690690
"""
691691
Controls compression for communications between the driver and Cassandra.
692692
If left as the default of :const:`True`, either lz4 or snappy compression
@@ -1173,7 +1173,7 @@ def token_metadata_enabled(self, enabled):
11731173
def __init__(self,
11741174
contact_points=_NOT_SET,
11751175
port=9042,
1176-
compression=True,
1176+
compression: Union[bool, str] = True,
11771177
auth_provider=None,
11781178
load_balancing_policy=None,
11791179
reconnection_policy=None,
@@ -1302,6 +1302,24 @@ def __init__(self,
13021302

13031303
self._resolve_hostnames()
13041304

1305+
if isinstance(compression, bool):
1306+
if compression and not locally_supported_compressions:
1307+
log.error(
1308+
"Compression is enabled, but no compression libraries are available. "
1309+
"Disabling compression, consider installing one of the Python packages: lz4 and/or python-snappy."
1310+
)
1311+
compression = False
1312+
elif isinstance(compression, str):
1313+
if not locally_supported_compressions.get(compression):
1314+
raise ValueError(
1315+
"Compression '%s' was requested, but it is not available. "
1316+
"Consider installing the corresponding Python package." % compression
1317+
)
1318+
else:
1319+
raise TypeError(
1320+
"The 'compression' option must be either a string (e.g., 'lz4' or 'snappy') "
1321+
"or a boolean (True to enable any available compression, False to disable it)."
1322+
)
13051323
self.compression = compression
13061324

13071325
if protocol_version is not _NOT_SET:

cassandra/connection.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import weakref
2929
import random
3030
import itertools
31-
from typing import Optional
31+
from typing import Optional, Union
3232

3333
from cassandra.application_info import ApplicationInfoBase
3434
from cassandra.protocol_features import ProtocolFeatures
@@ -679,7 +679,7 @@ class Connection(object):
679679
protocol_version = ProtocolVersion.MAX_SUPPORTED
680680

681681
keyspace = None
682-
compression = True
682+
compression: Union[bool, str] = True
683683
_compression_type = None
684684
compressor = None
685685
decompressor = None
@@ -760,7 +760,7 @@ def _iobuf(self):
760760
return self._io_buffer.io_buffer
761761

762762
def __init__(self, host='127.0.0.1', port=9042, authenticator=None,
763-
ssl_options=None, sockopts=None, compression=True,
763+
ssl_options=None, sockopts=None, compression: Union[bool, str] = True,
764764
cql_version=None, protocol_version=ProtocolVersion.MAX_SUPPORTED, is_control_connection=False,
765765
user_type_map=None, connect_timeout=None, allow_beta_protocol_version=False, no_compact=False,
766766
ssl_context=None, owning_pool=None, shard_id=None, total_shards=None,
@@ -1383,10 +1383,11 @@ def _handle_options_response(self, options_response):
13831383
overlap = (set(locally_supported_compressions.keys()) &
13841384
set(remote_supported_compressions))
13851385
if len(overlap) == 0:
1386-
log.error("No available compression types supported on both ends."
1387-
" locally supported: %r. remotely supported: %r",
1388-
locally_supported_compressions.keys(),
1389-
remote_supported_compressions)
1386+
if locally_supported_compressions:
1387+
log.error("No available compression types supported on both ends."
1388+
" locally supported: %r. remotely supported: %r",
1389+
locally_supported_compressions.keys(),
1390+
remote_supported_compressions)
13901391
else:
13911392
compression_type = None
13921393
if isinstance(self.compression, str):

0 commit comments

Comments
 (0)