This is the main new abstraction, the one that will be used by all DonationInterface and CRM code to queue and dequeue.
So far, I'm thinking something like:
The loop includes a transaction around each AtomicReadBuffer::popAtomic, and $callback takes single records as its argument.
Can we get away without single-record pop?
Must have tests.