One thread sends the heartbeats, the other processes the current whisper job. If the former crashes, then the runner will stay up and running as long as the job takes to complete, however since it will not send any heartbeats it will be offline to the backend and cannot submit its job when its finally done.
If the latter crashes, then it might happen that the runner is in a state where it still sends heartbeats and thus is online to the backend, but cannot process jobs because the variable that tells it if it currently is already processing one is still set.
Both occurrences are not theoretical but have been observed in the wild.
One thread sends the heartbeats, the other processes the current whisper job. If the former crashes, then the runner will stay up and running as long as the job takes to complete, however since it will not send any heartbeats it will be offline to the backend and cannot submit its job when its finally done. If the latter crashes, then it might happen that the runner is in a state where it still sends heartbeats and thus is online to the backend, but cannot process jobs because the variable that tells it if it currently is already processing one is still set. Both occurrences are not theoretical but have been observed in the wild.