diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03a3033fb..5f679c371 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -256,7 +256,7 @@ jobs: - name: Instantiate sample project using verdaccio artifacts - Fetch ESM run: | node scripts/init-from-verdaccio.js --registry-dir ${{ steps.tmp-dir.outputs.dir }}/npm-registry --sample https://github.com/temporalio/samples-typescript/tree/main/fetch-esm --target-dir ${{ steps.tmp-dir.outputs.dir }}/sample-fetch-esm - node scripts/test-example.js --work-dir "${{ steps.tmp-dir.outputs.dir }}/sample-fetch-esm" + node scripts/test-example.js --work-dir "${{ steps.tmp-dir.outputs.dir }}/sample-fetch-esm" --script-name workflow-local --expected-output "Hello World And Hello Wonderful Temporal!" # End samples diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index 850db67c8..0c5ee51a1 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit 850db67c87ac9208da53df1cd82f8a36d71c5227 +Subproject commit 0c5ee51a1fc66507204eb0c5ae35b3b3b25216bb diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index d0d0cdff3..8f1e64f32 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -166,6 +166,9 @@ pub fn worker_complete_workflow_activation( ), } } + CompleteWfError::WorkflowNotEnabled => { + BridgeError::UnexpectedError(format!("{err}")) + } }) }) } @@ -225,6 +228,9 @@ pub fn worker_complete_activity_task( field: None, message: format!("Malformed Activity Completion: {reason:?}"), }, + CompleteActivityError::ActivityNotEnabled => { + BridgeError::UnexpectedError(format!("{err}")) + } }) }) } @@ -470,7 +476,7 @@ mod config { ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, PollerBehavior as CorePollerBehavior, SlotKind, WorkerConfig, WorkerConfigBuilder, WorkerConfigBuilderError, WorkerDeploymentOptions as CoreWorkerDeploymentOptions, - WorkerDeploymentVersion as CoreWorkerDeploymentVersion, WorkflowSlotKind, + WorkerDeploymentVersion as CoreWorkerDeploymentVersion, WorkerTaskTypes, WorkflowSlotKind, }; use temporalio_sdk_core::{ ResourceBasedSlotsOptions, ResourceBasedSlotsOptionsBuilder, ResourceSlotOptions, @@ -499,7 +505,9 @@ mod config { workflow_task_poller_behavior: PollerBehavior, activity_task_poller_behavior: PollerBehavior, nexus_task_poller_behavior: PollerBehavior, - enable_non_local_activities: bool, + enable_workflow_tasks: bool, + enable_activity_tasks: bool, + enable_nexus_tasks: bool, sticky_queue_schedule_to_start_timeout: Duration, max_cached_workflows: usize, max_heartbeat_throttle_interval: Duration, @@ -566,7 +574,6 @@ mod config { .workflow_task_poller_behavior(self.workflow_task_poller_behavior) .activity_task_poller_behavior(self.activity_task_poller_behavior) .nexus_task_poller_behavior(self.nexus_task_poller_behavior) - .no_remote_activities(!self.enable_non_local_activities) .sticky_queue_schedule_to_start_timeout(self.sticky_queue_schedule_to_start_timeout) .max_cached_workflows(self.max_cached_workflows) .max_heartbeat_throttle_interval(self.max_heartbeat_throttle_interval) @@ -574,6 +581,11 @@ mod config { .max_task_queue_activities_per_second(self.max_task_queue_activities_per_second) .max_worker_activities_per_second(self.max_activities_per_second) .graceful_shutdown_period(self.shutdown_grace_time) + .task_types(WorkerTaskTypes { + enable_workflows: self.enable_workflow_tasks, + enable_activities: self.enable_activity_tasks, + enable_nexus: self.enable_nexus_tasks, + }) .build() } } diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index 2ddd20a1c..de81d3fb9 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -213,7 +213,9 @@ export interface WorkerOptions { workflowTaskPollerBehavior: PollerBehavior; activityTaskPollerBehavior: PollerBehavior; nexusTaskPollerBehavior: PollerBehavior; - enableNonLocalActivities: boolean; + enableWorkflowTasks: boolean; + enableActivityTasks: boolean; + enableNexusTasks: boolean; stickyQueueScheduleToStartTimeout: number; maxCachedWorkflows: number; maxHeartbeatThrottleInterval: number; diff --git a/packages/test/src/test-bridge.ts b/packages/test/src/test-bridge.ts index df14e0183..6447bc849 100644 --- a/packages/test/src/test-bridge.ts +++ b/packages/test/src/test-bridge.ts @@ -298,7 +298,9 @@ const GenericConfigs = { initial: 5, maximum: 100, }, - enableNonLocalActivities: false, + enableWorkflowTasks: true, + enableActivityTasks: true, + enableNexusTasks: true, stickyQueueScheduleToStartTimeout: 1000, maxCachedWorkflows: 1000, maxHeartbeatThrottleInterval: 1000, diff --git a/packages/test/src/test-integration-workflows.ts b/packages/test/src/test-integration-workflows.ts index 32620bee8..32a43781c 100644 --- a/packages/test/src/test-integration-workflows.ts +++ b/packages/test/src/test-integration-workflows.ts @@ -1403,7 +1403,7 @@ test('root execution is exposed', async (t) => { } } }; - await waitUntil(childStarted, 5000); + await waitUntil(childStarted, 8000); const childDesc = await childHandle.describe(); const parentDesc = await handle.describe(); diff --git a/packages/test/src/test-prometheus.ts b/packages/test/src/test-prometheus.ts index 264547402..18c5d7964 100644 --- a/packages/test/src/test-prometheus.ts +++ b/packages/test/src/test-prometheus.ts @@ -109,15 +109,22 @@ test.serial('Exporting Prometheus metrics from Core works with lots of options', 'temporal_workflow_task_replay_latency_seconds_bucket{namespace="default",' + 'service_name="temporal-core-sdk",task_queue="test-prometheus",' + 'workflow_type="successString",my_tag="my_value",le="0.001"}' - ) + ), + `Actual: \n-------\n${text}\n-------` ); // Verify histogram overrides - t.assert(text.match(/temporal_request_latency_seconds_bucket\{.*,le="31415"/)); - t.assert(text.match(/workflow_task_execution_latency_seconds_bucket\{.*,le="31415"/)); + t.assert( + text.match(/temporal_request_latency_seconds_bucket\{.*,le="31415"/), + `Actual: \n-------\n${text}\n-------` + ); + t.assert( + text.match(/workflow_task_execution_latency_seconds_bucket\{.*,le="31415"/), + `Actual: \n-------\n${text}\n-------` + ); // Verify prefix exists on client request metrics - t.assert(text.includes('temporal_long_request{')); + t.assert(text.includes('temporal_long_request{'), `Actual: \n-------\n${text}\n-------`); }); } finally { await localEnv.teardown(); diff --git a/packages/worker/src/worker-options.ts b/packages/worker/src/worker-options.ts index f04771623..a6f0ab8c9 100644 --- a/packages/worker/src/worker-options.ts +++ b/packages/worker/src/worker-options.ts @@ -1090,7 +1090,9 @@ export function toNativeWorkerOptions(opts: CompiledWorkerOptionsWithBuildId): n workflowTaskPollerBehavior: toNativeTaskPollerBehavior(opts.workflowTaskPollerBehavior), activityTaskPollerBehavior: toNativeTaskPollerBehavior(opts.activityTaskPollerBehavior), nexusTaskPollerBehavior: toNativeTaskPollerBehavior(opts.nexusTaskPollerBehavior), - enableNonLocalActivities: opts.enableNonLocalActivities, + enableWorkflowTasks: opts.workflowBundle !== undefined || opts.workflowsPath !== undefined, + enableActivityTasks: opts.activities.size > 0 && opts.enableNonLocalActivities, + enableNexusTasks: opts.nexusServiceRegistry !== undefined, stickyQueueScheduleToStartTimeout: msToNumber(opts.stickyQueueScheduleToStartTimeout), maxCachedWorkflows: opts.maxCachedWorkflows, maxHeartbeatThrottleInterval: msToNumber(opts.maxHeartbeatThrottleInterval), diff --git a/scripts/test-example.js b/scripts/test-example.js index 0152b00c0..cd4a080c8 100644 --- a/scripts/test-example.js +++ b/scripts/test-example.js @@ -23,8 +23,8 @@ async function withWorker(workdir, fn) { } } -async function test(workdir) { - const { status, output } = spawnSync(npm, ['run', 'workflow'], { +async function test(workdir, scriptName, expectedOutput) { + const { status, output } = spawnSync(npm, ['run', scriptName], { cwd: workdir, shell, encoding: 'utf8', @@ -33,7 +33,7 @@ async function test(workdir) { if (status !== 0) { throw new Error('Failed to run workflow'); } - if (!output[1].includes('Hello, Temporal!\n')) { + if (!output[1].includes(`${expectedOutput}\n`)) { throw new Error(`Invalid output: "${output[1]}"`); } } @@ -41,13 +41,17 @@ async function test(workdir) { async function main() { const opts = arg({ '--work-dir': String, + '--script-name': String, + '--expected-output': String, }); const workdir = opts['--work-dir']; if (!workdir) { throw new Error('Missing required option --work-dir'); } + const scriptName = opts['--script-name'] ?? 'workflow'; + const expectedOutput = opts['--expected-output'] ?? 'Hello, Temporal!'; - await withWorker(workdir, () => test(workdir)); + await withWorker(workdir, () => test(workdir, scriptName, expectedOutput)); } main()