modal 1.1.5.dev2__tar.gz → 1.1.5.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/PKG-INFO +1 -1
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/client.pyi +2 -2
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/experimental/flash.py +37 -30
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/experimental/flash.pyi +11 -5
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_version/__init__.py +1 -1
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/LICENSE +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/README.md +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/__main__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_clustered_functions.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_container_entrypoint.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_functions.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_ipython.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_location.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_object.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_output.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_partial_function.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_pty.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_resolver.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_resources.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/asgi.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_serialization.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_traceback.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_tunnel.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_tunnel.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_type_manager.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/blob_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/function_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/logger.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/_watcher.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/app.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/app.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/README.md +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/builder/base-images.json +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/call_graph.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/_download.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/_traceback.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/app.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/cluster.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/config.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/container.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/dict.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/entry_point.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/environment.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/import_refs.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/launch.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/profile.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/queues.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/run.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/secret.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/token.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/utils.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cli/volume.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/client.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cls.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/cls.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/config.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/container_process.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/container_process.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/dict.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/dict.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/environments.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/environments.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/exception.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/experimental/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/experimental/ipython.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/file_io.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/file_io.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/functions.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/functions.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/gpu.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/image.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/image.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/io_streams.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/io_streams.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/mount.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/mount.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/network_file_system.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/network_file_system.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/object.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/object.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/output.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/parallel_map.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/parallel_map.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/partial_function.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/partial_function.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/proxy.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/proxy.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/py.typed +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/queue.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/queue.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/retries.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/runner.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/runner.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/running_app.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/sandbox.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/sandbox.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/schedule.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/scheduler_placement.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/secret.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/secret.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/serving.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/serving.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/snapshot.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/snapshot.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/stream_type.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/token_flow.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/token_flow.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/volume.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal/volume.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/requires.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/__init__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api.proto +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api_pb2.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options.proto +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_proto/py.typed +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/modal_version/__main__.py +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/pyproject.toml +0 -0
- {modal-1.1.5.dev2 → modal-1.1.5.dev3}/setup.cfg +0 -0
@@ -33,7 +33,7 @@ class _Client:
|
|
33
33
|
server_url: str,
|
34
34
|
client_type: int,
|
35
35
|
credentials: typing.Optional[tuple[str, str]],
|
36
|
-
version: str = "1.1.5.
|
36
|
+
version: str = "1.1.5.dev3",
|
37
37
|
):
|
38
38
|
"""mdmd:hidden
|
39
39
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -164,7 +164,7 @@ class Client:
|
|
164
164
|
server_url: str,
|
165
165
|
client_type: int,
|
166
166
|
credentials: typing.Optional[tuple[str, str]],
|
167
|
-
version: str = "1.1.5.
|
167
|
+
version: str = "1.1.5.dev3",
|
168
168
|
):
|
169
169
|
"""mdmd:hidden
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -21,7 +21,7 @@ from ..client import _Client
|
|
21
21
|
from ..config import logger
|
22
22
|
from ..exception import InvalidError
|
23
23
|
|
24
|
-
|
24
|
+
_MAX_FAILURES = 3
|
25
25
|
|
26
26
|
|
27
27
|
class _FlashManager:
|
@@ -42,7 +42,9 @@ class _FlashManager:
|
|
42
42
|
self.num_failures = 0
|
43
43
|
self.task_id = os.environ["MODAL_TASK_ID"]
|
44
44
|
|
45
|
-
async def
|
45
|
+
async def is_port_connection_healthy(
|
46
|
+
self, process: Optional[subprocess.Popen], timeout: int = 5
|
47
|
+
) -> tuple[bool, Optional[Exception]]:
|
46
48
|
import socket
|
47
49
|
|
48
50
|
start_time = time.monotonic()
|
@@ -50,13 +52,13 @@ class _FlashManager:
|
|
50
52
|
while time.monotonic() - start_time < timeout:
|
51
53
|
try:
|
52
54
|
if process is not None and process.poll() is not None:
|
53
|
-
return Exception(f"Process {process.pid} exited with code {process.returncode}")
|
55
|
+
return False, Exception(f"Process {process.pid} exited with code {process.returncode}")
|
54
56
|
with socket.create_connection(("localhost", self.port), timeout=1):
|
55
|
-
return
|
57
|
+
return True, None
|
56
58
|
except (ConnectionRefusedError, OSError):
|
57
59
|
await asyncio.sleep(0.1)
|
58
60
|
|
59
|
-
return Exception(f"Waited too long for port {self.port} to start accepting connections")
|
61
|
+
return False, Exception(f"Waited too long for port {self.port} to start accepting connections")
|
60
62
|
|
61
63
|
async def _start(self):
|
62
64
|
self.tunnel = await self.tunnel_manager.__aenter__()
|
@@ -74,7 +76,7 @@ class _FlashManager:
|
|
74
76
|
while True:
|
75
77
|
try:
|
76
78
|
# Check if the container should be drained (e.g., too many failures)
|
77
|
-
if self.num_failures >
|
79
|
+
if self.num_failures > _MAX_FAILURES:
|
78
80
|
logger.warning(
|
79
81
|
f"[Modal Flash] Draining task {self.task_id} on {self.tunnel.url} due to too many failures."
|
80
82
|
)
|
@@ -101,35 +103,38 @@ class _FlashManager:
|
|
101
103
|
first_registration = True
|
102
104
|
while True:
|
103
105
|
try:
|
104
|
-
await self.
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
106
|
+
port_check_resp, port_check_error = await self.is_port_connection_healthy(process=self.process)
|
107
|
+
if port_check_resp:
|
108
|
+
resp = await self.client.stub.FlashContainerRegister(
|
109
|
+
api_pb2.FlashContainerRegisterRequest(
|
110
|
+
priority=10,
|
111
|
+
weight=5,
|
112
|
+
host=host,
|
113
|
+
port=port,
|
114
|
+
),
|
115
|
+
timeout=10,
|
116
|
+
)
|
117
|
+
self.num_failures = 0
|
118
|
+
if first_registration:
|
119
|
+
logger.warning(
|
120
|
+
f"[Modal Flash] Listening at {resp.url} over {self.tunnel.url} for task_id {self.task_id}"
|
121
|
+
)
|
122
|
+
first_registration = False
|
123
|
+
else:
|
124
|
+
logger.error(
|
125
|
+
f"[Modal Flash] Deregistering container {self.task_id} on {self.tunnel.url} "
|
126
|
+
f"due to error: {port_check_error}, num_failures: {self.num_failures}"
|
127
|
+
)
|
128
|
+
self.num_failures += 1
|
129
|
+
await retry_transient_errors(
|
130
|
+
self.client.stub.FlashContainerDeregister,
|
131
|
+
api_pb2.FlashContainerDeregisterRequest(),
|
118
132
|
)
|
119
|
-
first_registration = False
|
120
133
|
except asyncio.CancelledError:
|
121
134
|
logger.warning("[Modal Flash] Shutting down...")
|
122
135
|
break
|
123
136
|
except Exception as e:
|
124
137
|
logger.error(f"[Modal Flash] Heartbeat failed: {e}")
|
125
|
-
self.num_failures += 1
|
126
|
-
logger.error(
|
127
|
-
f"[Modal Flash] Deregistering container {self.tunnel.url}, num_failures: {self.num_failures}"
|
128
|
-
)
|
129
|
-
await retry_transient_errors(
|
130
|
-
self.client.stub.FlashContainerDeregister,
|
131
|
-
api_pb2.FlashContainerDeregisterRequest(),
|
132
|
-
)
|
133
138
|
|
134
139
|
try:
|
135
140
|
await asyncio.sleep(1)
|
@@ -167,7 +172,9 @@ FlashManager = synchronize_api(_FlashManager)
|
|
167
172
|
|
168
173
|
@synchronizer.create_blocking
|
169
174
|
async def flash_forward(
|
170
|
-
port: int,
|
175
|
+
port: int,
|
176
|
+
process: Optional[subprocess.Popen] = None,
|
177
|
+
health_check_url: Optional[str] = None,
|
171
178
|
) -> _FlashManager:
|
172
179
|
"""
|
173
180
|
Forward a port to the Modal Flash service, exposing that port as a stable web endpoint.
|
@@ -15,7 +15,9 @@ class _FlashManager:
|
|
15
15
|
"""Initialize self. See help(type(self)) for accurate signature."""
|
16
16
|
...
|
17
17
|
|
18
|
-
async def
|
18
|
+
async def is_port_connection_healthy(
|
19
|
+
self, process: typing.Optional[subprocess.Popen], timeout: int = 5
|
20
|
+
) -> tuple[bool, typing.Optional[Exception]]: ...
|
19
21
|
async def _start(self): ...
|
20
22
|
async def _drain_container(self):
|
21
23
|
"""Background task that checks if we've encountered too many failures and drains the container if so."""
|
@@ -37,11 +39,15 @@ class FlashManager:
|
|
37
39
|
health_check_url: typing.Optional[str] = None,
|
38
40
|
): ...
|
39
41
|
|
40
|
-
class
|
41
|
-
def __call__(
|
42
|
-
|
42
|
+
class __is_port_connection_healthy_spec(typing_extensions.Protocol[SUPERSELF]):
|
43
|
+
def __call__(
|
44
|
+
self, /, process: typing.Optional[subprocess.Popen], timeout: int = 5
|
45
|
+
) -> tuple[bool, typing.Optional[Exception]]: ...
|
46
|
+
async def aio(
|
47
|
+
self, /, process: typing.Optional[subprocess.Popen], timeout: int = 5
|
48
|
+
) -> tuple[bool, typing.Optional[Exception]]: ...
|
43
49
|
|
44
|
-
|
50
|
+
is_port_connection_healthy: __is_port_connection_healthy_spec[typing_extensions.Self]
|
45
51
|
|
46
52
|
class ___start_spec(typing_extensions.Protocol[SUPERSELF]):
|
47
53
|
def __call__(self, /): ...
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|