Skip to content

Releases: temporalio/sdk-typescript

v1.8.6

13 Sep 23:00
Compare
Choose a tag to compare

Bug Fixes

  • [worker] Fix a memory leak introduced in v1.8.5 (#1242)

v1.8.5

12 Sep 20:59
Compare
Choose a tag to compare

Features

  • [workflow] Add historySizeInBytes and continueAsNewSuggested to WorkflowInfo (#1223).

  • Remove experimental flags on the following APIs (#1235):

    • Schedules
    • Failure Converters
    • Local Activities
    • Replay Histories

Bug Fixes

  • [workflow] Fix a particular case where isReplaying could be incorrectly false if a query came in right after a cache eviction and there had been a signal in the last workflow task before the cache eviction (#1234). This could notably cause situations where calls to sink functions configured with calledDuringReplay = false would be called more than once for a same code location, as well as situations where patched(...) would return true even though that patch had not been set on the first execution.

  • [workflow] Make ExternalWorkflowHandle.signal signature match that of BaseWorkflowHandle.signal (#1237). Thanks to @gabrielsantosblanchet and @josiah-roberts 🙏.

  • [worker] Avoid rxjs error while flushing logs on worker shutdown (#1238).

  • Upgrade protobufjs dependencies (#1219). Thanks to @alex-dixon 🙏.

1.8.4

22 Aug 21:07
Compare
Choose a tag to compare

Bug Fixes

  • [workflow] Fix a particular case where isReplaying would be incorrectly true if a query came in right after a cache eviction (#1211). This could notably cause situations where calls to sink functions not configured with calledDuringReplay = true would not be relayed, as well as situations where patched(...) would return false even though this part of the code was being executed for the first time.

  • [workflow] Avoid errors in Search Attributes Payload Converter if enumerable properties had been added on Array.prototype (#1209).

  • [worker] Validate buildId is set when useVersioning is true (#1207).

1.8.3

17 Aug 00:27
Compare
Choose a tag to compare

Bug Fixes

  • [workflow] Remove accidental import of large protos into workflow library (#1203). This had been causing significant memory usage increases on workflow workers since 1.8.1.
  • [core] Fix removal of deprecated patch call adjacent to other patch (#587)
  • [client] Throw WorkflowExecutionAlreadyStartedError on signalWithStart (#1199 thanks to @satazor 🙏)

1.8.2

04 Aug 21:15
Compare
Choose a tag to compare

Features

  • [workflow] Add support for URL/URLSearchParams inside the workflow sandbox (#1173)

  • [worker] Export the WorkerStatus interface (#1184).

Bug Fixes

  • Use custom symbol-based implementation of instanceof for all of our custom error classes (#1166). This is a complete rework of the fixes introduced in 1.8.0 and 1.8.1, both of which turned out to be insufficient. instanceof now works correctly both across execution contexts and when running tests with Jest.

    💥 The static is function introduced previously on some of our error classes is no longer required, as the instanceof operator itself now behave correctly; these is functions have therefore been removed.

  • [client] Make action.workflowId optional on Schedule update (#1176)

  • [activity] heartbeatTimeoutMs is now correctly set on Activity's Context.current().info. The currentAttemptScheduledTimestampMs property has also been added to that data structure (#1187)

  • [workflow] The Workflow Bundler is now smarter regarding requiring files with incorrect or missing file extensions (#1186). Thanks to @GauBen 🙏.

  • [workflow] Fix incorrect values of workflowInfo.historyLength and workflowInfo.unsafe.isReplaying as reported in out-of-sandbox log messages, and as argument of sink function implementations (#1181).

  • [workflow] Sink functions configured with callDuringReplay = false are no longer invoked from a replay-only worker (i.e. Worker.runReplayHistories()); it was previously possible for these to get called in some cases on the very last Workflow Task (#1181).

  • [workflow] Encoding and decoding of protobuf JSON payloads is now working in workflow context. This was previously failing, due to the fact that an underlying library depends on the Buffer class, which is not available inside the workflow sandbox (#1170). Thanks to @antlai-temporal 🙏.

  • [core] Improve warning message on error response to completion (temporalio/sdk-core#581) Thanks to @dandavison 🙏.

  • [core] Fix abandoned children nondeterminism if they complete (temporalio/sdk-core#580).

1.8.1

04 Aug 21:16
Compare
Choose a tag to compare

Bug Fixes

  • Remove instanceof Error checks from is methods (#1162). This fixes various regressions observed when running Workflow tests with Jest.

  • Add the VersioningIntent parameters on the experimental worker versioning feature (#1156). Also, all values of the ReachabilityType type has been converted to SCREAMING_CASE.

  • [workflow] Make workflows.log()'s attributes argument optional (#1159).

  • [workflow] Attach workflows.log()'s attributes to every workflow log message (#1159).

1.8.0

04 Aug 21:16
Compare
Choose a tag to compare

Features

  • [worker] Add support for worker versioning (#1146).

    Worker versioning is available from server version 1.21 (if enabled in dynamic configuration).

    ⚠️ Experimental - While the feature is well tested and is considered functionally stable, the SDK APIs are considered experimental.

    To use worker versioning with the TypeScript SDK, use the following steps:

    import { Client } from '@temporalio/client';
    import { Worker } from '@temporalio/worker';
    
    const buildId = 'id-generated-from-continuous-integration';
    
    // Deploy new workers, opt them in to versioning.
    const worker = await Worker.create({
      workflowsPath: require.resolve('./workflows'),
      buildId,
      useVersioning: true,
      // ...
    });
    
    // ...
    
    // In a separate process, when all workers are up, update the build id compatibility for the task queue.
    const client = new Client({
      /* options */
    });
    // If the current version is incompatible with the previous ones:
    await client.taskQueue.updateBuildIdCompatibility('my-task-queue', {
      operation: 'addNewIdInNewDefaultSet',
      buildId,
    });
    // Or, if the current version is compatible with a previous one:
    await client.taskQueue.updateBuildIdCompatibility('my-task-queue', {
      operation: 'addNewCompatibleVersion',
      buildId,
      existingCompatibleBuildId: 'some-other-build-id',
    });
    
    // Check if workers are reachable before retiring them (even if their build ids are associated with multiple task
    // queues):
    const { buildIdReachability } = await client.taskQueue.getReachability({ buildIds: ['some-other-build-id'] });
    const { taskQueueReachability } = buildIdReachability['some-other-build-id'];
    for (const [taskQueue, reachability] of Object.entries(taskQueueReachability)) {
      if (reachability.length > 0) {
        if (reachability[0] === 'NotFetched') {
          // We asked the server for too many reachability entries (build ids or task queues),
          // This build id / task queue reachability should be fetched in another request.
          // Fetch this information here or later...
        } else {
          console.log('Build id still reachable on:', taskQueue);
        }
      }
    }
    // Check if build id is reachable...
  • [worker] Add support for using multiple concurrent pollers to fetch Workflow Tasks and Activity Tasks from Task Queues (#1132).

    The number of pollers for each type can be controlled through the WorkerOptions.maxConcurrentWorkflowTaskPolls and WorkerOptions.maxConcurrentActivityTaskPolls properties. Properly adjusting these values should allow better filling of the corresponding execution slots, which may signficiantly improve a Worker's throughput. Defaults are 10 Workflow Task Pollers and 2 Activity Task Pollers; we however strongly recommend tuning these values based on workload specific performance tests.

    Default value for maxConcurrentWorkflowTaskExecutions has also been reduced to 40 (it was previously 100), as recent performance tests demonstrate that higher values increase the risk of Workflow Task Timeouts unless other options are also tuned. This was not problem previously because the single poller was unlikely to fill all execution slots, so maximum would rarely be reached.

  • [workflow] The reuseV8Context worker option is no longer marked as experimental (#1132). This is a major optimization of the Workflow sandboxing runtime; it allows the worker to reuse a single execution context across Workflow instances, without compromising the safety of the deterministic sandbox. It significantly reduces RAM and CPU usage. The formula used to auto-configure maxCachedWorkflows has also been reviewed to reflect a lower memory usage requirement when reuseV8Context is enabled.

    At this point, you still need to opt-in to this feature by adding reuseV8Context: true to your WorkerOptions, as we believe most teams should reconsider their workers's performance settings after enabling this option.

    💥 Note that we are planing enabling this option by default starting with 1.9.0. If for some reason, you prefer to delay enabling this optimization, then we recommend that you explicitly add reuseV8Context: false to your worker options.

  • We now provide out-of-the-box log support from both Workflows and Activity contexts (#1117, #1138)).

    For Workflows, the logger funnels messages through the defaultWorkerLogger sink, which itself defaults to forwarding messages to Runtime.instance().logger.

    Example usage:

    import * as workflow from '@temporalio/workflow';
    
    export async function myWorkflow(): Promise<void> {
      workflow.log.info('hello from my workflow', { key: 'value' });
    }

    For Activities, the logger can be accessed as Context.log. It defaults to Runtime.instance().logger, but may be overridden by interceptors (i.e. to set a custom logger). ActivityInboundLogInterceptor is still installed by default, adding enriched metadata from activity context on each log entry.

    Example usage:

    import * as activity from '@temporalio/activity';
    
    export async function myActivity(): Promise<void> {
      const context = activity.Context.current();
      context.log.info('hello from my activity', { key: 'value' });
    }
  • 💥 Protect against 'ms' durations errors (#1136). There have been several reports of situations where invalid durations resulted in unexpected and hard to diagnose issues (e.g. can you predict what const bool = condition(fn, '1 month') will do?). We now provide type definitions for "ms-formatted strings" through the newly introduced Duration type, which is either a well-formed ms-formatted string or a number of milliseconds. Invalid ms-formatted-strings will also throw at runtime.

    Note: this might cause build errors in situations where a non-const string value is passed somewhere we expect a Duration. Consider either validating and converting these strings before passing them as Duration, or simply cast them to Duration and deal with runtime exceptions that might be thrown if an invalid value is provided.

  • [workflow] Clone sink args at call time on Node 17+ (#1118). A subtle aspect of Workflow Sinks is that calls are actually buffered and get executed only once the current Workflow activation completes. That sometime caused unexpected behavior where an object passed as argument to a sink function is mutated after the invocation.

    On Node.js 17+, we now clone sink arguments at call time, using structuredClone. While this adds some runtime overhead, it leads to more predictable experience, as well as better exceptions when passing non-transferrable objects to a sink.

  • [core] Add the sticky_cache_total_forced_eviction metric (Core #569)

  • [client] Throw more specific errors from Client APIs (#1147)

Bug Fixes

  • [core] Metrics that should be produced by the SDK Core's internal Client would previously not get emitted. This has been fixed. (#1119)
  • [client] Fix incorrect schedule spec boundaries checks on hour and day of month (#1120)
  • [workflow] We now throw more meaningful errors when Workflow-only APIs are used from non-Workflow context, and some other situations. (#1126)
  • Removed most instanceof checks from SDK, and replaced them by XxxError.is(...) checks, based on the presence of a symbol property. We believe this should help resolve most of the problems that previously been observed when multiple copies or different versions of SDK packages are installed in a same project ((#1128)).
  • [workflow] Make Local Activity timeouts in ActivityInfo match those of non-Local Activities (#1133, Core #569).
  • [workflow] Ensure payload converters keep Uint8Array type equality (#1143)
  • Fail workflow task if local activity not registered with worker (#1152)
  • [core] Don't increment terminal command metrics when replaying (Core #572)
  • [core] Fix start-to-close local activity timeouts not being retriable like they should be (#Core 576)

Documentation

  • Improve documentation for activity heartbeat and cancellationSignal (#1151)

1.7.4

04 Aug 21:17
Compare
Choose a tag to compare

Bug Fixes

  • Publish all pre-built binaries, 1.7.3 included only arm64 darwin

1.7.3

04 Aug 21:18
Compare
Choose a tag to compare

Bug Fixes

  • [workflow] Fix internal patches NDE on replay (#1106)
  • Fix null payload data in historyFromJSON (#1109)
  • [core] Fix issues with pagination and event loss in some edge cases (#537 + #538)
  • [core] Fix child wf state machine returning fatal instead of NDE (#536)

Features

  • Make proto JSON enum conversion noop if already in right format (#1110)

Miscellaneous Tasks

1.7.2

04 Aug 21:18
Compare
Choose a tag to compare

Bug Fixes

  • [core] Fix scenario where server sends page token pointing to empty page #533
  • [core] Fix internal flags not always being written when they should be #532
  • [core] Ensure cancels get delivered after grace, even if poll stream not done #531
  • [core] Get rid of leftover warning log line #530