Repository navigation
Routing rules can match the local time of day - #314
Merged
Merged
Conversation
A rule condition `time` matches when the wall-clock time of the machine core runs on falls inside any of its windows, written as `[days ]HH:MM-HH:MM` (`mon-fri 09:00-18:00`, `sat,sun 00:00-24:00`, `22:00-06:00`). The start is inclusive and the end exclusive, `24:00` is allowed as the end, and an end earlier than the start is an overnight window belonging to the day it starts on. Several windows are OR. The parser is a pure function in tw-engine with its own tests. A malformed value is refused when the configuration is read and when a rule is saved, with a message that names the rule and the value (`engine.rule_time_syntax`): a rule that silently never matches is the kind of problem users spend an afternoon on. The time itself is a routing fact (`RequestFacts::time`) the gateway fills at routing time from a clock on `AppState`, so tests can pin it and the HTTP pipeline, the WebSocket upgrade and every WebSocket frame see the same source. Dry-run uses the current time and reports a miss as `fri 17:30`. Protocol version 45. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
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.
What
Routing rules gain a
timecondition: the request matches when the local wall-clock time of the machine core runs on falls inside any of the listed windows. Protocol version 45.Value grammar (one string per window):
[<days> ]<HH:MM>-<HH:MM><days>: comma-separatedmon,tue,wed,thu,fri,sat,sunand/or rangesmon-fri,sat-sun,fri-mon(wraps past Sunday). Omitted = every day. Case-insensitive on input; the control plane stores values lower-case.<HH:MM>-<HH:MM>: 24-hour, two digits each; start inclusive, end exclusive; the end may be24:00. An end earlier than the start is an overnight window (22:00-06:00= 22:00 through 05:59 the next day); the day part names the day the window starts on. A window whose start equals its end is refused.intent.Where
tw-engine: newtimemodule (Window,LocalTime,parse; pure, unit-tested: day lists, ranges incl. wrapping, omitted days, overnight windows,24:00, malformed input).Whengainstime: Option<OneOrMany>(counts as a condition, validated at load, matched inWhen::matches).RequestFactsgainstime: Option<LocalTime>: filled by the gateway at routing time,Nonenever matches a time rule.RouteError::TimeSyntax { rule, value }carries the rule name;Engine::check_rulesmaps the engine-levelMatchError::BadTimeonto it.tw-gateway:AppStateholds aLocalClock(default: system clock, local zone;set_local_timefor tests). The fact is filled in the HTTP pipeline, on WebSocket upgrade and per WebSocket frame.tw-control:ConditionField::Timeround-trips throughdescribe_when/when_from(values validated and lower-cased on save); dry-run evaluates against the current time and reports the mismatch asfri 17:30.tw-api:ConditionFieldgainstime;CONTROL_API_VERSION44 → 45 with notes.docs/config.md/docs/config.zh-CN.mdtable row and grammar paragraph (regenerated by the manual test).New messages
engine.rule_time_syntax(argsrule,value): rule{rule}: time condition{value}is not written as[days ]HH:MM-HH:MM: days are mon, tue, wed, thu, fri, sat, sun or a range like mon-fri, the hours run from 00:00 to 24:00, as in "mon-fri 09:00-18:00"engine.time_syntax(argvalue): time condition{value}is not written as[days ]HH:MM-HH:MM: days are mon, tue, wed, thu, fri, sat, sun or a range like mon-fri, the hours run from 00:00 to 24:00, as in "mon-fri 09:00-18:00" (the engine-level sentence without a rule name; config load and the control plane always surface the rule-named one)Verified
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warnings,cargo clippy -p tw-api --all-targets --features ts -- -D warningsenv -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy cargo test -p tw-engine -p tw-config -p tw-api -p tw-control,cargo test -p tw-api --features tscargo test -p tw-gateway --test time_window(the same request routes to a different upstream at Wed 10:00, Sat 10:00 and Wed 18:00 with a fixed clock)🤖 Generated with Claude Code