Server Perf #86
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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_REQUIRE_TRUSTED_EVIDENCE: "true" | |
| 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 |