modal 1.1.4.dev15__tar.gz → 1.1.4.dev17__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.4.dev15 → modal-1.1.4.dev17}/PKG-INFO +1 -1
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/client.pyi +2 -2
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/experimental/flash.py +33 -12
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api.proto +1 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api_pb2.py +546 -546
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api_pb2.pyi +6 -1
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_version/__init__.py +1 -1
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/LICENSE +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/README.md +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/__main__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_clustered_functions.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_container_entrypoint.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_functions.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_ipython.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_location.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_object.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_output.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_partial_function.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_pty.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_resolver.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_resources.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/asgi.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_serialization.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_traceback.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_tunnel.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_tunnel.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_type_manager.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/blob_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/function_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/logger.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/_watcher.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/app.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/app.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/README.md +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/builder/base-images.json +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/call_graph.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/_download.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/_traceback.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/app.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/cluster.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/config.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/container.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/dict.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/entry_point.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/environment.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/import_refs.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/launch.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/profile.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/queues.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/run.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/secret.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/token.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/utils.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cli/volume.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/client.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cls.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/cls.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/config.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/container_process.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/container_process.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/dict.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/dict.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/environments.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/environments.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/exception.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/experimental/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/experimental/flash.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/experimental/ipython.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/file_io.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/file_io.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/functions.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/functions.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/gpu.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/image.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/image.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/io_streams.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/io_streams.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/mount.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/mount.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/network_file_system.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/network_file_system.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/object.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/object.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/output.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/parallel_map.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/parallel_map.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/partial_function.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/partial_function.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/proxy.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/proxy.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/py.typed +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/queue.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/queue.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/retries.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/runner.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/runner.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/running_app.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/sandbox.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/sandbox.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/schedule.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/scheduler_placement.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/secret.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/secret.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/serving.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/serving.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/snapshot.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/snapshot.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/stream_type.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/token_flow.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/token_flow.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/volume.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal/volume.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/requires.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/__init__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options.proto +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_proto/py.typed +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/modal_version/__main__.py +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/pyproject.toml +0 -0
- {modal-1.1.4.dev15 → modal-1.1.4.dev17}/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.4.
|
36
|
+
version: str = "1.1.4.dev17",
|
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.4.
|
167
|
+
version: str = "1.1.4.dev17",
|
168
168
|
):
|
169
169
|
"""mdmd:hidden
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -213,8 +213,8 @@ class _FlashPrometheusAutoscaler:
|
|
213
213
|
)
|
214
214
|
|
215
215
|
logger.warning(
|
216
|
-
f"[Modal Flash] Scaling to {actual_target_containers} containers.
|
217
|
-
f"made in {time.time() - autoscaling_time} seconds."
|
216
|
+
f"[Modal Flash] Scaling to {actual_target_containers=} containers. "
|
217
|
+
f" Autoscaling decision made in {time.time() - autoscaling_time} seconds."
|
218
218
|
)
|
219
219
|
|
220
220
|
await self.autoscaling_decisions_dict.put(
|
@@ -223,9 +223,7 @@ class _FlashPrometheusAutoscaler:
|
|
223
223
|
)
|
224
224
|
await self.autoscaling_decisions_dict.put("current_replicas", actual_target_containers)
|
225
225
|
|
226
|
-
await self.cls.update_autoscaler(
|
227
|
-
min_containers=actual_target_containers,
|
228
|
-
)
|
226
|
+
await self.cls.update_autoscaler(min_containers=actual_target_containers)
|
229
227
|
|
230
228
|
if time.time() - autoscaling_time < self.autoscaling_interval_seconds:
|
231
229
|
await asyncio.sleep(self.autoscaling_interval_seconds - (time.time() - autoscaling_time))
|
@@ -239,6 +237,8 @@ class _FlashPrometheusAutoscaler:
|
|
239
237
|
await asyncio.sleep(self.autoscaling_interval_seconds)
|
240
238
|
|
241
239
|
async def _compute_target_containers(self, current_replicas: int) -> int:
|
240
|
+
# current_replicas is the number of live containers + cold starting containers (not yet live)
|
241
|
+
# containers is the number of live containers that are registered in flash dns
|
242
242
|
containers = await self._get_all_containers()
|
243
243
|
if len(containers) > current_replicas:
|
244
244
|
logger.info(
|
@@ -271,11 +271,17 @@ class _FlashPrometheusAutoscaler:
|
|
271
271
|
sum_metric += container_metrics[target_metric][0].value
|
272
272
|
containers_with_metrics += 1
|
273
273
|
|
274
|
+
# n_containers_missing_metric is the number of unhealthy containers + number of cold starting containers
|
274
275
|
n_containers_missing_metric = current_replicas - containers_with_metrics
|
276
|
+
# n_containers_unhealthy is the number of live containers that are not emitting metrics i.e. unhealthy
|
277
|
+
n_containers_unhealthy = len(containers) - containers_with_metrics
|
278
|
+
|
279
|
+
# Scale up assuming that every unhealthy container is at 2x the target metric value.
|
280
|
+
scale_up_target_metric_value = (sum_metric + n_containers_unhealthy * target_metric_value) / (
|
281
|
+
(containers_with_metrics + n_containers_unhealthy) or 1
|
282
|
+
)
|
275
283
|
|
276
|
-
# Scale
|
277
|
-
# value of the metric when scaling up and the maximum value of the metric when scaling down.
|
278
|
-
scale_up_target_metric_value = sum_metric / (containers_with_metrics or 1)
|
284
|
+
# Scale down assuming that every container (including cold starting containers) are at the target metric value.
|
279
285
|
scale_down_target_metric_value = (
|
280
286
|
sum_metric + n_containers_missing_metric * target_metric_value
|
281
287
|
) / current_replicas
|
@@ -290,9 +296,14 @@ class _FlashPrometheusAutoscaler:
|
|
290
296
|
desired_replicas = math.ceil(current_replicas * scale_down_ratio)
|
291
297
|
|
292
298
|
logger.warning(
|
293
|
-
f"[Modal Flash] Current replicas: {current_replicas},
|
294
|
-
f"
|
295
|
-
f"
|
299
|
+
f"[Modal Flash] Current replicas: {current_replicas}, "
|
300
|
+
f"target metric value: {target_metric_value}, "
|
301
|
+
f"current sum of metric values: {sum_metric}, "
|
302
|
+
f"number of containers with metrics: {containers_with_metrics}, "
|
303
|
+
f"number of containers unhealthy: {n_containers_unhealthy}, "
|
304
|
+
f"number of containers missing metric (includes unhealthy): {n_containers_missing_metric}, "
|
305
|
+
f"scale up ratio: {scale_up_ratio}, "
|
306
|
+
f"scale down ratio: {scale_down_ratio}, "
|
296
307
|
f"desired replicas: {desired_replicas}"
|
297
308
|
)
|
298
309
|
|
@@ -312,9 +323,19 @@ class _FlashPrometheusAutoscaler:
|
|
312
323
|
logger.warning(f"[Modal Flash] Error getting metrics from {url}: {e}")
|
313
324
|
return None
|
314
325
|
|
326
|
+
# Read body with timeout/error handling and parse Prometheus metrics
|
327
|
+
try:
|
328
|
+
text_body = await response.text()
|
329
|
+
except asyncio.TimeoutError:
|
330
|
+
logger.warning(f"[Modal Flash] Timeout reading metrics body from {url}")
|
331
|
+
return None
|
332
|
+
except Exception as e:
|
333
|
+
logger.warning(f"[Modal Flash] Error reading metrics body from {url}: {e}")
|
334
|
+
return None
|
335
|
+
|
315
336
|
# Parse the text-based Prometheus metrics format
|
316
337
|
metrics: dict[str, list[Sample]] = defaultdict(list)
|
317
|
-
for family in text_string_to_metric_families(
|
338
|
+
for family in text_string_to_metric_families(text_body):
|
318
339
|
for sample in family.samples:
|
319
340
|
metrics[sample.name] += [sample]
|
320
341
|
|
@@ -1798,6 +1798,7 @@ message FunctionHandleMetadata {
|
|
1798
1798
|
optional string input_plane_region = 47;
|
1799
1799
|
// Use optional to ensure unset values default to None instead of 0
|
1800
1800
|
optional uint64 max_object_size_bytes = 48;
|
1801
|
+
repeated string _experimental_flash_urls = 49; // (Optional) urls for flash services
|
1801
1802
|
}
|
1802
1803
|
|
1803
1804
|
message FunctionInput {
|