writePending() did a synchronous ReadRow per queued node to avoid
rewriting unchanged os/arch/version. With thousands of check-ins per
cycle that's thousands of sequential round-trips every 10s, and the read
was nearly pointless since last_seen and the IP cell are written every
cycle anyway.
Replace it with an in-process cache of the last-written node_info per
row (keyed by a 64-bit hash of the row key). node_info is emitted only
when changed, new, or past its refresh window; check_in is still written
every cycle. Failed rows are dropped from the cache so they're rewritten
next cycle, and stale entries are evicted (24h TTL). Net result: one
BulkApply per cycle, no read RPCs.