feat!: normalize timestamps from TEXT to epoch millisecond INTEGER#75
Merged
Conversation
Replace all nine timestamp columns (created_at, started_at, completed_at,
expires_at, run_after) across tasks and task_history tables from TEXT
format to INTEGER epoch milliseconds. This unifies the inconsistent
second/millisecond TEXT formats and enables direct integer arithmetic
in SQL (e.g. TTL computation via `? + (ttl_seconds * 1000)`) instead
of strftime/datetime conversions.
Breaking storage change — requires database recreation.
- Add epoch_ms/from_epoch_ms helpers, remove parse_datetime and friends
- Bind all timestamps from Rust as i64 epoch millis
- Replace all datetime('now')/strftime(...) SQL expressions with bound params
- Add explicit completed_at to insert_history (was DEFAULT-based)
- Fix idx_tasks_expires partial index to include 'blocked' status
Contributor
Benchmark ComparisonClick to expand |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
created_at,started_at,completed_at,expires_at,run_after) acrosstasksandtask_historytables fromTEXTtoINTEGERepoch millisecondsdatetime('now')/strftime(...)SQL expressions with boundi64parameters computed in Rust, and all TEXT formatting (format("%Y-%m-%d %H:%M:%S")) with.timestamp_millis()callsparse_datetime/parse_2/parse_4/parse_frac_nanosTEXT parser withepoch_ms()/from_epoch_ms()helperscompleted_atbind toinsert_history(previously relied onDEFAULT (datetime('now'))which is removed)idx_tasks_expirespartial index to include'blocked'status (pre-existing bug —expire_tasks()queriesstatus IN ('pending', 'paused', 'blocked')but the index only covered('pending', 'paused'))? + (ttl_seconds * 1000)) instead ofdatetime('now', '+' || ttl_seconds || ' seconds')Motivation
strftime('%s', col)conversions — simpler, faster, less error-pronerun_aftergating, and pruningrun_afterused second precision (%H:%M:%S) while retry backoff used millisecond precision (%H:%M:%S%.3f) — epoch millis unify bothBreaking change
Storage-level only — public Rust types remain
DateTime<Utc>. Requires database recreation (no live migration). The activetaskstable is transient (work queue drains) andtask_historyis diagnostic, so data loss on recreation is acceptable.