Skip to content

Refactor: Extract transcoding job state machine into explicit code (#438)#499

Merged
filthyrake merged 2 commits intodevfrom
feature/438-transcoding-state-machine
Jan 4, 2026
Merged

Refactor: Extract transcoding job state machine into explicit code (#438)#499
filthyrake merged 2 commits intodevfrom
feature/438-transcoding-state-machine

Conversation

@filthyrake
Copy link
Copy Markdown
Owner

Summary

  • Adds api/job_state.py with TranscodingJobStateMachine class that makes the implicit state machine explicit and self-documenting
  • Provides JobState enum with 6 states: unclaimed, claimed, expired, completed, failed, retrying
  • Includes state predicates (is_unclaimed(), is_claimed(), etc.), SQL condition generators, and transition validation methods
  • Reduces the 109-line comment block in database.py to 6 lines that reference the new module

Changes

  • New file: api/job_state.py - Contains TranscodingJobStateMachine class with:

    • JobState enum for explicit state representation
    • JobRow dataclass for type-safe state determination
    • State predicates: is_unclaimed(), is_claimed(), is_expired(), is_completed(), is_failed(), is_retrying()
    • SQL condition generators: sql_unclaimed(), sql_claimed(), sql_expired(), etc. for query composition
    • Transition validation: can_claim(), can_reclaim(), can_complete(), can_fail()
    • Module-level singleton job_state_machine for convenience
  • New file: tests/test_job_state.py - 49 comprehensive tests covering:

    • State predicates with various field combinations
    • Time-based state transitions (claimed vs expired)
    • SQL condition generation
    • Transition validation
    • Edge cases
  • Updated: api/database.py - Simplified comments to reference new module

  • Updated: api/worker_api.py - Updated docstring to reference new module

Benefits

  • States are self-documenting through method names
  • Code reads like requirements documentation
  • Easy to test state transitions in isolation
  • SQL conditions are centralized and consistent

Closes #438

Test plan

  • All 49 new state machine tests pass
  • Existing worker API tests pass (82 passed)
  • Lint checks pass

🤖 Generated with Claude Code

filthyrake and others added 2 commits January 4, 2026 05:48
)

- Add api/job_state.py with TranscodingJobStateMachine class
  - JobState enum: unclaimed, claimed, expired, completed, failed, retrying
  - State predicates: is_unclaimed(), is_claimed(), is_expired(), etc.
  - SQL condition generators: sql_unclaimed(), sql_claimed(), etc.
  - Transition validation: can_claim(), can_complete(), can_fail()
  - JobRow dataclass for type-safe state determination
- Add comprehensive tests (49 test cases) for state machine
- Simplify 109-line comment block in database.py to 6 lines
- Update worker_api.py to reference new state machine module

The implicit state machine derived from nullable field combinations is now
explicit, self-documenting code that reads like requirements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security fixes:
- Add SQL identifier validation to prevent injection in table_alias
- Add SQL parameter validation to prevent injection in now_param
- Sanitize error messages to avoid leaking internal state details

Reliability fixes:
- Add timezone normalization in JobRow.from_mapping() for naive datetimes
- Add defensive completed_at checks in is_failed() and is_retrying()
- Validate numeric fields (attempt_number, max_attempts >= 1)
- Improve indeterminate state error logging

Consistency fixes:
- Fix sql_claimable() to include both unclaimed AND retrying jobs
- Update is_unclaimed() to check last_error is None (distinguishes from retrying)
- Rename 'now' parameter to 'current_time' for clarity

Performance:
- Remove unused jobs_table constructor parameter
- Add _normalize_job() helper to reduce code duplication

Documentation:
- Add state transition diagram to module and class docstrings
- Add thread safety and distributed safety notes
- Improve docstrings with worker identity verification notes

Tests (71 total):
- Add SQL injection prevention tests
- Add timezone normalization tests
- Add boundary condition tests (exact expiration time)
- Add indeterminate state test
- Add numeric validation tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@filthyrake filthyrake merged commit d878ee5 into dev Jan 4, 2026
3 checks passed
@filthyrake filthyrake deleted the feature/438-transcoding-state-machine branch January 4, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor: Extract transcoding job state machine into explicit code

1 participant