Skip to content

Commit a79cc2a

Browse files
committed
created a base function to compute resources
1 parent ea42bf5 commit a79cc2a

File tree

3 files changed

+52
-31
lines changed

3 files changed

+52
-31
lines changed

packages/service-library/src/servicelib/docker_utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,33 @@ async def _pull_image_with_retry() -> None:
326326
)
327327

328328
await _pull_image_with_retry()
329+
330+
331+
_CPUS_SAFE_MARGIN: Final[float] = (
332+
1.4 # accounts for machine overhead (ops + sidecar itself)
333+
)
334+
_MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO: Final[float] = (
335+
0.1 # NOTE: machines always have less available RAM than advertised
336+
)
337+
_SIDECARS_OPS_SAFE_RAM_MARGIN: Final[ByteSize] = TypeAdapter(ByteSize).validate_python(
338+
"1GiB"
339+
)
340+
DYNAMIC_SIDECAR_MIN_CPUS: Final[float] = 0.5
341+
342+
343+
def estimate_dynamic_sidecar_resources_from_ec2_instance(
344+
cpus: float, ram: int
345+
) -> tuple[float, int]:
346+
"""Estimates the resources available to a dynamic-sidecar running in an EC2 instance,
347+
taking into account safe margins for CPU and RAM, as the EC2 full resources are not completely visible
348+
349+
Returns:
350+
tuple: Estimated resources for the dynamic-sidecar (cpus, ram).
351+
"""
352+
# dynamic-sidecar usually needs less CPU
353+
sidecar_cpus = max(DYNAMIC_SIDECAR_MIN_CPUS, cpus - _CPUS_SAFE_MARGIN)
354+
sidecar_ram = int(
355+
ram - _MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO * ram - _SIDECARS_OPS_SAFE_RAM_MARGIN
356+
)
357+
358+
return (sidecar_cpus, sidecar_ram)

services/autoscaling/src/simcore_service_autoscaling/modules/cluster_scaling/_provider_dynamic.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
import dataclasses
2-
from typing import Final
32

43
from aws_library.ec2 import EC2InstanceData, EC2Tags, Resources
54
from aws_library.ec2._models import EC2InstanceType
65
from fastapi import FastAPI
76
from models_library.docker import DockerLabelKey
87
from models_library.generated_models.docker_rest_api import Node, Task
9-
from pydantic import ByteSize, TypeAdapter
8+
from pydantic import ByteSize
9+
from servicelib.docker_utils import estimate_dynamic_sidecar_resources_from_ec2_instance
1010
from types_aiobotocore_ec2.literals import InstanceTypeType
1111

1212
from ...core.settings import get_application_settings
1313
from ...models import AssociatedInstance
1414
from ...utils import utils_docker, utils_ec2
1515
from ..docker import get_docker_client
1616

17-
_MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO: Final[float] = (
18-
0.1 # NOTE: machines always have less available RAM than advertised
19-
)
20-
_SIDECARS_OPS_SAFE_RAM_MARGIN: Final[ByteSize] = TypeAdapter(ByteSize).validate_python(
21-
"1GiB"
22-
)
23-
_CPUS_SAFE_MARGIN: Final[float] = 1.4
24-
_MIN_NUM_CPUS: Final[float] = 0.5
25-
2617

2718
class DynamicAutoscalingProvider:
2819
async def get_monitored_nodes(self, app: FastAPI) -> list[Node]:
@@ -132,13 +123,12 @@ def adjust_instance_type_resources(
132123
) -> EC2InstanceType:
133124
assert self # nosec
134125
assert app # nosec
135-
# nothing to do at the moment
136-
adjusted_cpus = float(instance_type.resources.cpus) - _CPUS_SAFE_MARGIN
137-
adjusted_ram = int(
138-
instance_type.resources.ram
139-
- _MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO * instance_type.resources.ram
140-
- _SIDECARS_OPS_SAFE_RAM_MARGIN
126+
adjusted_cpus, adjusted_ram = (
127+
estimate_dynamic_sidecar_resources_from_ec2_instance(
128+
instance_type.resources.cpus, instance_type.resources.ram
129+
)
141130
)
131+
142132
return dataclasses.replace(
143133
instance_type,
144134
resources=instance_type.resources.model_copy(

services/web/server/src/simcore_service_webserver/projects/_projects_service.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@
8888
X_FORWARDED_PROTO,
8989
X_SIMCORE_USER_AGENT,
9090
)
91+
from servicelib.docker_utils import (
92+
DYNAMIC_SIDECAR_MIN_CPUS,
93+
estimate_dynamic_sidecar_resources_from_ec2_instance,
94+
)
9195
from servicelib.logging_utils import log_context
9296
from servicelib.rabbitmq import RemoteMethodNotRegisteredError, RPCServerError
9397
from servicelib.rabbitmq.rpc_interfaces.catalog import services as catalog_rpc
@@ -652,12 +656,12 @@ def _by_type_name(ec2: EC2InstanceTypeGet) -> bool:
652656
app, user_id, project_id, node_id, service_key, service_version
653657
)
654658
scalable_service_name = DEFAULT_SINGLE_SERVICE_NAME
655-
new_cpus_value = float(selected_ec2_instance_type.cpus) - _CPUS_SAFE_MARGIN
656-
new_ram_value = int(
657-
selected_ec2_instance_type.ram
658-
- _MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO * selected_ec2_instance_type.ram
659-
- _SIDECARS_OPS_SAFE_RAM_MARGIN
659+
new_cpus_value, new_ram_value = (
660+
estimate_dynamic_sidecar_resources_from_ec2_instance(
661+
selected_ec2_instance_type.cpus, selected_ec2_instance_type.ram
662+
)
660663
)
664+
661665
if DEFAULT_SINGLE_SERVICE_NAME not in node_resources:
662666
# NOTE: we go for the largest sub-service and scale it up/down
663667
scalable_service_name, hungry_service_resources = max(
@@ -680,17 +684,14 @@ def _by_type_name(ec2: EC2InstanceTypeGet) -> bool:
680684
}
681685
)
682686
new_cpus_value = max(
683-
float(selected_ec2_instance_type.cpus)
684-
- _CPUS_SAFE_MARGIN
685-
- other_services_resources["CPU"],
686-
_MIN_NUM_CPUS,
687+
new_cpus_value - other_services_resources["CPU"],
688+
DYNAMIC_SIDECAR_MIN_CPUS,
687689
)
688-
new_ram_value = int(
689-
selected_ec2_instance_type.ram
690-
- _MACHINE_TOTAL_RAM_SAFE_MARGIN_RATIO * selected_ec2_instance_type.ram
691-
- other_services_resources["RAM"]
692-
- _SIDECARS_OPS_SAFE_RAM_MARGIN
690+
691+
new_ram_value = max(
692+
int(new_ram_value - other_services_resources["RAM"]), 128 * 1024 * 1024
693693
)
694+
694695
# scale the service
695696
node_resources[scalable_service_name].resources["CPU"].set_value(new_cpus_value)
696697
node_resources[scalable_service_name].resources["RAM"].set_value(new_ram_value)

0 commit comments

Comments
 (0)