Forum teuk.org

MB735 — When TinyURL Closes the Floo Network, News Still Travels 🛡️🔥

in Mediabot · started by TeuK · 4d ago

TeuK · 4d ago

TinyURL recently stopped shortening new links for our account. The API key was still present, correctly formatted and accepted, but the authenticated endpoint answered with:

HTTP 422 Unprocessable Entity
TinyURL links limit reached.

That distinction matters. This was neither a missing credential nor ordinary request throttling. The account had reached its link-creation allowance, so every article and every isolated worker would otherwise keep trying the same operation while gaining nothing from it.

MB735 gives Mediabot a shared memory for this particular bit of dark magic. When TinyURL closes the Floo Network, the news does not disappear: the bot simply delivers the exact original article URL.

What changed

The TinyURL presentation helper is now shared by all four paths that publish news links:

  • automatic RSS polling;
  • rss show;
  • rss probe;
  • interactive news / actualites searches.

Successful mappings are stored in a private persistent cache. TinyURL aliases are normally permanent, so a known article can reuse its existing alias without another API request. Cache lookup happens before circuit evaluation, which means previously shortened links remain available even while creation of new links is suspended.

Failures now open a shared circuit visible to every isolated worker:

Failure Circuit policy
HTTP 422 with TinyURL links limit reached. 24 hours
HTTP 429 Retry-After, bounded from 60 seconds to 24 hours; 15 minutes by default
HTTP 401 or 403 6 hours
TinyURL 5xx 10 minutes
Transport failure 5 minutes
Invalid response, alias or destination binding 1 hour

When a circuit expires, the next eligible article performs one probe. Success clears the circuit and records a recovery event; another failure renews the appropriate protection.

Shared state without shared secrets

The state is written beside the active instance configuration, at:

cache/tinyurl-state.json

It uses an inter-process lock and atomic replacement so concurrent RSS and command workers cannot corrupt it or launch a request storm. The state file and lock are private to the bot account, with mode 0600; the containing directory is created with mode 0750.

The cache is bounded to 5,000 mappings and the complete state to 8 MiB. It contains original-to-short-alias mappings and circuit metadata, but never the TinyURL API key, authorization header, response body or arbitrary diagnostic payload.

If shared state cannot be read safely, shortening fails closed to the original article URL instead of bypassing the circuit protection.

Diagnostics that explain the real failure

The old fallback was deliberately safe but almost silent. MB735 now records concise operator-facing events without leaking secrets or article URLs.

For the observed incident, the first worker writes:

TinyURL: HTTP 422 link creation limit reached; circuit open for 86400s

Further workers remain silent during the normal circuit interval. A bounded reminder may be emitted after six hours, and a successful post-circuit probe records recovery. This keeps the application log useful without turning one exhausted quota into hundreds of repetitive warnings.

Development validation

The change was applied first to the Mediabot 3.6 development instance and validated without touching production.

  • Perl syntax: all four modified runtime modules passed.
  • Targeted TinyURL, RSS and news contracts: 99/99.
  • Fast validation lane: 7,130/7,130.
  • Unique final full suite: 19,182/19,182 in 137 seconds.
  • Live test: the first interactive news worker received the real HTTP 422 and opened the shared 24-hour circuit.
  • Cross-worker test: a second isolated news worker published original URLs without making another TinyURL request.
  • Runtime state: version 1, mode 0600, owner mediabot, category link_limit, HTTP status 422.

The live application log contained exactly one TinyURL failure event across both workers.

Operational impact

MB735 requires no database migration and changes no RSS source, article selection or IRC formatting contract. TinyURL remains presentation-only and optional:

  • with no API key, Mediabot uses the original URL and makes no request;
  • with a working key, cached or newly created TinyURL aliases are used;
  • with an exhausted or unavailable service, the original article URL remains available;
  • after recovery, shortening resumes automatically through one controlled probe.

The owls may find the chimney blocked, but the Daily Prophet still reaches the Great Hall. 🦉📰

You must be logged in to reply.