pyroute2
pyroute2 copied to clipboard
exception - queue full in nlsocket - async_recv()
example code:
with IPRoute() as ipr: # With IPRoute objects you have to call bind() manually ipr.bind(async_cache=True) while True: try: for message in ipr.get(): <....> except OSError as e: raise e
callstack: for message in ipr.get(): File "/usr/local/lib/python3.9/site-packages/pr2modules/netlink/nlsocket.py", line 394, in get return tuple(self._genlm_get(*argv, **kwarg)) File "/usr/local/lib/python3.9/site-packages/pr2modules/netlink/nlsocket.py", line 788, in get data = self.recv_ft(bufsize) File "/usr/local/lib/python3.9/site-packages/pr2modules/netlink/nlsocket.py", line 1067, in recv_plugin raise data_in File "/usr/local/lib/python3.9/site-packages/pr2modules/netlink/nlsocket.py", line 580, in async_recv self.buffer_queue.put_nowait(data) File "/usr/lib64/python3.9/queue.py", line 191, in put_nowait return self.put(item, block=False) File "/usr/lib64/python3.9/queue.py", line 137, in put raise Full
Looks like the parser doesn't manage to handle the packet flow.
Possible solutions:
1. increase the buffer queue
from pyroute2 import config, IPRoute
config.async_qsize = X
ipr = IPRoute()
# or
from pyroute2 import IPRoute
ipr = IPRoute(async_qsize=X)
Where X is the queue max size, by default 4096. The socket uses 64K buffers for each recv_into()
, so consider memory usage as well.
2. use a custom parser
IPRoute
objects have .marshal
to run parsers on incoming messages.
IPRoute.marshal.msg_map = {msg_type: parser}
IPRoute.marshal.seq_map = {sequence_number: parser}
More on parsers and how to run own implementations: https://docs.pyroute2.org/parser.html
Looks like the parser doesn't manage to handle the packet flow.
Possible solutions:
1. increase the buffer queue
from pyroute2 import config, IPRoute config.async_qsize = X ipr = IPRoute() # or from pyroute2 import IPRoute ipr = IPRoute(async_qsize=X)
Where X is the queue max size, by default 4096. The socket uses 64K buffers for each
recv_into()
, so consider memory usage as well.2. use a custom parser
IPRoute
objects have.marshal
to run parsers on incoming messages.IPRoute.marshal.msg_map = {msg_type: parser} IPRoute.marshal.seq_map = {sequence_number: parser}
More on parsers and how to run own implementations: https://docs.pyroute2.org/parser.html
As I understand this could happen due to temporal event storm, in which case the parser will lose pace against the socket reader, and the queue will get full. Is there a way to somehow instruct the API to restrict which events it should deliver via the socket?
@LuiGuest there are three ways setting up that:
- Using
groups
--ipr.bind(groups=...)
, seepyroute2.netlink.rtnl.RTMGRP_*
(becomes deprecated in the Linux kernel, but still used by default in the library) - Using membership --
ipr.add_membership(...)
/ipr.drop_membership(...)
, seepyroute2.netlink.rtnl.RTNLGRP_*
- Using custom parsers and assigning to particular message types (
ipr.marshal.msg_map
) or sequence numbers (ipr.marshal.seq_map
)
...
- and 2. will instruct the kernel not to send some message types, while 3. makes pyroute2 to drop received messages w/o parsing them (by the default parser)
- RTMGRP_
Thank You a lot for your help!