Skip to content

Cover bounded-growth runtime changes in perf CI #49

Cover bounded-growth runtime changes in perf CI

Cover bounded-growth runtime changes in perf CI #49

Workflow file for this run

name: Server Perf
on:
pull_request:
branches: [main]
paths:
- ".github/workflows/server-perf.yml"
- "Dockerfile"
- "docker-compose.yml"
- "app/Support/HistoryRetentionEnforcer.php"
- "app/Support/BoundedMetricPolicy.php"
- "app/Support/LongPollSignalStore.php"
- "app/Support/ProjectionDriftMetrics.php"
- "app/Support/ServerReadiness.php"
- "app/Support/ServerPollingCache.php"
- "app/Support/TaskQueueAdmission.php"
- "app/Support/WorkflowQueryTaskBroker.php"
- "app/Support/WorkflowTaskFailureMetrics.php"
- "app/Support/WorkflowTaskPoller.php"
- "app/Support/WorkflowTaskPollRequestStore.php"
- "app/Http/Controllers/Api/SystemController.php"
- "config/dw-bounded-growth.php"
- "config/server.php"
- "docs/bounded-growth.md"
- "routes/api.php"
- "scripts/perf/**"
- "tests/Unit/BoundedGrowthPolicyTest.php"
- "tests/Unit/BoundedMetricPolicyTest.php"
- "tests/Unit/ServerPerfHarnessContractTest.php"
- "tests/Feature/SystemMetricsTest.php"
push:
branches: [main]
paths:
- ".github/workflows/server-perf.yml"
- "Dockerfile"
- "docker-compose.yml"
- "app/Support/HistoryRetentionEnforcer.php"
- "app/Support/BoundedMetricPolicy.php"
- "app/Support/LongPollSignalStore.php"
- "app/Support/ProjectionDriftMetrics.php"
- "app/Support/ServerReadiness.php"
- "app/Support/ServerPollingCache.php"
- "app/Support/TaskQueueAdmission.php"
- "app/Support/WorkflowQueryTaskBroker.php"
- "app/Support/WorkflowTaskFailureMetrics.php"
- "app/Support/WorkflowTaskPoller.php"
- "app/Support/WorkflowTaskPollRequestStore.php"
- "app/Http/Controllers/Api/SystemController.php"
- "config/dw-bounded-growth.php"
- "config/server.php"
- "docs/bounded-growth.md"
- "routes/api.php"
- "scripts/perf/**"
- "tests/Unit/BoundedGrowthPolicyTest.php"
- "tests/Unit/BoundedMetricPolicyTest.php"
- "tests/Unit/ServerPerfHarnessContractTest.php"
- "tests/Feature/SystemMetricsTest.php"
schedule:
- cron: "17 7 * * *"
workflow_dispatch:
inputs:
duration_seconds:
description: "Soak duration in seconds"
required: false
default: "7200"
concurrency:
description: "Concurrent long-poll workers"
required: false
default: "24"
remote_write:
description: "Enable Prometheus remote_write when variables/secrets are configured"
required: false
type: boolean
default: true
permissions:
contents: read
concurrency:
group: server-perf-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: false
jobs:
contract:
name: Bounded-growth contract
if: github.event_name == 'pull_request' || github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout server
uses: actions/checkout@v6
- name: Checkout workflow package
uses: actions/checkout@v6
with:
repository: durable-workflow/workflow
ref: v2
path: workflow-package
- name: Run bounded-growth contract tests
run: |
docker run --rm \
-u "$(id -u):$(id -g)" \
-v "${PWD}:/app" \
-v "${PWD}/workflow-package:/workflow:ro" \
-w /app \
composer:2 \
sh -lc 'composer install --no-interaction --no-progress --prefer-dist && vendor/bin/phpunit tests/Unit/BoundedGrowthPolicyTest.php tests/Unit/ServerPerfHarnessContractTest.php --colors=never'
smoke:
name: Polling cache bounded-growth smoke
if: github.event_name == 'pull_request' || github.event_name == 'push'
needs: contract
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout server
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Run short perf smoke
env:
DW_PERF_DURATION_SECONDS: "120"
DW_PERF_CONCURRENCY: "8"
DW_PERF_NAMESPACES: "4"
DW_PERF_TASK_QUEUES: "8"
DW_PERF_MAX_SERVER_MEMORY_MB: "768"
DW_PERF_MAX_POLLING_KEYS: "512"
DW_PERF_MAX_FINAL_POLLING_KEYS: "0"
DW_PERF_MAX_SERVER_CACHE_KEYS_BY_POLICY: '{"workflow_task_poll_requests":512,"long_poll_signals":512,"workflow_query_tasks":64,"task_queue_admission_locks":128,"task_queue_dispatch_counters":128,"workflow_task_expired_lease_recovery":128,"history_retention_inline":64,"readiness_probe":16}'
DW_PERF_MAX_FINAL_SERVER_CACHE_KEYS_BY_POLICY: '{"workflow_task_poll_requests":0,"long_poll_signals":0,"workflow_query_tasks":0,"task_queue_admission_locks":0,"task_queue_dispatch_counters":0,"workflow_task_expired_lease_recovery":0,"history_retention_inline":0,"readiness_probe":0}'
RUNNER_ENVIRONMENT: "github-hosted"
run: scripts/perf/run-server-soak.sh
- name: Upload perf artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: server-perf-smoke
path: build/perf/
if-no-files-found: warn
soak:
name: Self-hosted polling cache soak
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: [self-hosted, linux, x64, perf-soak, server-perf]
timeout-minutes: 390
steps:
- name: Checkout server
uses: actions/checkout@v6
- name: Run long perf soak
env:
DW_PERF_DURATION_SECONDS: ${{ github.event_name == 'workflow_dispatch' && inputs.duration_seconds || '7200' }}
DW_PERF_CONCURRENCY: ${{ github.event_name == 'workflow_dispatch' && inputs.concurrency || '24' }}
DW_PERF_NAMESPACES: "8"
DW_PERF_TASK_QUEUES: "16"
DW_PERF_MAX_SERVER_MEMORY_MB: "1024"
DW_PERF_MAX_POLLING_KEYS: "2048"
DW_PERF_MAX_FINAL_POLLING_KEYS: "0"
DW_PERF_MAX_SERVER_CACHE_KEYS_BY_POLICY: '{"workflow_task_poll_requests":2048,"long_poll_signals":2048,"workflow_query_tasks":128,"task_queue_admission_locks":256,"task_queue_dispatch_counters":256,"workflow_task_expired_lease_recovery":256,"history_retention_inline":128,"readiness_probe":32}'
DW_PERF_MAX_FINAL_SERVER_CACHE_KEYS_BY_POLICY: '{"workflow_task_poll_requests":0,"long_poll_signals":0,"workflow_query_tasks":0,"task_queue_admission_locks":0,"task_queue_dispatch_counters":0,"workflow_task_expired_lease_recovery":0,"history_retention_inline":0,"readiness_probe":0}'
DW_PERF_MAX_SERVER_MEMORY_SLOPE_MB_HOUR: "128"
DW_PERF_REMOTE_WRITE_ENABLED: ${{ github.event_name != 'workflow_dispatch' || inputs.remote_write }}
DW_PERF_REMOTE_WRITE_URL: ${{ vars.DW_PERF_REMOTE_WRITE_URL }}
DW_PERF_REMOTE_WRITE_USERNAME: ${{ vars.DW_PERF_REMOTE_WRITE_USERNAME }}
DW_PERF_REMOTE_WRITE_PASSWORD: ${{ secrets.DW_PERF_REMOTE_WRITE_PASSWORD }}
RUNNER_ENVIRONMENT: "self-hosted"
run: scripts/perf/run-server-soak.sh
- name: Upload perf artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: server-perf-soak
path: build/perf/
if-no-files-found: warn