May 25, 2023

Temporal for VS Code

Loren Sands-Ramshaw

Loren Sands-Ramshaw

We just published the first version of our extension for Visual Studio Code. It currently improves the debugging experience for TypeScript workflows, and in the future we'd like to add other languages, features, and editors. If you have ideas, open an issue in the GitHub repo!

Temporal for VS Code banner

When you run a workflow function, each step it takes is stored as an event in a list called the Event History. You can download a workflow's Event History from the UI or CLI in a JSON file and have an SDK replay it: the Worker calls your workflow function with the same arguments, the Worker immediately resolves activity calls with the return values recorded in Event History, and other things like timers going off and signals arriving happen in the same order they did previously. You can set breakpoints in workflow code to see what happened during the workflow's original execution. This ability to replay what happened during a function's execution, whether it's on a coworker's machine or in production, is a great help to debugging.

The Temporal VS Code extension improves the experience of replay debugging. It allows you to:

  • Load Event Histories by Workflow Id or JSON file
  • Easily start a replay
  • Set breakpoints on events, not just code

Usage

To learn how to use the extension, watch this video or follow these steps:

  • Install the extension

  • If you don’t already have a TypeScript workflow, create a project if you don't already have one:

    $ npx @temporalio/create@latest replay-demo --sample vscode-debugger
    $ code replay-demo
    
  • If you do have a TypeScript workflow, add a file at src/debug-replayer.ts (or can configure an alternate location):

    import { startDebugReplayer } from "@temporalio/worker"
    
    startDebugReplayer({
      workflowsPath: require.resolve("./workflows"),
    })
    

    And edit the './workflows' path to match the location of your workflows file. This file is run the by the extension whenever you start a debug session. startDebugReplayer creates a replay Worker (like Worker.runReplayHistory does) and communicates with the extension.

  • Run Temporal: Open Panel (use Cmd/Ctrl-Shift-P to open Command Palette)

Temporal: Open Panel

  • Enter a Workflow Id or choose a history JSON file (if you have the replay-demo project open, use this file)

MAIN tab of Temporal Panel

  • Click Start
  • The Workflow Execution will start replaying and hit a breakpoint set on the first event:

Debug session paused on the first line of the Workflow function

  • Set breakpoints in code or on history events. Here's a breakpoint on the sleep line as well as the history event when the verify Signal arrives:

Red breakpoint dots on a line of code and an event in the HISTORY tab of the Temporal Panel

  • Hit play or step forward. In this example, after you hit play, it goes until the WorkflowExecutionSignaled event, pausing on the first line of the Signal handler:

Paused on first line of the Signal handler

When you hit play again, it stops on the sleep line:

Paused on sleep('1 day')

You can see on the top left that the verified variable is now true.

  • To restart from the beginning, click the green restart icon:

Top bar of debugging icons

If instead of restarting, you step forward or hit play again, the debugging session will end (the replay Worker gets to the end of this history file and exits). Once a debug session has ended, to restart it, go back to the MAIN tab and Start again.

The humanVerificationWorkflow workflow used above is in temporalio/samples-typescript. For a more in-depth demo, see this video.

Configuration

Server

When starting a replay by Workflow Id (and optionally Run Id), the extension downloads the history from the Temporal Server. By default, it connects to a Server running on the default localhost:7233.

To connect to a different Server:

  • Open the SETTINGS tab
  • Edit the Address field
  • If you're using TLS (e.g. to connect to Temporal Cloud), check the box and select your client cert and key

SETTINGS tab of Temporal Panel

Entrypoint

By default, the extension will look for the file that calls startDebugReplayer at src/debug-replayer.ts. To use a different TypeScript or JavaScript file, set the temporal.replayerEntrypoint config:

  • Open or create .vscode/settings.json

  • Add the config field:

    {
      "temporal.replayerEntrypoint": "test/different-file.ts"
    }
    

That's the extension! If you have any problems with it, please open an issue. We also welcome contributions—please get consensus for your plan in an issue before submitting a PR ☺️. Happy debugging! 🐞💃