Lock workflows in workhorse to prevent concurrent execution

Problem

As described in #548686 it's not good that users can trigger the same workflow to be running twice concurrently. Behaviour is undefined and likely bad for users.

Solution

While #548686 proposes a slightly more robust approach to this problem which also covers faster failure transitions it will also require more elaborate coordination across several systems.

Instead we can keep implement a simple locking mechanism in workhorse based on Redis distributed locks. This is based on the assumption that soon all flows will be proxied by workhorse. Basically as soon as a flow starts in redis we acquire a lock in redis and then we give up the lock as soon as the flow finishes from workhorse's perspective. Also we fail any requests from a user that attempts to resume an already running workflow.

UX impact

This will dis-allow the concurrent execution of the same session at the same time for now. The most likely case of this is a user opening the same chat in multiple tabs. A less likely case would be opening up the same chat in an IDE and the Web at the same time.

Edited by Sebastian Rehm