I have a process that has two independent modules that can connect to either the same fdb cluster, or two different clusters depending on configuration (one would be for general purpose data, and the other for centralized logging).
The implementation of each module is completely separate and they don’t share any code (apart from the fdb binding), so they currently create their own Cluster and Database handle, and read the cluster file path from two different configuration sections.
In the case where both target the same fdb cluster, they will both have the same cluster file path. So if the list of coordinators change on that cluster, both FDBCluster
instances may want to update the cluster file “at the same time”.
Looking at the client code, it seems that monitorLeaderOneGeneration(..)
in MonitorLeader.actor.cpp
is listening for leader change notifications, and will call ClusterConnectionFile::setConnectionString(..)
with the new string. This will create a tmp file with the new cnx string, and swap it with the old .cluster file “atomically”. It then does check the content of the file to see if it matches what was written previously.
I was not able to confirm this or not, but if I create two cluster handles, they will both call monitorLeader(...)
so both may respond to the same event and independently try to update the same cluster file.
Since both cluster handles will share the same network thread, can I safely assume that since the fdb client is single threaded, then both actors won’t try to update the same file at the same time (concurrently) ? At worst, the same file will be overwritten twice with the same content.
What would happen if the cluster file changes twice in very rapid succession, both the leader monitor actors fire but in some weird order that would end up with the intermediate version of the cluster file on disk?
Is this a scenario were having multiple of a Cluster handle per process with the same cluster file is a bad thing? Should I try to dedup this at the application level? or maybe even at the binding level? (ie: if second cluster use same path as first one, reuse this handle but create a second database handle, to at least have some isolation between both modules)