An idea I just had: Director basically works by assigning the backend IP address by:
ip = vhosts[ md5(username) mod vhosts_count ].ip
The rest of director is about what happens when vhosts[] or vhosts_count changes. What about instead doing this on IP address level?
ip = ip_pool[ md5(username) mod ip_pool_size ]
When a backend dies, you'll reassign the backend's IPs to other backends. Each backend should have many IPs. The main restriction here is that the IP pool cannot change without stopping the entire Dovecot. But if you initially allocate enough IPs, that shouldn't be a problem.
And the advantage of this over the current director? To guarantee that one director can't break others, because they don't need to communicate with each others.
The disadvantage of course is that it's a little less flexible and requires more planning ahead. The IP address reassignment would also need some distro-specific scripts.
This could be implemented as an alternative director-lite or something. The doveadm director status-related commands could still work with it.