Fix the meter for remote calls inside a transaction

Review the AI's codeEasy10 min

Your task

An order service holds one database transaction open while it charges the card and sends the email, and under load the connection pool runs dry. The team wants a meter that replays a request's steps and adds up the time spent on remote calls while a transaction is open.

An assistant wrote external_ms_in_transaction(steps). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • steps: the request's steps, in order. Each one is "begin", "commit", "rollback", or "kind|name|duration_ms", such as "http|charge|800".
  • Return the total milliseconds, as an integer.

Rules the tests check:

  • Keep a depth that starts at 0. "begin" adds 1. "commit" and "rollback" each take 1 away, but never below 0. A nested "begin" joins the outer transaction, so the connection stays held until the depth is back to 0.
  • A transaction is open while the depth is above 0. A transaction still open at the end of the list counts the same.
  • Any other step must split on | into exactly 3 parts: kind, name and duration. Skip it otherwise.
  • The duration must be 1 to 15 digits (0 to 9) and nothing else. Leading zeros are fine. Skip the step otherwise.
  • The kind "db" is local database work and never counts. Every other kind is a remote call: "http", "queue", "grpc", an empty kind, anything.
  • Add a remote call's duration when a transaction is open. The name part does not matter and can be empty.
  • Matching is case sensitive. "DB" is a remote kind, and "Begin" is not "begin", so it is skipped like any step without 3 parts.
  • No steps returns 0.

Examples

external_ms_in_transaction(steps: list[str]) -> int
Example 1
Inputexternal_ms_in_transaction(["begin", "db|save_order|5", "http|charge|800", "http|email|400", "db|save_order|5", "commit"])
Output1200
Example 2
Inputexternal_ms_in_transaction(["begin", "db|save_order|5", "commit", "http|charge|800", "begin", "db|record_payment|4", "commit", "queue|enqueue_email|2"])
Output0
Example 3
Inputexternal_ms_in_transaction(["begin", "begin", "http|charge|800", "commit", "http|email|400", "commit"])
Output1200