Skip to content

State Machine

The state machine on the paste row tracks where the async upload is in its lifecycle. It lets the read path return a meaningful response at every stage — not just success or 404.


The problem without states

Without a status column, the DB row looks the same whether: - The upload is still in progress (worker picked it up, uploading now) - The upload failed (worker gave up after retries) - The upload never started (worker crashed before picking it up)

All three cases show s3_url = NULL. The read path can't distinguish between them. It can't tell the user "try again in 30 seconds" vs "this paste is gone."

A state machine fixes this by making each stage explicit.


The states

IN_PROGRESS  — paste row created, S3 upload queued or in flight
PROCESSED    — S3 upload succeeded, s3_url populated, paste is readable
FAILED       — all retries exhausted, S3 upload never succeeded, paste is permanently broken

Transitions:

                S3 upload succeeds
IN_PROGRESS ─────────────────────→ PROCESSED

                all retries exhausted
IN_PROGRESS ─────────────────────→ FAILED

There is no transition out of PROCESSED or FAILED — both are terminal states.


The schema change

One column added to the pastes table:

status VARCHAR(20) NOT NULL DEFAULT 'IN_PROGRESS'
  CHECK (status IN ('IN_PROGRESS', 'PROCESSED', 'FAILED'))

On INSERT (paste creation):

INSERT INTO pastes (short_code, user_id, content_hash, s3_url, status, ...)
VALUES ('aB3xYz', 123, 'sha256...', NULL, 'IN_PROGRESS', ...)

On successful upload:

UPDATE pastes
SET s3_url = 'https://s3.amazonaws.com/...', status = 'PROCESSED'
WHERE short_code = 'aB3xYz'

On permanent failure:

UPDATE pastes
SET status = 'FAILED'
WHERE short_code = 'aB3xYz'

What the state machine buys you

Every read request now has a definitive answer:

status = PROCESSED   → paste is readable, serve content
status = IN_PROGRESS → paste is being created, ask client to retry
status = FAILED      → paste creation failed, treat as not found

No ambiguity. No silent broken pastes. The read path can always explain what's happening.