When Orchagent creates new SAI object, it actually performs two operations on Redis DB:
- Enqueue SAI object create operation through LPUSH (in fact, Redis linked list object is used as an queue to pass SAI object data between Orchagent and Syncd);
- Inform Syncd about new data in the linked list through PUBLISH operation;
/*
* KEYS[1] : tableName + "_KEY_VALUE_OP_QUEUE
* ARGV[1] : key
* ARGV[2] : value
* ARGV[3] : op
* KEYS[2] : tableName + "_CHANNEL"
* ARGV[4] : "G"
*/
string luaEnque =
"redis.call('LPUSH', KEYS[1], ARGV[1], ARGV[2], ARGV[3]);"
"redis.call('PUBLISH', KEYS[2], ARGV[4]);";
Where 'op' string consists of two parts: DB operation ("S" - set, "D" - delete) and SAI operation ("create", "notify", "set", etc);
Both orchagent and syncd use VIDCOUNTER to generate new VID values.
/*
* Current VID format:
*
* bits 63..56 - switch index
* bits 55..48 - SAI object type
* bits 47..40 - global context
* bits 40..0 - object index
*/
For more information, please refer to VirtualObjectIdManager::allocateNewObjectId() located in: sonic-sairedis/lib/src/VirtualObjectIdManager.cpp
LPUSH ASIC_STATE_KEY_VALUE_OP_QUEUE "SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000" '["SAI_SWITCH_ATTR_INIT_SWITCH","true","SAI_SWITCH_ATTR_SRC_MAC_ADDRESS","52:54:00:EE:BB:70"]' Screate
PUBLISH ASIC_STATE_CHANNEL G
redis-cli -n 1 LRANGE GETRESPONSE_KEY_VALUE_OP_QUEUE 0 -1
redis-cli -n 1 DEL GETRESPONSE_KEY_VALUE_OP_QUEUE
1) "Sgetresponse"
2) "[]"
3) "SAI_STATUS_SUCCESS"
LPUSH ASIC_STATE_KEY_VALUE_OP_QUEUE "SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000" '["SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID","oid:0x0"]' Sget
PUBLISH ASIC_STATE_CHANNEL G
redis-cli -n 1 LRANGE GETRESPONSE_KEY_VALUE_OP_QUEUE 0 -1
redis-cli -n 1 DEL GETRESPONSE_KEY_VALUE_OP_QUEUE
1) "Sgetresponse"
2) "[\"SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID\",\"oid:0x3000000000022\"]"
3) "SAI_STATUS_SUCCESS"