Replaces the active database connection with a new one. Must be called from the main thread.
| 1994 | |
| 1995 | // Replaces the active database connection with a new one. Must be called from the main thread. |
| 1996 | void MultiVersionDatabase::DatabaseState::updateDatabase(Reference<IDatabase> newDb, Reference<ClientInfo> client) { |
| 1997 | if (closed) { |
| 1998 | return; |
| 1999 | } |
| 2000 | |
| 2001 | if (newDb) { |
| 2002 | optionLock.enter(); |
| 2003 | for (auto option : options) { |
| 2004 | try { |
| 2005 | // In practice, this will set a deferred error instead of throwing. If that happens, the database |
| 2006 | // will be unusable (attempts to use it will throw errors). |
| 2007 | newDb->setOption(option.first, option.second.castTo<StringRef>()); |
| 2008 | } catch (Error& e) { |
| 2009 | optionLock.leave(); |
| 2010 | |
| 2011 | // If we can't set all of the options on a cluster, we abandon the client |
| 2012 | TraceEvent(SevError, "ClusterVersionChangeOptionError") |
| 2013 | .error(e) |
| 2014 | .detail("Option", option.first) |
| 2015 | .detail("OptionValue", option.second) |
| 2016 | .detail("LibPath", client->libPath); |
| 2017 | client->failed = true; |
| 2018 | MultiVersionApi::api->updateSupportedVersions(); |
| 2019 | newDb = Reference<IDatabase>(); |
| 2020 | break; |
| 2021 | } |
| 2022 | } |
| 2023 | |
| 2024 | db = newDb; |
| 2025 | |
| 2026 | optionLock.leave(); |
| 2027 | |
| 2028 | if (dbProtocolVersion.get().hasStableInterfaces() && db) { |
| 2029 | versionMonitorDb = db; |
| 2030 | } else { |
| 2031 | // For older clients that don't have an API to get the protocol version, we have to monitor it locally |
| 2032 | try { |
| 2033 | versionMonitorDb = connectionRecord.createDatabase(MultiVersionApi::api->getLocalClient()->api); |
| 2034 | } catch (Error& e) { |
| 2035 | // We can't create a new database to monitor the cluster version. This means we will continue using the |
| 2036 | // previous one, which should hopefully continue to work. |
| 2037 | TraceEvent(SevWarnAlways, "FailedToCreateDatabaseForVersionMonitoring") |
| 2038 | .error(e) |
| 2039 | .detail("ConnectionRecord", connectionRecord); |
| 2040 | } |
| 2041 | } |
| 2042 | } else { |
| 2043 | // We don't have a database connection, so use the local client to monitor the protocol version |
| 2044 | db = Reference<IDatabase>(); |
| 2045 | try { |
| 2046 | versionMonitorDb = connectionRecord.createDatabase(MultiVersionApi::api->getLocalClient()->api); |
| 2047 | } catch (Error& e) { |
| 2048 | // We can't create a new database to monitor the cluster version. This means we will continue using the |
| 2049 | // previous one, which should hopefully continue to work. |
| 2050 | TraceEvent(SevWarnAlways, "FailedToCreateDatabaseForVersionMonitoring") |
| 2051 | .error(e) |
| 2052 | .detail("ConnectionRecord", connectionRecord); |
| 2053 | } |
no test coverage detected