diff options
author | Ole Troan <ot@cisco.com> | 2020-05-20 15:47:06 +0200 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2020-05-25 11:22:34 +0000 |
commit | f5db3711b28db4e364ac01be8b124dd24d573782 (patch) | |
tree | eee3c8aabae4287bf89c0e545e2400770fc223cb /src/tools/vppapigen | |
parent | afc233aa93c3f23b30b756cb4ae2967f968bbbb1 (diff) |
api: add new stream message convention
Instead of having to wrap dump/detail calls in control ping, send details messages in between a normal
reply / request pair. As expressed in the below service statement.
Example:
service {
rpc map_domains_gets returns map_domains_get_reply
stream map_domain_details;
};
define map_domains_get
{
u32 client_index;
u32 context;
u32 cursor;
};
define map_domains_get_reply
{
u32 context;
i32 retval;
u32 cursor;
};
To avoid blocking the main thread for too long, the replies are now sent in client message queue size
chunks. The reply message returns VNET_API_ERROR_EAGAIN when there is more to read.
The API handler must also include a "cursor" that is used to the next call to the get function.
API handler example:
REPLY_AND_DETAILS_MACRO (VL_API_MAP_DOMAINS_GET_REPLY, mm->domains,
({
send_domain_details (cursor, rp, mp->context);
}));
The macro starts from cursor and iterates through the pool
until vl_api_process_may_suspend() returns true or the iteration
reaches the end of the list.
Client Example:
cursor = 0
d = []
while True:
rv, details = map_domains_get(cursor=cursor)
d += details
if rv.retval == 0 or rv.retval != -165:
break
cursor = rv.cursor
or the convenience iterator:
for x in vpp.details_iter(vpp.api.map_domains_get):
pass
or
list(details_iter(map_domains_get))
Change-Id: Iad9f6b41b0ef886adb584c97708dd91cf552749e
Type: feature
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/tools/vppapigen')
-rwxr-xr-x | src/tools/vppapigen/vppapigen.py | 7 | ||||
-rw-r--r-- | src/tools/vppapigen/vppapigen_json.py | 2 |
2 files changed, 8 insertions, 1 deletions
diff --git a/src/tools/vppapigen/vppapigen.py b/src/tools/vppapigen/vppapigen.py index 06bfbff238f..94e770e38bc 100755 --- a/src/tools/vppapigen/vppapigen.py +++ b/src/tools/vppapigen/vppapigen.py @@ -176,10 +176,11 @@ def vla_is_last_check(name, block): class Service(): - def __init__(self, caller, reply, events=None, stream=False): + def __init__(self, caller, reply, events=None, stream_message=None, stream=False): self.caller = caller self.reply = reply self.stream = stream + self.stream_message = stream_message self.events = [] if events is None else events @@ -511,6 +512,10 @@ class VPPAPIParser(object): else: p[0] = Service(p[2], p[4]) + def p_service_statement2(self, p): + '''service_statement : RPC ID RETURNS ID STREAM ID ';' ''' + p[0] = Service(p[2], p[4], stream_message=p[6], stream=True) + def p_event_list(self, p): '''event_list : events | event_list events ''' diff --git a/src/tools/vppapigen/vppapigen_json.py b/src/tools/vppapigen/vppapigen_json.py index 35dcbcafbbd..6e7aaa2e6f5 100644 --- a/src/tools/vppapigen/vppapigen_json.py +++ b/src/tools/vppapigen/vppapigen_json.py @@ -26,6 +26,8 @@ def walk_services(s): d = {'reply': e.reply} if e.stream: d['stream'] = True + if e.stream_message: + d['stream_msg'] = e.stream_message if e.events: d['events'] = e.events r[e.caller] = d |