-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[sairedis/syncd] Implement bulk get support #1509
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Stepan Blyschak <[email protected]>
Signed-off-by: Stepan Blyschak <[email protected]>
Signed-off-by: Stepan Blyschak <[email protected]>
Signed-off-by: Stepan Blyschak <[email protected]>
Signed-off-by: Stepan Blyschak <[email protected]>
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
|
||
status = meta_generic_validation_get(meta_key, attr_count[idx], attr_list[idx]); | ||
|
||
// FIXME: This macro returns on failure. |
Check notice
Code scanning / CodeQL
FIXME comment Note
saiplayer/SaiPlayer.cpp
Outdated
switch (api) | ||
{ | ||
case SAI_COMMON_API_BULK_CREATE: | ||
|
||
{ | ||
sai_object_id_t switch_id = m_sai->switchIdQuery(local_ids[0]); | ||
std::vector<sai_object_id_t> ids(object_count); | ||
|
||
for (uint32_t it = 0; it < object_count; it++) | ||
{ | ||
if (m_sai->switchIdQuery(local_ids[it]) != switch_id || | ||
switch_id == SAI_NULL_OBJECT_ID) | ||
{ | ||
SWSS_LOG_THROW("invalid switch_id translated from VID %s", | ||
sai_serialize_object_id(local_ids[it]).c_str()); | ||
} | ||
} | ||
|
||
std::vector<uint32_t> attr_counts(object_count); | ||
|
||
std::vector<const sai_attribute_t*> attr_lists(object_count); | ||
|
||
for (uint32_t idx = 0; idx < object_count; idx++) | ||
{ | ||
attr_counts[idx] = attributes[idx]->get_attr_count(); | ||
attr_lists[idx] = attributes[idx]->get_attr_list(); | ||
} | ||
|
||
switch_id = translate_local_to_redis(switch_id); | ||
|
||
status = m_sai->bulkCreate(object_type, | ||
switch_id, | ||
object_count, | ||
attr_counts.data(), | ||
attr_lists.data(), | ||
mode, | ||
ids.data(), | ||
statuses.data()); | ||
|
||
if (status == SAI_STATUS_SUCCESS) | ||
{ | ||
for (uint32_t it = 0; it < object_count; it++) | ||
{ | ||
match_redis_with_rec(ids[it], local_ids[it]); | ||
|
||
SWSS_LOG_INFO("saved VID %s to RID %s", | ||
sai_serialize_object_id(local_ids[it]).c_str(), | ||
sai_serialize_object_id(ids[it]).c_str()); | ||
} | ||
} | ||
|
||
return status; | ||
} | ||
break; | ||
|
||
case SAI_COMMON_API_BULK_REMOVE: | ||
|
||
{ | ||
std::vector<sai_object_id_t> ids(object_count); | ||
|
||
for (uint32_t it = 0; it < object_count; it++) | ||
{ | ||
ids[it] = translate_local_to_redis(local_ids[it]); | ||
} | ||
|
||
status = m_sai->bulkRemove(object_type, object_count, ids.data(), mode, statuses.data()); | ||
} | ||
break; | ||
|
||
case SAI_COMMON_API_BULK_SET: | ||
|
||
{ | ||
std::vector<sai_object_id_t> ids(object_count); | ||
|
||
for (uint32_t it = 0; it < object_count; it++) | ||
{ | ||
ids[it] = translate_local_to_redis(local_ids[it]); | ||
} | ||
|
||
std::vector<sai_attribute_t> attr_list; | ||
|
||
// route can have multiple attributes, so we need to handle them all | ||
for (const auto &alist: attributes) | ||
{ | ||
attr_list.push_back(alist->get_attr_list()[0]); | ||
} | ||
|
||
status = m_sai->bulkSet(object_type, object_count, ids.data(), attr_list.data(), mode, statuses.data()); | ||
} | ||
break; | ||
|
||
case SAI_COMMON_API_BULK_GET: | ||
|
||
{ |
Check notice
Code scanning / CodeQL
Long switch case Note
SAI_COMMON_API_BULK_CREATE (52 lines)
switch (api) | ||
{ | ||
case SAI_COMMON_API_BULK_GET: | ||
sendBulkGetResponse(objectType, objectIds, all, attributes, statuses); | ||
break; | ||
default: | ||
sendApiResponse(api, all, (uint32_t)objectIds.size(), statuses.data()); | ||
break; | ||
} |
Check notice
Code scanning / CodeQL
No trivial switch statements Note
switch (object_type) | ||
{ | ||
case SAI_OBJECT_TYPE_PORT: | ||
ptr = m_apis.port_api->get_ports_attribute; | ||
break; | ||
|
||
SWSS_LOG_ERROR("not implemented, FIXME"); | ||
default: | ||
SWSS_LOG_ERROR("not implemented %s, FIXME", sai_serialize_object_type(object_type).c_str()); | ||
return SAI_STATUS_NOT_IMPLEMENTED; | ||
} |
Check notice
Code scanning / CodeQL
No trivial switch statements Note
|
||
// FIXME: This macro returns on failure. | ||
// When mode is SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR we should continue instead of return. | ||
// This issue exists for all bulk operations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we fix it here for this api ? since GET operation is specific, so maybe some attributes maybe not implemented and they will definitely return failure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please clarify? Attribute may be not implemented with SET as well.
@@ -2522,17 +2629,17 @@ int SaiPlayer::replay() | |||
|
|||
SWSS_LOG_NOTICE("using file: %s", filename.c_str()); | |||
|
|||
std::ifstream infile(filename); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this logic is changed ? not need for this variable to be member of class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to use m_infile in processBulk method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see that, but why the reason ? since this is local variable no need to upgrade it to member
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SaiPlayer operates on input stream, the input stream is feeding multiple functions with data throuhgout this operation. From that point of view the lifetime of the input stream needs to match the lifetime of SaiPlayer, thus fits to be a member variable. I did this change for ergonomics primaraly - not having to pass the input stream explicitelly everywhere it is needed in downstream code. Besides, passing an input stream explicitelly implies a member function may operate on different input streams throughout SaiPlayer's lifetime which is not the case.
I can make a function parameter though if you prefer so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kcudnik can be resolved?
@@ -259,6 +260,8 @@ namespace saiplayer | |||
|
|||
std::shared_ptr<CommandLineOptions> m_commandLineOptions; | |||
|
|||
std::ifstream m_infile; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this is moved to member ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to use m_infile in processBulk method
@@ -4,27 +4,3 @@ | |||
#include <gtest/gtest.h> | |||
|
|||
using namespace sairedis; | |||
|
|||
TEST(RedisRemoteSaiInterface, bulkGet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't remove tests, implement correct TEST to validate your code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not sure what this test actually checks. It seems the test was added to satisfy code coverage rather then check functionality. As for functioanlity check and code coverage I added tests to TestSyncdBrcm and added player tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kcudnik Please share your thoughts on what should be in this test case instead and if needed at all since the code is covered by a set of other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
address comments
… count is 0" This reverts commit e4b0f58.
Signed-off-by: Stepan Blyschak <[email protected]>
Signed-off-by: Stepan Blyschak <[email protected]>
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/* | ||
* Those objects are user created, so if user created ROUTE he | ||
* passed some attributes, there is no sense to support GET | ||
* since user explicitly know what attributes were set, similar | ||
* for other non object id types. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but thoe objects may have readonly attributes that can dynamically change and user may want to query those, for example SAI_ROUTE_ENTRY_ATTR_IP_ADDR_FAMILY
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is inherited from processQuadInInitViewModeGet(). I do not want to make the behaviour incosistent between get vs. get bulk thus I support only objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kcudnik can be resolved?
…into bulk-get Signed-off-by: Stepan Blyschak <[email protected]>
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Stepan Blyschak <[email protected]>
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
syncd/Syncd.cpp
Outdated
case SAI_COMMON_API_BULK_REMOVE: | ||
|
||
if (info->isnonobjectid) | ||
{ | ||
sendApiResponse(api, SAI_STATUS_SUCCESS, (uint32_t)statuses.size(), statuses.data()); | ||
|
||
syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); | ||
|
||
return SAI_STATUS_SUCCESS; | ||
} | ||
|
||
switch (objectType) | ||
{ | ||
case SAI_OBJECT_TYPE_SWITCH: | ||
case SAI_OBJECT_TYPE_PORT: | ||
case SAI_OBJECT_TYPE_SCHEDULER_GROUP: | ||
case SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP: | ||
|
||
SWSS_LOG_THROW("%s is not supported in init view mode", | ||
sai_serialize_object_type(objectType).c_str()); | ||
|
||
default: | ||
|
||
sendApiResponse(api, SAI_STATUS_SUCCESS, (uint32_t)statuses.size(), statuses.data()); | ||
|
||
syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); | ||
|
||
for (auto& str: objectIds) | ||
{ | ||
sai_object_id_t objectVid; | ||
sai_deserialize_object_id(str, objectVid); | ||
|
||
// in init view mode insert every created object except switch | ||
|
||
m_createdInInitView.insert(objectVid); | ||
} | ||
|
||
return SAI_STATUS_SUCCESS; | ||
} | ||
|
||
case SAI_COMMON_API_BULK_SET: | ||
|
||
switch (objectType) | ||
{ | ||
case SAI_OBJECT_TYPE_SWITCH: | ||
case SAI_OBJECT_TYPE_SCHEDULER_GROUP: | ||
|
||
SWSS_LOG_THROW("%s is not supported in init view mode", | ||
sai_serialize_object_type(objectType).c_str()); | ||
|
||
default: | ||
|
||
break; | ||
} | ||
|
||
sendApiResponse(api, SAI_STATUS_SUCCESS, (uint32_t)statuses.size(), statuses.data()); | ||
|
||
syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); | ||
|
||
return SAI_STATUS_SUCCESS; | ||
|
||
case SAI_COMMON_API_BULK_GET: | ||
SWSS_LOG_THROW("GET bulk api is not implemented in init view mode, FIXME"); | ||
if (info->isnonobjectid) | ||
{ | ||
/* | ||
* Those objects are user created, so if user created ROUTE he | ||
* passed some attributes, there is no sense to support GET | ||
* since user explicitly know what attributes were set, similar | ||
* for other non object id types. | ||
*/ | ||
|
||
SWSS_LOG_ERROR("get is not supported on %s in init view mode", sai_serialize_object_type(objectType).c_str()); |
Check notice
Code scanning / CodeQL
Long switch case Note
SAI_COMMON_API_BULK_REMOVE (39 lines)
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azpw run |
/AzurePipelines run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azpw run |
/AzurePipelines run |
Azure Pipelines successfully started running 1 pipeline(s). |
Tests are failing due to build using older swss-common which is missing PR sonic-net/sonic-swss-common#966. Test is using swss-common built here - https://dev.azure.com/mssonic/build/_build/results?buildId=757465 which is from a previous commit. Waiting for a new swss-common build |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
DEPENDS ON sonic-net/sonic-swss-common#966.
Implement bulk get support for SAIRedis, Syncd, SaiPlayer and VSlib.