papi: introduce read_blocking

Previously, self.transport.q got the messages
(at least for socket transport), stored in the encoded (packed) form.
In order to avoid accessing internals for async reads,
a new method is introduced, to perform
blocking reads of decoded (unpacked) messages.

The method is also used in _call_vpp(),
so sync and async reads are kept compatible.

Type: feature

Change-Id: Id49792dfa57c00b1a14a198031c5398d09a9ba20
Signed-off-by: Vratko Polak <vrpolak@cisco.com>
This commit is contained in:
Vratko Polak
2019-09-10 13:35:11 +02:00
committed by Ole Trøan
parent d6f1c9c514
commit 0938547eaa

View File

@ -645,10 +645,9 @@ class VPPApiClient(object):
# Block until we get a reply.
rl = []
while (True):
msg = self.transport.read()
if not msg:
r = self.read_blocking(no_type_conversion)
if r is None:
raise VPPIOError(2, 'VPP API client: read failed')
r = self.decode_incoming_msg(msg, no_type_conversion)
msgname = type(r).__name__
if context not in r or r.context == 0 or context != r.context:
# Message being queued
@ -700,6 +699,33 @@ class VPPApiClient(object):
self.transport.write(b)
return context
def read_blocking(self, no_type_conversion=False):
"""Get next received message from transport within timeout, decoded.
Note that noticifations have context zero
and are not put into receive queue (at least for socket transport),
use async_thread with registered callback for processing them.
If no message appears in the queue within timeout, return None.
Optionally, type conversion can be skipped,
as some of conversions are into less precise types.
When r is the return value of this, the caller can get message name as:
msgname = type(r).__name__
and context number (type long) as:
context = r.context
:param no_type_conversion: If false, type conversions are applied.
:type no_type_conversion: bool
:returns: Decoded message, or None if no message (within timeout).
:rtype: Whatever VPPType.unpack returns, depends on no_type_conversion.
"""
msg = self.transport.read()
if not msg:
return None
return self.decode_incoming_msg(msg, no_type_conversion)
def register_event_callback(self, callback):
"""Register a callback for async messages.