-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement general redis table waiter
- Loading branch information
1 parent
0f69104
commit 007798d
Showing
9 changed files
with
353 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#include "redis_table_waiter.h" | ||
#include "select.h" | ||
#include "subscriberstatetable.h" | ||
|
||
using namespace swss; | ||
|
||
bool RedisTableWaiter::waitUntil( | ||
DBConnector &db, | ||
const std::string &tableName, | ||
unsigned int maxWaitSec, | ||
CheckFunc checkFunc) | ||
{ | ||
if (maxWaitSec == 0) | ||
{ | ||
SWSS_LOG_ERROR("Error: invalid maxWaitSec value 0, must be larger than 0"); | ||
return false; | ||
} | ||
|
||
SubscriberStateTable table(&db, tableName); | ||
Select s; | ||
s.addSelectable(&table); | ||
|
||
int maxWaitMs = static_cast<int>(maxWaitSec) * 1000; | ||
int selectTimeout = maxWaitMs; | ||
auto start = std::chrono::steady_clock::now(); | ||
while(1) | ||
{ | ||
Selectable *sel = NULL; | ||
int ret = s.select(&sel, selectTimeout, true); | ||
if (ret == Select::OBJECT) | ||
{ | ||
KeyOpFieldsValuesTuple kco; | ||
table.pop(kco); | ||
if (checkFunc(kco)) | ||
{ | ||
return true; | ||
} | ||
} | ||
else if (ret == Select::ERROR) | ||
{ | ||
SWSS_LOG_NOTICE("Error: wait redis table got error - %s!", strerror(errno)); | ||
} | ||
else if (ret == Select::TIMEOUT) | ||
{ | ||
SWSS_LOG_INFO("Timeout: wait redis table got select timeout"); | ||
} | ||
else if (ret == Select::SIGNALINT) | ||
{ | ||
return false; | ||
} | ||
|
||
auto end = std::chrono::steady_clock::now(); | ||
int delay = static_cast<int>( | ||
std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()); | ||
|
||
if (delay >= maxWaitMs) | ||
{ | ||
return false; | ||
} | ||
|
||
selectTimeout = maxWaitMs - delay; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool RedisTableWaiter::waitUntilFieldSet( | ||
DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
const std::string &fieldName, | ||
unsigned int maxWaitSec, | ||
ConditionFunc cond) | ||
{ | ||
auto sep = SonicDBConfig::getSeparator(&db); | ||
auto value = db.hget(tableName + sep + key, fieldName); | ||
if (value && cond(*value.get())) | ||
{ | ||
return true; | ||
} | ||
|
||
auto checkFunc = [&](const KeyOpFieldsValuesTuple &kco) -> bool { | ||
if (SET_COMMAND == kfvOp(kco)) | ||
{ | ||
if (key == kfvKey(kco)) | ||
{ | ||
auto& values = kfvFieldsValues(kco); | ||
for (auto& fvt: values) | ||
{ | ||
if (fieldName == fvField(fvt)) | ||
{ | ||
return cond(fvValue(fvt)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
}; | ||
return waitUntil(db, tableName, maxWaitSec, checkFunc); | ||
} | ||
|
||
bool RedisTableWaiter::waitUntilKeySet( | ||
DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
unsigned int maxWaitSec) | ||
{ | ||
auto sep = SonicDBConfig::getSeparator(&db); | ||
if (db.exists(tableName + sep + key)) | ||
{ | ||
return true; | ||
} | ||
|
||
auto checkFunc = [&](const KeyOpFieldsValuesTuple &kco) -> bool { | ||
if (SET_COMMAND == kfvOp(kco)) | ||
{ | ||
return key == kfvKey(kco); | ||
} | ||
return false; | ||
}; | ||
return waitUntil(db, tableName, maxWaitSec, checkFunc); | ||
} | ||
|
||
bool RedisTableWaiter::waitUntilKeyDel( | ||
DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
unsigned int maxWaitSec) | ||
{ | ||
auto sep = SonicDBConfig::getSeparator(&db); | ||
if (!db.exists(tableName + sep + key)) | ||
{ | ||
return true; | ||
} | ||
|
||
auto checkFunc = [&](const KeyOpFieldsValuesTuple &kco) -> bool { | ||
if (DEL_COMMAND == kfvOp(kco)) | ||
{ | ||
return key == kfvKey(kco); | ||
} | ||
return false; | ||
}; | ||
return waitUntil(db, tableName, maxWaitSec, checkFunc); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#pragma once | ||
|
||
#include <functional> | ||
#include <string> | ||
|
||
#include "dbconnector.h" | ||
|
||
namespace swss | ||
{ | ||
|
||
class RedisTableWaiter | ||
{ | ||
public: | ||
typedef std::function<bool(const std::string &)> ConditionFunc; | ||
typedef std::function<bool(const KeyOpFieldsValuesTuple &)> CheckFunc; | ||
|
||
static bool waitUntilFieldSet(DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
const std::string &fieldName, | ||
unsigned int maxWaitSec, | ||
ConditionFunc cond); | ||
|
||
|
||
static bool waitUntilKeySet(DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
unsigned int maxWaitSec); | ||
|
||
static bool waitUntilKeyDel(DBConnector &db, | ||
const std::string &tableName, | ||
const std::string &key, | ||
unsigned int maxWaitSec); | ||
|
||
static bool waitUntil( | ||
DBConnector &db, | ||
const std::string &tableName, | ||
unsigned int maxWaitSec, | ||
CheckFunc checkFunc); | ||
|
||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.