Use async instead of forkIO everywhere

And also make sure that all command handlers are cancelled when one of them
fails so we can cleanly restart everything again.
Restart if we caught an exception
Send periodic pings if needed and time out after some time with no activity