chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# __client_script_begin__
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
||||
APPLICATION_NAME = "my-app"
|
||||
DEPLOYMENT_NAME = "TextProcessor"
|
||||
SERVE_ENDPOINT = "http://localhost:8265"
|
||||
SCALING_INTERVAL = 300 # Check every 5 minutes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_current_replicas(app_name: str, deployment_name: str) -> int:
|
||||
"""Get current replica count. Returns -1 on error."""
|
||||
try:
|
||||
resp = requests.get(
|
||||
f"{SERVE_ENDPOINT}/api/serve/applications/",
|
||||
timeout=10
|
||||
)
|
||||
if resp.status_code != 200:
|
||||
logger.error(f"Failed to get applications: {resp.status_code}")
|
||||
return -1
|
||||
|
||||
apps = resp.json().get("applications", {})
|
||||
if app_name not in apps:
|
||||
logger.error(f"Application {app_name} not found")
|
||||
return -1
|
||||
|
||||
deployments = apps[app_name].get("deployments", {})
|
||||
if deployment_name in deployments:
|
||||
return deployments[deployment_name]["target_num_replicas"]
|
||||
|
||||
logger.error(f"Deployment {deployment_name} not found")
|
||||
return -1
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Request failed: {e}")
|
||||
return -1
|
||||
|
||||
|
||||
def scale_deployment(app_name: str, deployment_name: str):
|
||||
"""Scale deployment based on time of day."""
|
||||
hour = datetime.now().hour
|
||||
current = get_current_replicas(app_name, deployment_name)
|
||||
|
||||
# Check if we successfully retrieved the current replica count
|
||||
if current == -1:
|
||||
logger.error("Failed to get current replicas, skipping scaling decision")
|
||||
return
|
||||
|
||||
target = 10 if 9 <= hour < 17 else 3 # Peak hours: 9am-5pm
|
||||
|
||||
delta = target - current
|
||||
if delta == 0:
|
||||
logger.info(f"Already at target ({current} replicas)")
|
||||
return
|
||||
|
||||
action = "Adding" if delta > 0 else "Removing"
|
||||
logger.info(f"{action} {abs(delta)} replicas ({current} -> {target})")
|
||||
|
||||
try:
|
||||
resp = requests.post(
|
||||
f"{SERVE_ENDPOINT}/api/v1/applications/{app_name}/deployments/{deployment_name}/scale",
|
||||
headers={"Content-Type": "application/json"},
|
||||
json={"target_num_replicas": target},
|
||||
timeout=10
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
logger.info("Successfully scaled deployment")
|
||||
else:
|
||||
logger.error(f"Scale failed: {resp.status_code} - {resp.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Request failed: {e}")
|
||||
|
||||
|
||||
def main():
|
||||
logger.info(f"Starting predictive scaling for {APPLICATION_NAME}/{DEPLOYMENT_NAME}")
|
||||
while True:
|
||||
scale_deployment(APPLICATION_NAME, DEPLOYMENT_NAME)
|
||||
time.sleep(SCALING_INTERVAL)
|
||||
# __client_script_end__
|
||||
Reference in New Issue
Block a user