Add --requestTimeout flag for process instance creation#73
Conversation
Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
Co-authored-by: vobu <6573426+vobu@users.noreply.github.com>
|
@copilot merge current |
The branch is already up-to-date with main. Both are based on commit 6758764 (v2.1.0-alpha.1), so there's nothing to merge. Build successful ✓ |
|
This has been released in 2.1.0-alpha.2. |
There was a problem hiding this comment.
Pull request overview
This PR adds the --requestTimeout flag to the create pi and await pi commands, allowing users to specify a custom timeout in milliseconds when waiting for process instance completion with --awaitCompletion. The implementation follows the existing CLI option pattern and maps directly to the Camunda REST API's requestTimeout parameter.
Changes:
- Added
--requestTimeout <ms>CLI flag that accepts milliseconds (default: 0 = cluster timeout) - Updated help text, README, EXAMPLES, and shell completions for bash/zsh/fish
- Simplified docker-compose infrastructure for testing (8.9 uses H2, 8.8 hardcoded to elasticsearch)
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/index.ts | Added requestTimeout parsing and passing to createProcessInstance for both create pi and await pi commands |
| src/commands/process-instances.ts | Added requestTimeout parameter to createProcessInstance function and API request |
| src/commands/help.ts | Added documentation for --requestTimeout flag in general help, create help, and await help |
| src/commands/completion.ts | Added --requestTimeout to bash, zsh, and fish shell completions |
| tests/unit/help.test.ts | Added assertion to verify --requestTimeout appears in help output |
| README.md | Added examples showing --requestTimeout usage with create and await commands |
| EXAMPLES.md | Added examples and explanation of --requestTimeout behavior |
| assets/c8/8.9/docker-compose.yml | Simplified test infrastructure to use H2 in-memory database instead of Elasticsearch |
| assets/c8/8.9/.env | Added default Camunda version configuration for docker-compose |
| assets/c8/8.8/docker-compose.yml | Hardcoded database dependency to elasticsearch instead of using variable |
| assets/c8/8.8/.env | Added elasticsearch profile configuration for docker-compose |
| .gitignore | Added exception to allow .env files in assets directory |
| .github/workflows/test.yml | Updated to use simplified docker-compose commands without DATABASE variable |
| .github/workflows/release.yml | Updated to use simplified docker-compose commands without DATABASE variable |
| package-lock.json | Added "peer": true metadata to several dev dependencies (incidental change) |
| variables: values.variables as string | undefined, | ||
| awaitCompletion: values.awaitCompletion as boolean | undefined, | ||
| fetchVariables: values.fetchVariables as boolean | undefined, | ||
| requestTimeout: (values.requestTimeout && typeof values.requestTimeout === 'string') ? parseInt(values.requestTimeout) : undefined, |
There was a problem hiding this comment.
Missing input validation for requestTimeout. The parseInt call could result in NaN for invalid input (e.g., --requestTimeout=abc), and negative values aren't validated. Consider adding validation similar to:
if (values.requestTimeout && typeof values.requestTimeout === 'string') {
const timeout = parseInt(values.requestTimeout);
if (isNaN(timeout) || timeout < 0) {
logger.error('requestTimeout must be a non-negative number');
process.exit(1);
}
requestTimeout = timeout;
}
This would provide clear error messages to users who provide invalid timeout values.
| variables: values.variables as string | undefined, | ||
| awaitCompletion: true, // Always true for await command | ||
| fetchVariables: values.fetchVariables as boolean | undefined, | ||
| requestTimeout: (values.requestTimeout && typeof values.requestTimeout === 'string') ? parseInt(values.requestTimeout) : undefined, |
There was a problem hiding this comment.
Same validation issue as line 352. Missing input validation for requestTimeout. Add validation to check for NaN and negative values before passing to createProcessInstance.
| // Set requestTimeout if provided | ||
| if (options.requestTimeout !== undefined) { | ||
| request.requestTimeout = options.requestTimeout; | ||
| } |
There was a problem hiding this comment.
Missing validation: requestTimeout should only be allowed when awaitCompletion is true. The help text states "use with --awaitCompletion" for the requestTimeout flag, but there's no validation enforcing this constraint.
Consider adding validation similar to the fetchVariables check on lines 136-139:
// Validate: requestTimeout requires awaitCompletion
if (options.requestTimeout !== undefined && !options.awaitCompletion) {
logger.error('--requestTimeout can only be used with --awaitCompletion');
process.exit(1);
}
This would provide clear feedback to users and prevent confusion when requestTimeout is used without awaitCompletion (where it would have no effect).
| services: | ||
| postgres: | ||
| container_name: postgres | ||
| image: postgres:17.5-alpine | ||
| ports: | ||
| - '5432:5432' | ||
| environment: | ||
| POSTGRES_DB: identity | ||
| POSTGRES_USER: identity | ||
| POSTGRES_PASSWORD: 't2L@!AqSMg8%I%NmHM' | ||
| networks: | ||
| - zeebe_network | ||
|
|
||
| elasticsearch: | ||
| image: docker.elastic.co/elasticsearch/elasticsearch:8.18.4 | ||
| container_name: elasticsearch | ||
| profiles: ['elasticsearch'] | ||
| environment: | ||
| - discovery.type=single-node | ||
| - cluster.name=elasticsearch | ||
| - bootstrap.memory_lock=true | ||
| - xpack.security.enabled=false | ||
| - 'ES_JAVA_OPTS=-Xms1024m -Xmx1024m' | ||
| - path.repo=/usr/local/els-snapshots | ||
| ulimits: | ||
| memlock: | ||
| soft: -1 | ||
| hard: -1 | ||
| ports: | ||
| - 9200:9200 | ||
| - 9300:9300 | ||
| networks: | ||
| - zeebe_network | ||
| restart: always | ||
| volumes: | ||
| - ./els-snapshots:/usr/local/els-snapshots | ||
|
|
||
| opensearch: | ||
| image: opensearchproject/opensearch:2.17.0 | ||
| container_name: opensearch | ||
| profiles: ['opensearch'] | ||
| environment: | ||
| - cluster.name=opensearch-cluster | ||
| - discovery.type=single-node | ||
| - plugins.security.disabled=true | ||
| - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping | ||
| - 'OPENSEARCH_JAVA_OPTS=-Xms1024m -Xmx1024m' # minimum and maximum Java heap size, recommend setting both to 50% of system RAM | ||
| - OPENSEARCH_INITIAL_ADMIN_PASSWORD=yourStrongPassword123! | ||
| ulimits: | ||
| memlock: | ||
| soft: -1 | ||
| hard: -1 | ||
| nofile: | ||
| soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems | ||
| hard: 65536 | ||
| ports: | ||
| - 9200:9200 | ||
| - 9605:9605 # required for Performance Analyzer | ||
| networks: | ||
| - zeebe_network | ||
|
|
||
| kibana: | ||
| image: docker.elastic.co/kibana/kibana:8.18.4 | ||
| profiles: ['elasticsearch'] | ||
| ports: | ||
| - 5601:5601 | ||
| environment: | ||
| - elasticsearch.hosts=http://elasticsearch:9200 | ||
| depends_on: | ||
| - elasticsearch | ||
| networks: | ||
| - zeebe_network | ||
|
|
||
| keycloak: | ||
| depends_on: | ||
| - postgres | ||
| container_name: keycloak | ||
| image: quay.io/keycloak/keycloak:26.0 | ||
| command: start-dev --http-relative-path=/auth | ||
| ports: | ||
| - '18080:8080' | ||
| environment: | ||
| KC_DB: postgres | ||
| KC_DB_URL: jdbc:postgresql://postgres:5432/identity | ||
| KC_DB_USERNAME: identity | ||
| KC_DB_PASSWORD: 't2L@!AqSMg8%I%NmHM' | ||
| KEYCLOAK_ADMIN: admin | ||
| KEYCLOAK_ADMIN_PASSWORD: admin | ||
| healthcheck: | ||
| test: ['CMD-SHELL', 'exec 3<>/dev/tcp/localhost/8080 && echo -e "GET /auth/health/ready HTTP/1.1\nhost: localhost:8080\n" >&3 && timeout 1 cat <&3 | grep "200 OK"'] | ||
| interval: 30s | ||
| timeout: 15s | ||
| retries: 8 | ||
| start_period: 30s | ||
| networks: | ||
| - zeebe_network | ||
|
|
||
| camunda: | ||
| image: camunda/camunda:${CAMUNDA_VERSION} | ||
| container_name: camunda | ||
| image: camunda/camunda:SNAPSHOT | ||
| environment: | ||
| - 'JAVA_TOOL_OPTIONS=-Xms512m -Xmx1g' | ||
| - ZEEBE_BROKER_NETWORK_HOST=camunda | ||
| - SPRING_PROFILES_ACTIVE=e2e-test,consolidated-auth,tasklist,broker,operate,identity | ||
| - CAMUNDA_SECURITY_AUTHENTICATION_UNPROTECTEDAPI=false | ||
| - CAMUNDA_SECURITY_AUTHORIZATIONS_ENABLED=true | ||
| - CAMUNDA_SECURITY_AUTHENTICATION_METHOD=BASIC | ||
| - CAMUNDA_SECURITY_MULTITENANCY_CHECKSENABLED=false | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_0_USERNAME=demo | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_0_PASSWORD=demo | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_0_NAME=Demo | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_0_EMAIL=demo@example.com | ||
| - CAMUNDA_SECURITY_INITIALIZATION_DEFAULTROLES_ADMIN_USERS_0=demo | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_1_USERNAME=lisa | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_1_PASSWORD=lisa | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_1_NAME=lisa | ||
| - CAMUNDA_SECURITY_INITIALIZATION_USERS_1_EMAIL=lisa@example.com | ||
| - CAMUNDA_SECURITY_INITIALIZATION_DEFAULTROLES_ADMIN_USERS_1=lisa | ||
| - CAMUNDA_DATA_SECONDARY_STORAGE_TYPE=elasticsearch | ||
| - CAMUNDA_DATA_SECONDARY_STORAGE_ELASTICSEARCH_URL=http://elasticsearch:9200 | ||
| - CAMUNDA_DATA_SECONDARYSTORAGE_ELASTICSEARCH_WAITFORIMPORTERS=false | ||
| - CAMUNDA_TASKLIST_V2_MODE_ENABLED=${CAMUNDA_TASKLIST_V2_MODE_ENABLED:-true} | ||
| SPRING_PROFILES_ACTIVE: 'broker,consolidated-auth' | ||
| ZEEBE_CLOCK_CONTROLLED: 'true' | ||
| ZEEBE_LOG_APPENDER: 'Stackdriver' | ||
| CAMUNDA_SECURITY_AUTHENTICATION_UNPROTECTEDAPI: 'true' | ||
| CAMUNDA_SECURITY_AUTHORIZATIONS_ENABLED: 'false' | ||
| # H2 / in-memory config (mirrors H2Configuration) | ||
| CAMUNDA_DATABASE_URL: 'jdbc:h2:mem:cpt;DB_CLOSE_DELAY=-1;MODE=PostgreSQL' | ||
| CAMUNDA_DATABASE_TYPE: 'rdbms' | ||
| CAMUNDA_DATABASE_USERNAME: 'sa' | ||
| CAMUNDA_DATABASE_PASSWORD: '' | ||
| CAMUNDA_DATA_SECONDARY_STORAGE_TYPE: 'rdbms' | ||
| ZEEBE_BROKER_EXPORTERS_RDBMS_CLASSNAME: 'io.camunda.exporter.rdbms.RdbmsExporter' | ||
| ZEEBE_BROKER_EXPORTERS_RDBMS_ARGS_FLUSH_INTERVAL: 'PT0S' | ||
| ZEEBE_BROKER_EXPORTERS_RDBMS_ARGS_DEFAULT_HISTORY_TTL: 'PT2S' | ||
| ZEEBE_BROKER_EXPORTERS_RDBMS_ARGS_MIN_HISTORY_CLEANUP_INTERVAL: 'PT2S' | ||
| ZEEBE_BROKER_EXPORTERS_RDBMS_ARGS_MAX_HISTORY_CLEANUP_INTERVAL: 'PT5S' | ||
| LOGGING_LEVEL_IO_CAMUNDA_DB_RDBMS: 'INFO' | ||
| LOGGING_LEVEL_ORG_MYBATIS: 'INFO' | ||
| ports: | ||
| - 26500:26500 | ||
| - 9600:9600 | ||
| - 8080:8080 | ||
| depends_on: | ||
| - ${DATABASE} | ||
| - '8080:8080' # REST API (ZEEBE_REST_ADDRESS -> http://localhost:8080) | ||
| - '26500:26500' # gRPC Gateway | ||
| - '9600:9600' # Monitoring / actuator / test time control | ||
| # Uncomment if you need direct access to internal broker ports: | ||
| # - "26501:26501" # Command API (internal) | ||
| # - "26502:26502" # Internal API (internal) | ||
| healthcheck: | ||
| # Mimic readiness checks: uses monitoring port + health endpoint | ||
| test: ['CMD', 'wget', '-qO', '-', 'http://localhost:9600/actuator/health/status'] | ||
| interval: 5s | ||
| timeout: 3s | ||
| retries: 30 | ||
| networks: | ||
| - zeebe_network | ||
| env_file: | ||
| - envs/.env.database.${DATABASE} | ||
| - camunda-net | ||
|
|
||
| # connectors: | ||
| # image: camunda/connectors-bundle:SNAPSHOT | ||
| # container_name: camunda-connectors | ||
| # depends_on: | ||
| # camunda: | ||
| # condition: service_healthy | ||
| # environment: | ||
| # # Adapted from runtime: service name + internal port | ||
| # ZEEBE_CLIENT_BROKER_GATEWAY-ADDRESS: "camunda:26500" | ||
| # ZEEBE_CLIENT_SECURITY_PLAINTEXT: "true" | ||
| # # Optional additional env you might pass via framework (placeholders): | ||
| # # CONNECTORS_LOG_APPENDER: "Stackdriver" | ||
| # # CAMUNDA_CLIENT_GRPC-ADDRESS: "camunda:26500" | ||
| # # CAMUNDA_CLIENT_REST-ADDRESS: "http://camunda:8080" | ||
| # ports: | ||
| # - "8085:8080" # Expose connectors runtime (external 8085 -> internal 8080) | ||
| # networks: | ||
| # - camunda-net | ||
|
|
||
| networks: | ||
| camunda-net: | ||
| name: camunda-net |
There was a problem hiding this comment.
The docker-compose infrastructure changes appear to be unrelated to the --requestTimeout feature. This PR should focus on adding the requestTimeout flag. Infrastructure simplifications (switching 8.9 to H2, hardcoding elasticsearch for 8.8, etc.) should be in a separate PR for easier review and to maintain clear commit history per the coding guidelines.
| assert.ok(output.includes('--variables')); | ||
| assert.ok(output.includes('--awaitCompletion')); | ||
| assert.ok(output.includes('--fetchVariables')); | ||
| assert.ok(output.includes('--requestTimeout')); |
There was a problem hiding this comment.
Missing integration test coverage for the --requestTimeout flag. Per the coding guidelines (CodingGuidelineID: 1000000), "for every implementation, make sure to add or update tests that cover the new functionality. This includes unit tests for individual functions and integration tests for end-to-end scenarios."
There should be integration tests that verify:
- The requestTimeout parameter is correctly passed to the API when using
create pi --awaitCompletion --requestTimeout=<ms> - The requestTimeout parameter is correctly passed when using
await pi --requestTimeout=<ms> - The timeout value is properly parsed from the command line (e.g., testing with a valid timeout value)
These tests should be added to tests/integration/process-instances.test.ts following the existing patterns for awaitCompletion tests.
|
This has been released in 2.1.0. |
(ping back to https://github.com/camunda/product-hub/issues/2638 for tracability)
Adds
--requestTimeoutoption to control server-side wait timeout when using--awaitCompletionorawaitcommands.Changes
--requestTimeout <ms>flag accepting milliseconds (default: 0 = cluster timeout)requestTimeoutparameterUsage
Maps to the
requestTimeoutfield in the Create Process Instance API.Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.