Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
cbe98dc
Initial asyncio commit
yuce Sep 19, 2025
162fd17
Updates
yuce Sep 19, 2025
9931956
Updates
yuce Sep 19, 2025
856e3df
Merge branch 'master' into asyncio-module
yuce Sep 19, 2025
35384bf
Black
yuce Sep 19, 2025
fdda120
Updates
yuce Sep 19, 2025
fee5b45
Updates
yuce Sep 19, 2025
fc2c38b
Updates
yuce Sep 19, 2025
1772031
Removed docs, include HazelcastClient/Map in public API
yuce Sep 19, 2025
170cf89
Updates
yuce Sep 19, 2025
539c904
Merge branch 'master' into asyncio-module
yuce Sep 22, 2025
22449a8
black
yuce Sep 22, 2025
5406bc6
Ignore incorrect mypy errors
yuce Sep 22, 2025
a417a4a
Updates
yuce Sep 24, 2025
d00c480
Updates
yuce Sep 25, 2025
baa3bc1
Annotate optional params
yuce Sep 29, 2025
ebfc9e2
black
yuce Sep 29, 2025
6928837
Remove update to test util
yuce Sep 30, 2025
3e03cbf
black
yuce Sep 30, 2025
51ced7a
black
yuce Sep 30, 2025
e635b94
update
yuce Sep 30, 2025
4f103f6
Added support for SSL
yuce Sep 30, 2025
042cc58
Added SSL tests
yuce Sep 30, 2025
265a2b4
Added mutual authentication test
yuce Sep 30, 2025
293975d
Added hostname verification tests
yuce Oct 1, 2025
2718478
black
yuce Oct 1, 2025
58783dc
Ported more integration tests
yuce Oct 1, 2025
3cf9982
Ported hazelcast json value test
yuce Oct 2, 2025
7e97ec7
Merge branch 'master' into asyncio-module-integration-tests1
yuce Oct 2, 2025
6a558e8
Merge branch 'master' into asyncio-module-ssl
yuce Oct 2, 2025
a630706
Merge branch 'master' into asyncio-module
yuce Oct 2, 2025
c1798ea
Ported heart beat test
yuce Oct 2, 2025
e92936a
Ported more tests
yuce Oct 20, 2025
6ced889
Merge branch 'master' into asyncio-module
yuce Oct 20, 2025
c313bfa
Merge branch 'master' into asyncio-module-ssl
yuce Oct 20, 2025
6222c6b
Merge branch 'master' into asyncio-module-integration-tests1
yuce Oct 20, 2025
120a58a
black
yuce Oct 22, 2025
80880b8
Fixed type hints
yuce Oct 30, 2025
6431acc
type hints
yuce Nov 14, 2025
91bf1d1
Addressed review comment
yuce Nov 21, 2025
2128f5e
Removed unnecessary code
yuce Nov 21, 2025
62697e3
Add BETA warning
yuce Nov 21, 2025
a87a5c6
Black
yuce Nov 21, 2025
8d7eede
Merge branch 'asyncio-module' into asyncio-module-ssl
yuce Nov 24, 2025
00a2d12
Merge branch 'asyncio-module-ssl' into asyncio-module-integration-tests1
yuce Nov 24, 2025
e673679
Updated test_heartbeat_stopped_and_restored
yuce Nov 25, 2025
1ca7fd6
Addressed review comment
yuce Nov 26, 2025
d9acede
updates
yuce Nov 28, 2025
bd23f41
Merge branch 'asyncio-module-ssl' into asyncio-module-integration-tests1
yuce Nov 28, 2025
2a2d6e8
Merge branch 'master' into asyncio-module-integration-tests1
yuce Dec 1, 2025
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ check:
black --check --config black.toml .

test:
pytest -m "not enterprise"
pytest --verbose -m "not enterprise"

test-enterprise:
pytest
pytest --verbose

test-cover:
pytest --cov=hazelcast --cov-report=xml
2 changes: 0 additions & 2 deletions hazelcast/asyncio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ def _init_context(self):
)

async def _start(self):
self._reactor.start()
try:
self._internal_lifecycle_service.start()
self._invocation_service.start()
Expand Down Expand Up @@ -250,7 +249,6 @@ async def shutdown(self) -> None:
await self._connection_manager.shutdown()
self._invocation_service.shutdown()
self._statistics.shutdown()
self._reactor.shutdown()
self._internal_lifecycle_service.fire_lifecycle_event(LifecycleState.SHUTDOWN)

