code wiki / _hdl_build / nx_crawl_pace.nx

nx_crawl_pace.nx

buildroot/runtime/_hdl_build/nx_crawl_pace.nx

27045 B440 linesdepth 2pulls 2 transitivereach 22 importersview sourcekind tooltopic crawl
docsdependenciesstructsconstsfunctions

about

nx_crawl_pace.nx -- SOTA polite crawler pacing (operator 2026-07-05: "pacing is a great callout on all the systems... get to state of the art"). Per-host adaptive rate limiting: a min interval between hits to the same host, HONOR Retry-After on 429/503, EXPONENTIAL backoff on repeated throttles (R9 2026-08-24: a success HALVES the backoff instead of erasing it -- pace_decay -- so one lucky 200 cannot re-trip a host's limit), and robots crawl-delay override. State persists across invocations (each nx_url_index run is a fresh process) in a fixed hash-table file, so serial crawls stay polite and don't get IP-banned (a ban = LOST reach, not just rudeness -- reddit 429'd us on rapid feed hits). A shared organ any fetcher can call: pace_before(host) before a request, pace_after(host,status,retry_after) after. license_tier: ORIGINAL

dependencies 1 imports · 9 importers

nx_syscalls.nx nx_crawl_pace.nx nx_4chan.nx nx_bulk_index.nx nx_crawl_pace_gate.nx nx_domain_map.nx nx_paced_fetch.nx nx_paced_fetch_gate.nx nx_pacetbl_probe.nx nx_url_index.nx nx_web_crawl_step.nx

imports: nx_syscalls.nx

imported by: nx_4chan.nxnx_bulk_index.nxnx_crawl_pace_gate.nxnx_domain_map.nxnx_paced_fetch.nxnx_paced_fetch_gate.nxnx_pacetbl_probe.nxnx_url_index.nxnx_web_crawl_step.nx

structs

none

consts

10const PACE_MAGIC_5381: i64 = 5381
11const PACE_MAGIC_1024: i64 = 1024
12const PACE_MAGIC_1000000: i64 = 1000000
15const PACE_BASE_MS: i64 = 1000 // polite default: >= 1s between requests to the same host
16const PACE_MAX_BACKOFF_MS: i64 = 300000 // cap any single backoff at 5 min
17const PACE_WAIT_CAP_MS: i64 = 60000 // never block ONE fetch > 60s (caller may defer beyond)
18const PACE_SLOTS: i64 = 4096
19const PACE_REC: i64 = 40 // host_hash(8) | next_allowed_ms(8) | consec_throttle(8) | crawl_delay_ms(8) | flags(8)
20const PACE_TBL_BYTES: i64 = 163840 // PACE_SLOTS * PACE_REC
21const PACE_REC_V1: i64 = 32 // the pre-R12 record; on-disk tables in that layout are MIGRATED, never discarded
22const PACE_TBL_BYTES_V1: i64 = 131072
23const PACE_F_OKSEEN: i64 = 1 // flags bit 0: this host has returned a 2xx at least once
28const PACE_OFF_HASH: i64 = 0
29const PACE_OFF_NEXT_ALLOWED: i64 = 8
30const PACE_OFF_CONSEC: i64 = 16
31const PACE_OFF_CRAWL_DELAY: i64 = 24
32const PACE_OFF_FLAGS: i64 = 32
33const PACE_TBL_MODE: i64 = 0x1A4 // 0o644 file MODE for sys_openat_wr (flags O_CREAT|O_WRONLY|O_TRUNC

functions

38func pace_ld(tbl: *u8, off: i64) -> i64 { var v: i64=0; var i: i64=0; while i<8 { v = v | ((tbl[off+i] as i64) << (i*8)); i=i+1 } return v }
39func pace_st(tbl: *u8, off: i64, val: i64) -> i64 { var i: i64=0; while i<8 { tbl[off+i] = ((val >> (i*8)) & 0xff) as u8; i=i+1 } return 0 }
42func pace_hash(h: *u8, n: i64) -> i64
62func pace_load_tbl_into(dst: *u8) -> i64
99func pace_load_tbl() -> *u8
109func pace_ew(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 }
called by 2: pace_enpace_save_tbl calls 1: sys_write
110func pace_en(v: i64) -> i64
144func pace_save_tbl(tbl: *u8) -> i64
172func pace_slot(tbl: *u8, hh: i64) -> i64
194func pace_slot_or_evict(tbl: *u8, hh: i64) -> i64
213func pace_delay_after(base_ms: i64, crawl_delay_ms: i64, consec_in: i64,
called by 1: main calls 1: pace_delay_after2
219func pace_delay_after2(base_ms: i64, crawl_delay_ms: i64, consec_in: i64,
258func pace_decay(consec_in: i64) -> i64 { if consec_in <= 0 { return 0 } return consec_in - 1 }
261func pace_reset_host(host: *u8, host_len: i64) -> i64
275func pace_wait_ms(now_ms: i64, next_allowed_ms: i64) -> i64
283func pace_before(host: *u8, host_len: i64) -> i64
291func pace_before_tbl(tbl: *u8, host: *u8, host_len: i64) -> i64
330func pace_should_defer_tbl(tbl: *u8, host: *u8, host_len: i64) -> i64
364func pace_should_defer(host: *u8, host_len: i64) -> i64
369func pace_after(host: *u8, host_len: i64, status: i64, retry_after_s: i64) -> i64
374func pace_after_tbl(tbl: *u8, host: *u8, host_len: i64, status: i64, retry_after_s: i64) -> i64
405func pace_set_crawl_delay(host: *u8, host_len: i64, cd_ms: i64) -> i64
418func pace_retry_after(resp: *u8, n: i64) -> i64
called by 1: main
440func main() -> i64 { return 0 }