Split callback into poll and run to cleanly handle UDP and TCP