@property
Expand Down
39 changes: 23 additions & 16 deletions hazelcast/internal/asyncio_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ def __init__(
self._use_public_ip = (
isinstance(address_provider, DefaultAddressProvider) and config.use_public_ip
)
# asyncio tasks are weakly referenced
# storing tasks here in order not to lose them midway
self._tasks = set()

def add_listener(self, on_connection_opened=None, on_connection_closed=None):
"""Registers a ConnectionListener.
Expand Down Expand Up @@ -315,22 +318,21 @@ async def on_connection_close(self, closed_connection):
disconnected = False
removed = False
trigger_reconnection = False
async with self._lock:
connection = self.active_connections.get(remote_uuid, None)
if connection == closed_connection:
self.active_connections.pop(remote_uuid, None)
removed = True
_logger.info(
"Removed connection to %s:%s, connection: %s",
remote_address,
remote_uuid,
connection,
)
connection = self.active_connections.get(remote_uuid, None)
if connection == closed_connection:
self.active_connections.pop(remote_uuid, None)
removed = True
_logger.info(
"Removed connection to %s:%s, connection: %s",
remote_address,
remote_uuid,
connection,
)

if not self.active_connections:
trigger_reconnection = True
if self._client_state == ClientState.INITIALIZED_ON_CLUSTER:
disconnected = True
if not self.active_connections:
trigger_reconnection = True
if self._client_state == ClientState.INITIALIZED_ON_CLUSTER:
disconnected = True

if disconnected:
self._lifecycle_service.fire_lifecycle_event(LifecycleState.DISCONNECTED)
Expand Down Expand Up @@ -809,6 +811,9 @@ def __init__(self, connection_manager, client, config, reactor, invocation_servi
self._heartbeat_timeout = config.heartbeat_timeout
self._heartbeat_interval = config.heartbeat_interval
self._heartbeat_task: asyncio.Task | None = None
# asyncio tasks are weakly referenced
# storing tasks here in order not to lose them midway
self._tasks = set()

def start(self):
"""Starts sending periodic HeartBeat operations."""
Expand Down Expand Up @@ -848,7 +853,9 @@ async def _check_connection(self, now, connection):
if (now - connection.last_write_time) > self._heartbeat_interval:
request = client_ping_codec.encode_request()
invocation = Invocation(request, connection=connection, urgent=True)
asyncio.create_task(self._invocation_service.ainvoke(invocation))
task = asyncio.create_task(self._invocation_service.ainvoke(invocation))
self._tasks.add(task)
task.add_done_callback(self._tasks.discard)


_frame_header = struct.Struct("<iH")
Expand Down
17 changes: 7 additions & 10 deletions hazelcast/internal/asyncio_reactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,13 @@

class AsyncioReactor:
def __init__(self, loop: AbstractEventLoop | None = None):
self._is_live = False
self._loop = loop or asyncio.get_running_loop()
self._bytes_sent = 0
self._bytes_received = 0

def add_timer(self, delay, callback):
return self._loop.call_later(delay, callback)

def start(self):
self._is_live = True

def shutdown(self):
if not self._is_live:
return
# TODO: cancel tasks

async def connection_factory(
self, connection_manager, connection_id, address: Address, network_config, message_callback
):
Expand Down Expand Up @@ -70,6 +61,7 @@ def __init__(
self._address = address
self._config = config
self._proto = None
self.connected_address = address

@classmethod
async def create_and_connect(
Expand Down Expand Up @@ -174,6 +166,9 @@ def __init__(self, conn: AsyncioConnection):
self._write_buf_size = 0
self._recv_buf = None
self._alive = True
# asyncio tasks are weakly referenced
# storing tasks here in order not to lose them midway
self._tasks: set = set()

def connection_made(self, transport: transports.BaseTransport):
self._transport = transport
Expand All @@ -184,7 +179,9 @@ def connection_made(self, transport: transports.BaseTransport):

def connection_lost(self, exc):
self._alive = False
self._conn._loop.create_task(self._conn.close_connection(str(exc), None))
task = self._conn._loop.create_task(self._conn.close_connection(str(exc), None))
self._tasks.add(task)
task.add_done_callback(self._tasks.discard)
return False

def close(self):
Expand Down
Loading