Skip to content

Commit 610e4d0

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 27ca050 commit 610e4d0

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

cassandra/cluster.py

Lines changed: 21 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,23 @@ 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+
"Consider installing one of the Python packages: lz4 or python-snappy."
1310+
)
1311+
elif isinstance(compression, str):
1312+
if not locally_supported_compressions.get(compression):
1313+
raise ValueError(
1314+
"Compression '%s' was requested, but it is not available. "
1315+
"Consider installing the corresponding Python package." % compression
1316+
)
1317+
else:
1318+
raise TypeError(
1319+
"The 'compression' option must be either a string (e.g., 'lz4' or 'snappy') "
1320+
"or a boolean (True to enable any available compression, False to disable it)."
1321+
)
13051322
self.compression = compression
13061323

13071324
if protocol_version is not _NOT_SET:

cassandra/connection.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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)