Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9aa5ddc
Add optional query_params parameter to QueryMessage
sylwiaszunejko Mar 12, 2026
8bba6eb
Introduce skip_scylla_version_lt for integration tests
sylwiaszunejko Mar 13, 2026
bc864c1
Add client routes data types and route store
sylwiaszunejko Mar 17, 2026
ac91295
Add client routes handler for Private Link support
sylwiaszunejko Mar 17, 2026
1e0e6ca
Add ClientRoutesEndPoint and ClientRoutesEndPointFactory
sylwiaszunejko Mar 10, 2026
3202302
Integrate client routes handler into Cluster and ControlConnection
sylwiaszunejko Mar 10, 2026
b205f83
tests: add unit tests for client routes
sylwiaszunejko Mar 10, 2026
6743edd
tests: add integration tests for client routes
sylwiaszunejko Mar 11, 2026
efdc08a
Release 3.29.9: changelog, version and documentation
dkropachev Mar 18, 2026
fec90ae
Specify auth superuser name for tests (#759)
sylwiaszunejko Mar 23, 2026
153c913
(improvement) cqltypes: fast-path lookup_casstype() for simple type n…
mykaul Mar 6, 2026
70995bd
tests: remove redundant 10s sleep from setup_keyspace()
mykaul Mar 27, 2026
7931113
tests: replace high-priority time.sleep() calls with polling
mykaul Mar 27, 2026
4a23f72
tests: replace medium-priority time.sleep() calls with polling
mykaul Mar 27, 2026
9fe9931
tests: fix flaky tablet tests by increasing trace timeout and polling…
mykaul Mar 29, 2026
d31ea37
tests: replace fixed time.sleep() calls with polling (~17s saving)
mykaul Mar 29, 2026
e2a9511
Replace SCYLLA_EXT_OPTS env var with ccm updateconf options for auth …
sylwiaszunejko Mar 31, 2026
44cf752
chore(deps): update dependency pygments to v2.20.0 [security]
renovate[bot] Mar 30, 2026
d5f9d37
(fix) cluster: handle None control_connection_timeout in wait_for_sch…
mykaul Mar 26, 2026
94438c6
tests: fix flaky TestTwistedConnection.test_connection_initialization
mykaul Mar 26, 2026
4bff340
fix: correct 'clustering_key' to 'clustering' in column kind filter
mykaul Mar 24, 2026
ad12bed
chore(deps): update dependency tornado to v6.5.5 [security]
renovate[bot] Mar 30, 2026
c898583
metadata: conditionally skip triggers query for ScyllaDB
mykaul Dec 23, 2025
c3e2378
Fix code quality issues in test_cluster.py
Copilot Dec 23, 2025
8e6c4d4
Fix additional '== None' comparison for consistency
Copilot Dec 23, 2025
7224945
perf: optimize was_applied fast path for known LWT statements
mykaul Mar 15, 2026
f4ec874
bench: add micro-benchmark for was_applied fast path
mykaul Apr 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
3.29.9
======
March 18, 2026

Features
--------
* Add Private Link support via client routes handler
* Add optional query_params parameter to QueryMessage

Bug Fixes
---------
* Fix segmentation fault in libev prepare_callback during shutdown
* Add null checks to io_callback and timer_callback in libev wrapper
* Fix RecursionError in execute_concurrent on synchronous errbacks
* Fix floating-point precision loss for timestamps far from epoch

Others
------
* Cache parsed tablet routing type in ResponseFuture
* Remove deprecated setup_requires in favor of PEP 517 build-system.requires
* Update dependency hatchling to v1.29.0

3.29.8
======
February 09, 2026
Expand Down
72 changes: 72 additions & 0 deletions benchmarks/bench_was_applied.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright DataStax, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Micro-benchmark: was_applied fast path for known LWT statements.

Measures the speedup from skipping regex batch detection when the
query already knows it's an LWT statement (is_lwt() returns True).

Run:
python benchmarks/bench_was_applied.py
"""
import re
import timeit
from unittest.mock import Mock

from cassandra.query import named_tuple_factory, SimpleStatement, BatchStatement


def bench_was_applied():
"""Benchmark was_applied fast path vs slow path."""
batch_regex = re.compile(r'\s*BEGIN', re.IGNORECASE)

# Fast path: known LWT statement (BoundStatement-like, is_lwt=True)
lwt_query = Mock()
lwt_query.is_lwt.return_value = True

def fast_path():
query = lwt_query
if query.is_lwt() and not isinstance(query, BatchStatement):
# Fast path - known single LWT, skip batch detection
pass

# Slow path: non-LWT SimpleStatement (must check regex)
non_lwt_query = Mock(spec=SimpleStatement)
non_lwt_query.is_lwt.return_value = False
non_lwt_query.query_string = "INSERT INTO t (k, v) VALUES (1, 2) IF NOT EXISTS"

def slow_path():
query = non_lwt_query
if query.is_lwt() and not isinstance(query, BatchStatement):
pass
else:
isinstance(query, BatchStatement) or \
(isinstance(query, SimpleStatement) and batch_regex.match(query.query_string))

n = 500_000
t_fast = timeit.timeit(fast_path, number=n)
t_slow = timeit.timeit(slow_path, number=n)

print(f"Fast path (known LWT, {n} iters): {t_fast:.3f}s ({t_fast / n * 1e6:.2f} us/call)")
print(f"Slow path (regex check, {n} iters): {t_slow:.3f}s ({t_slow / n * 1e6:.2f} us/call)")
print(f"Speedup: {t_slow / t_fast:.1f}x")


def main():
bench_was_applied()


if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion cassandra/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def emit(self, record):

logging.getLogger('cassandra').addHandler(NullHandler())

__version_info__ = (3, 29, 8)
__version_info__ = (3, 29, 9)
__version__ = '.'.join(map(str, __version_info__))


Expand Down
Loading
Loading