rework main wait loop

- accumulate rapid successive changes into one block
- but process changes as soon as there's at least 'latency' after last change
- sleep until changes are queued
- quickly and gracefully stop the loop