DEV Community

Cover image for The Mystery of a Missing Greeting
Mark Markaryan
Mark Markaryan

Posted on

The Mystery of a Missing Greeting

"Sure, I can build things quickly with durable workflows, but how do I debug them?"

I hear this question a lot, so let's solve this mystery!

Source Code and Setup

The source code for this exercise is available at https://github.com/markmark206/journey-introspect.

You can clone that repo and follow its README's setup steps to run this sequence on your machine, or you can just follow along!

Some output in fragments below is omitted for brevity.

With logistics out of the way, let's go!

Welcome, Customers!

You are a technical co-founder. You just implemented the "welcome" sequence of your onboarding application, as a durable workflow. Your co-founder is surprised at how quickly you did it and how well it works.

Honestly, you are also surprised at how little code you needed to write:

iex(1)> import Journey.Node
Journey.Node
iex(2)> graph = Journey.new_graph(
  "Customer Onboarding",
  [
    input(:name),
    input(:email_address),
    compute(
      :greeting,
      [:name, :email_address],
      fn values ->
        welcome = "Welcome, #{values.name} at #{values.email_address}"
        IO.puts(welcome)
        {:ok, welcome}
      end
    )
  ]
)
Enter fullscreen mode Exit fullscreen mode

The application spins up an execution of this workflow (Journey.start(graph)) for every customer, as they navigate your website. Customers are getting greeted. The business is booming.

The Mystery of a Missing Greeting

All of a sudden you get a call from your co-founder, Ms. Too-Ticky: "Mr. Hemulen, our newest customer, did not get his 'welcome' greeting! Why?!?"

No worries, Ms. Too-Ticky! Journey.Tools.introspect/1 to the rescue!

Mystery Solved?

Let's introspect Mr. Hemulen's onboarding execution. Did :greeting compute?

iex(5)> Journey.Tools.introspect(eid) |> IO.puts()
Values:
- Set:
  - name: '"Hemulen"' | :input
    set at 2025-12-10 09:02:16Z | rev: 1

- Not set:
  - email_address: <unk> | :input
  - greeting: <unk> | :compute

Computations:
- Outstanding:
  - greeting:  :not_set (not yet attempted) | :compute
       :and
        ├─  :name | &provided?/1 | rev 1
        └─ 🛑 :email_address | &provided?/1
Enter fullscreen mode Exit fullscreen mode

Aha! :greeting is blocked – we have Mr. Hemulen's :name, but not his :email_address.

Mystery Solved! Hello, Mr. Hemulen!

As soon as Mr. Hemulen provides his email address, he is greeted:

iex> Journey.set(eid, :email_address, "hemulen@gojourney.dev")
Welcome, Hemulen at hemulen@gojourney.dev
Enter fullscreen mode Exit fullscreen mode

All done!

:greeting should now be computed. Is it?

iex(7)> Journey.Tools.introspect(eid) |> IO.puts()
Values:
- Set:
  - greeting: '"Welcome, Hemulen at hemulen@gojourney.dev"' | :compute
    computed at 2025-12-10 09:03:06Z | rev: 4

  - email_address: '"hemulen@gojourney.dev"' | :input
    set at 2025-12-10 09:03:06Z | rev: 2

  - name: '"Hemulen"' | :input
    set at 2025-12-10 09:02:16Z | rev: 1

Computations:
- Completed:
  - :greeting (CMPR7RL0T7T2VTJAG9Z0748):  :success | :compute | rev 4
    inputs used:
       :name (rev 1)
       :email_address (rev 2)
Enter fullscreen mode Exit fullscreen mode

Yes! With Mr. Hemulen's :name and :email_address both in place, :greeting is done!

Ms. Too-Ticky is happy. Mr. Hemulen is happy.

One call to Journey.Tools.introspect/1... mystery solved!

Stay tuned for more adventures in Durable Workflows. ;)

References

Top comments (0)