in common/dbinterface.cpp [158:226]
T DBInterface::blockable(FUNC f, const std::string& dbName, bool blocking)
{
int attempts = 0;
for (;;)
{
try
{
T ret_data = f();
_unsubscribe_keyspace_notification(dbName);
return ret_data;
}
catch (const UnavailableDataError& e)
{
if (blocking)
{
SWSS_LOG_WARN("%s", e.what());
auto found = keyspace_notification_channels.find(dbName);
if (found != keyspace_notification_channels.end())
{
bool result = _unavailable_data_handler(dbName, e.getData());
if (result)
{
continue; // received updates, try to read data again
}
else
{
_unsubscribe_keyspace_notification(dbName);
throw; // No updates was received. Raise exception
}
}
else
{
// Subscribe to updates and try it again (avoiding race condition)
_subscribe_keyspace_notification(dbName);
}
}
else
{
return T();
}
}
catch (const std::system_error&)
{
/*
Something is fundamentally wrong with the request itself.
Retrying the request won't pass unless the schema itself changes. In this case, the error
should be attributed to the application itself. Re-raise the error.
*/
SWSS_LOG_ERROR("Bad DB request [%s]", dbName.c_str());
throw;
}
catch (const RedisError&)
{
// Redis connection broken and we need to retry several times
attempts += 1;
_connection_error_handler(dbName);
std::string msg = "DB access failure by [" + dbName + + "]";
if (BLOCKING_ATTEMPT_ERROR_THRESHOLD < attempts && attempts < BLOCKING_ATTEMPT_SUPPRESSION)
{
// Repeated access failures implies the database itself is unhealthy.
SWSS_LOG_ERROR("%s", msg.c_str());
}
else
{
SWSS_LOG_WARN("%s", msg.c_str());
}
}
}
}