Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Activity diagram examples

Examples for systems developers. Each is a golden test, so what you see is what drumlin produces.

Build and release pipeline

Compile, tests and lint run concurrently. The note attaches to the fork. A release only happens for a tagged build, so the signing steps sit on the main axis and the empty [else] branch runs around them.

diagram activity "Build and release pipeline"
start
action "Fetch sources"
action "Resolve dependencies"
object "Lockfile"
fork {
  action "Compile"
  action "Link"
} and {
  action "Run unit tests"
} and {
  action "Lint and audit"
}
note: Compile, test and lint run concurrently.
action "Package artifacts"
if "tag build" {
  action "Sign artifacts"
  send "Publish release"
}
action "Notify the team"
stop
Build and release pipeline Fetch sources Resolve dependencies Lockfile Compile Link Run unit tests Lint and audit Package artifacts Sign artifacts Publish release Notify the team Compile, test and lint run concurrently. [tag build] [else]

Interrupt service with deferred work

The top half is the hard interrupt handler; the bottom half is the deferred work. The handler is started by an accept event rather than an initial node, and hands off with a signal.

diagram activity "Interrupt service with deferred work"
accept "IRQ line raised"
action "Acknowledge at the controller"
action "Read status register"
if "FIFO has data" {
  action "Copy bytes to the ring buffer"
  send "Wake softirq"
} else "overrun" {
  action "Count overrun"
}
action "Return from interrupt"
accept "softirq scheduled"
while "ring buffer not empty" {
  action "Pop one packet"
  if "checksum valid" {
    action "Deliver to the stack"
  } else {
    action "Drop and count"
  }
}
end
Interrupt service with deferred work IRQ line raised Acknowledge at the controller Read status register Copy bytes to the ring buffer Wake softirq Count overrun Return from interrupt softirq scheduled Pop one packet Deliver to the stack Drop and count [FIFO has data] [overrun] [ring buffer not empty] [else] [checksum valid] [else]

Connection retry

A repeat wraps the handshake with backoff, and early failures step aside so that the successful path stays straight.

diagram activity "Connection retry with backoff"
start
action "Resolve host"
if "resolved" {
  repeat {
    action "Open socket"
    action "TLS handshake"
    if "failed" {
      action "Wait for backoff"
    }
  } until "connected or attempts exhausted"
  if "connected" {
    action "Send greeting"
  } else {
    action "Report unreachable"
    stop
  }
} else {
  action "Report DNS failure"
  stop
}
action "Mark session ready"
stop
Connection retry with backoff Resolve host Open socket TLS handshake Wait for backoff Send greeting Report unreachable Report DNS failure Mark session ready [connected or attempts exhausted] [else] [failed] [else] [connected] [else] [resolved] [else]

Deployment with parallel checks across lanes

The fork spans the lanes running the checks, and the release decision returns to the developer’s lane.

diagram activity "Deployment with parallel checks"
start
lane "Developer" {
  action "Merge to main"
}
lane "CI" {
  action "Build image"
  send "Image ready"
}
lane "Staging" {
  accept "Image ready"
  action "Deploy to staging"
}
fork {
  lane "Staging" {
    action "Smoke tests"
  }
} and {
  lane "Security" {
    action "Scan image"
  }
} and {
  lane "CI" {
    action "Contract tests"
  }
}
lane "Developer" {
  if "all green" {
    lane "Production" {
      action "Roll out canary"
    }
  } else {
    action "Roll back and file issue"
  }
}
stop
Deployment with parallel checks Developer CI Staging Security Production Merge to main Build image Image ready Image ready Deploy to staging Smoke tests Scan image Contract tests Roll out canary Roll back and file issue [all green] [else]

Firmware boot

A switch on the boot slot, with «decisionInput» naming what the guards test.

diagram activity "Firmware boot"
start
action "Clock and RAM init"
if "reset cause is brown-out" {
  action "Record fault"
}
switch "boot slot" {
  case "A" {
    action "Verify slot A"
  }
  case "B" {
    action "Verify slot B"
  }
  case "else" {
    action "Enter recovery"
    end
  }
}
if "signature valid" {
  action "Jump to application"
  note: The vector table is relocated first.
} else {
  action "Enter recovery"
}
stop
Firmware boot Clock and RAM init Record fault Verify slot A Verify slot B Enter recovery Jump to application Enter recovery «decisionInput» boot slot The vector table is relocated first. [reset cause is brown-out] [else] [A] [B] [else] [signature valid] [else]