Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

124 lines
3.4 KiB
Python

"""Base deployer with common patterns and async support."""
import asyncio
from concurrent.futures import ThreadPoolExecutor
from typing import Any
import boto3
from botocore.config import Config
DEFAULT_REGION = "us-east-1"
# Thread pool for parallel boto3 operations
_executor = ThreadPoolExecutor(max_workers=10)
def get_boto3_client(service: str, region: str = DEFAULT_REGION) -> Any:
"""Get a boto3 client with standard configuration."""
config = Config(
retries={"max_attempts": 3, "mode": "adaptive"},
connect_timeout=10,
read_timeout=30,
)
return boto3.client(service, region_name=region, config=config) # type: ignore[call-overload]
def get_boto3_resource(service: str, region: str = DEFAULT_REGION) -> Any:
"""Get a boto3 resource with standard configuration."""
config = Config(
retries={"max_attempts": 3, "mode": "adaptive"},
connect_timeout=10,
read_timeout=30,
)
return boto3.resource(service, region_name=region, config=config) # type: ignore[call-overload]
def get_standard_tags(stack_name: str) -> list[dict[str, str]]:
"""Get standard tags for resources.
All resources are tagged with:
- tracer:stack = stack name
- tracer:managed = sdk
"""
return [
{"Key": "tracer:stack", "Value": stack_name},
{"Key": "tracer:managed", "Value": "sdk"},
]
def get_standard_tags_dict(stack_name: str) -> dict[str, str]:
"""Get standard tags as a dict (for services that use dict format)."""
return {
"tracer:stack": stack_name,
"tracer:managed": "sdk",
}
def get_standard_tags_ecs(stack_name: str) -> list[dict[str, str]]:
"""Get standard tags for ECS resources (uses lowercase key/value)."""
return [
{"key": "tracer:stack", "value": stack_name},
{"key": "tracer:managed", "value": "sdk"},
]
async def run_parallel(*coroutines: Any) -> list[Any]:
"""Run multiple async operations in parallel.
Args:
*coroutines: Async coroutines to run in parallel.
Returns:
List of results from all coroutines.
"""
return await asyncio.gather(*coroutines)
async def run_in_executor(func: Any, *args: Any) -> Any:
"""Run sync boto3 call in thread pool.
Args:
func: Synchronous function to run.
*args: Arguments to pass to the function.
Returns:
Result of the function call.
"""
loop = asyncio.get_event_loop()
return await loop.run_in_executor(_executor, func, *args)
def wait_for_condition(
check_func: Any,
max_attempts: int = 60,
delay_seconds: int = 5,
description: str = "condition",
) -> bool:
"""Wait for a condition to be true.
Args:
check_func: Function that returns True when condition is met.
max_attempts: Maximum number of attempts.
delay_seconds: Delay between attempts.
description: Description for error messages.
Returns:
True if condition was met.
Raises:
TimeoutError: If condition not met within max attempts.
"""
import time
for _attempt in range(max_attempts):
try:
if check_func():
return True
except Exception:
# AWS resource may not be ready yet; retry until timeout
time.sleep(delay_seconds)
continue
time.sleep(delay_seconds)
raise TimeoutError(f"Timeout waiting for {description} after {max_attempts * delay_seconds}s")