Skip to content

Commit 21117f3

Browse files
thomasjpfanmodal-bot
authored andcommitted
Fix _connected in grpclib Channel (#54193)
GitOrigin-RevId: 0a65a95df46aeab69b8e614840aeecf726e1886f
1 parent db09abc commit 21117f3

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

py/CHANGELOG_DEV.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Added `Sandbox.logs`(/docs/sdk/py/latest/Sandbox#logs) namespace to retrieve Sandbox entrypoint logs directly from the SDK. The namespace has two different methods, allowing you `fetch()` logs from a specific date/time range, or `tail()` the most recent logs.
66
- Added support for setting the default member Role when creating Restricted Environments through the Python SDK and CLI.
77
- The `modal` CLI now accepts a global `--profile` option for simpler ad hoc profile selection.
8+
- Fixed gRPC channels attempting to reuse connections whose underlying transport is closing.
89
- `modal environment roles list --exclude-default` and
910
`Environment.roles.list(exclude_default=True)` list only users and service users who have been
1011
directly assigned a role for the Environment.

py/modal/_utils/grpc_utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ async def _create_connection(self) -> H2Protocol:
152152
)
153153
return protocol
154154

155+
@property
156+
def _connected(self) -> bool:
157+
return (
158+
self._protocol is not None
159+
# the H2Protocol handler does have connection_lost
160+
and not self._protocol.handler.connection_lost # type: ignore
161+
and not self._protocol.connection.is_closing()
162+
)
163+
155164
def close(self):
156165
self.__closed = True
157166
return super().close()

py/test/grpc_utils_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pytest
33
import time
44
import urllib.parse
5+
from unittest import mock
56

67
from google.protobuf.any_pb2 import Any
78
from grpclib import GRPCError, Status
@@ -393,6 +394,20 @@ async def test_ModalChannel(servicer):
393394
await client_stub.BlobCreate(req, metadata=metadata)
394395

395396

397+
@pytest.mark.asyncio
398+
def test_modal_channel_connected_checks_transport():
399+
channel = ModalChannel()
400+
assert not channel._connected
401+
402+
channel._protocol = mock.Mock() # type: ignore
403+
channel._protocol.handler.connection_lost = False # type: ignore
404+
channel._protocol.connection.is_closing.return_value = False # type: ignore
405+
assert channel._connected
406+
407+
channel._protocol.connection.is_closing.return_value = True
408+
assert not channel._connected
409+
410+
396411
@pytest.mark.asyncio
397412
async def test_create_channel_with_fallbacks_single_url(servicer):
398413
# With a single URL, the channel is created and connected normally.

0 commit comments

Comments
 (0)