From 8809d53871169775e8869328679987ba56e4c426 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Tue, 21 Jul 2020 01:40:45 +0200 Subject: [PATCH] [syncd] Add support for synchronous bulk api (#640) --- syncd/Syncd.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++---- syncd/Syncd.h | 16 ++++-- 2 files changed, 132 insertions(+), 13 deletions(-) diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 07ab90084..9aae66052 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -584,6 +584,8 @@ sai_status_t Syncd::processBulkQuadEvent( const std::vector &values = kfvFieldsValues(kco); + std::vector> strAttributes; + // field = objectId // value = attrid=attrvalue|... @@ -616,6 +618,8 @@ sai_status_t Syncd::processBulkQuadEvent( entries.emplace_back(field, value); } + strAttributes.push_back(entries); + // since now we converted this to proper list, we can extract attributes auto list = std::make_shared(objectType, entries, false); @@ -629,7 +633,7 @@ sai_status_t Syncd::processBulkQuadEvent( if (isInitViewMode()) { - return processBulkQuadEventInInitViewMode(objectType, objectIds, api, attributes); + return processBulkQuadEventInInitViewMode(objectType, objectIds, api, attributes, strAttributes); } if (api != SAI_COMMON_API_BULK_GET) @@ -649,23 +653,24 @@ sai_status_t Syncd::processBulkQuadEvent( if (info->isobjectid) { - return processBulkOid(objectType, objectIds, api, attributes); + return processBulkOid(objectType, objectIds, api, attributes, strAttributes); } else { - return processBulkEntry(objectType, objectIds, api, attributes); + return processBulkEntry(objectType, objectIds, api, attributes, strAttributes); } } sai_status_t Syncd::processBulkQuadEventInInitViewMode( _In_ sai_object_type_t objectType, - _In_ const std::vector &object_ids, + _In_ const std::vector& objectIds, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes) + _In_ const std::vector>& attributes, + _In_ const std::vector>& strAttributes) { SWSS_LOG_ENTER(); - std::vector statuses(object_ids.size()); + std::vector statuses(objectIds.size()); for (auto &a: statuses) { @@ -683,6 +688,9 @@ sai_status_t Syncd::processBulkQuadEventInInitViewMode( if (info->isnonobjectid) { sendApiResponse(api, SAI_STATUS_SUCCESS, (uint32_t)statuses.size(), statuses.data()); + + syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); + return SAI_STATUS_SUCCESS; } @@ -699,6 +707,9 @@ sai_status_t Syncd::processBulkQuadEventInInitViewMode( default: sendApiResponse(api, SAI_STATUS_SUCCESS, (uint32_t)statuses.size(), statuses.data()); + + syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); + return SAI_STATUS_SUCCESS; } @@ -714,9 +725,10 @@ sai_status_t Syncd::processBulkQuadEventInInitViewMode( sai_status_t Syncd::processBulkEntry( _In_ sai_object_type_t objectType, - _In_ const std::vector &objectIds, + _In_ const std::vector& objectIds, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes) + _In_ const std::vector>& attributes, + _In_ const std::vector>& strAttributes) { SWSS_LOG_ENTER(); @@ -794,6 +806,8 @@ sai_status_t Syncd::processBulkEntry( sendApiResponse(api, all, (uint32_t)objectIds.size(), statuses.data()); + syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); + return all; } @@ -829,9 +843,10 @@ sai_status_t Syncd::processEntry( sai_status_t Syncd::processBulkOid( _In_ sai_object_type_t objectType, - _In_ const std::vector &objectIds, + _In_ const std::vector& objectIds, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes) + _In_ const std::vector>& attributes, + _In_ const std::vector>& strAttributes) { SWSS_LOG_ENTER(); @@ -892,6 +907,8 @@ sai_status_t Syncd::processBulkOid( sendApiResponse(api, all, (uint32_t)objectIds.size(), statuses.data()); + syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes); + return all; } @@ -1371,6 +1388,98 @@ void Syncd::syncUpdateRedisQuadEvent( } } +void Syncd::syncUpdateRedisBulkQuadEvent( + _In_ sai_common_api_t api, + _In_ const std::vector& statuses, + _In_ sai_object_type_t objectType, + _In_ const std::vector& objectIds, + _In_ const std::vector>& strAttributes) +{ + SWSS_LOG_ENTER(); + + if (!m_commandLineOptions->m_enableSyncMode) + { + return; + } + + // When in synchronous mode, we need to modify redis database when status + // is success, since consumer table on synchronous mode is not making redis + // changes and we only want to apply changes when api succeeded. This + // applies to init view mode and apply view mode. + + const std::string strObjectType = sai_serialize_object_type(objectType); + + for (size_t idx = 0; idx < statuses.size(); idx++) + { + sai_status_t status = statuses[idx]; + + if (status != SAI_STATUS_SUCCESS) + { + // in case of failure, don't modify database + continue; + } + + auto& objectId = objectIds.at(idx); + + auto& values = strAttributes.at(idx); + + auto key = strObjectType + ":" + objectId; + + sai_object_meta_key_t metaKey; + sai_deserialize_object_meta_key(key, metaKey); + + const bool initView = isInitViewMode(); + + switch (api) + { + case SAI_COMMON_API_BULK_CREATE: + + { + if (initView) + m_client->createTempAsicObject(metaKey, values); + else + m_client->createAsicObject(metaKey, values); + + return; + } + + case SAI_COMMON_API_BULK_REMOVE: + + { + if (initView) + m_client->removeTempAsicObject(metaKey); + else + m_client->removeAsicObject(metaKey); + + return; + } + + case SAI_COMMON_API_BULK_SET: + + { + auto& first = values.at(0); + + auto& attr = fvField(first); + auto& value = fvValue(first); + + if (initView) + m_client->setTempAsicObject(metaKey, attr, value); + else + m_client->setAsicObject(metaKey, attr, value); + + return; + } + + case SAI_COMMON_API_GET: + return; // ignore get since get is not modifying db + + default: + + SWSS_LOG_THROW("api %d is not supported", api); + } + } +} + sai_status_t Syncd::processQuadEvent( _In_ sai_common_api_t api, _In_ const swss::KeyOpFieldsValuesTuple &kco) diff --git a/syncd/Syncd.h b/syncd/Syncd.h index 266fb0315..92a31aee7 100644 --- a/syncd/Syncd.h +++ b/syncd/Syncd.h @@ -147,19 +147,22 @@ namespace syncd _In_ sai_object_type_t objectType, _In_ const std::vector &object_ids, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes); + _In_ const std::vector> &attributes, + _In_ const std::vector>& strAttributes); sai_status_t processBulkEntry( _In_ sai_object_type_t objectType, _In_ const std::vector &object_ids, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes); + _In_ const std::vector> &attributes, + _In_ const std::vector>& strAttributes); sai_status_t processBulkQuadEventInInitViewMode( _In_ sai_object_type_t objectType, _In_ const std::vector &object_ids, _In_ sai_common_api_t api, - _In_ const std::vector> &attributes); + _In_ const std::vector> &attributes, + _In_ const std::vector>& strAttributes); sai_status_t processOid( _In_ sai_object_type_t objectType, @@ -221,6 +224,13 @@ namespace syncd _In_ sai_common_api_t api, _In_ const swss::KeyOpFieldsValuesTuple &kco); + void syncUpdateRedisBulkQuadEvent( + _In_ sai_common_api_t api, + _In_ const std::vector& statuses, + _In_ sai_object_type_t objectType, + _In_ const std::vector& objectIds, + _In_ const std::vector>& strAttributes); + public: // TODO to private sai_status_t processEntry(