Migrating to version 3
Version 3 makes a number of breaking changes, for the purpose of keeping the number of constructor arguments under control and making future extension more manageable. Almost all code will need to be updated, but the updates will in most cases be minor.
To allow for code that wishes to support both version 3 and older versions, C++ macros are defined to allow the version number to be interrogated at compile time. Thus, version 3 can be detected as
#if defined(SPEAD2_MAJOR) && SPEAD2_MAJOR >= 3
// Version 3 or later
#else
// Older
#endif
Note that version 3.0.0b1 did not define these macros, but also did not include the breaking changes.
-
SPEAD2_MAJOR
Major version of spead2 e.g.,
3
for version 3.4.6.
-
SPEAD2_MINOR
Minor version of spead2 e.g.,
4
for version 3.4.6.
-
SPEAD2_PATCH
Patch level of spead2 e.g.,
6
for version 3.4.6.
-
SPEAD2_VERSION
Full spead2 version number, as a string constant.
In Python, one can get the full version string from
spead2.__version__
. Use the classes in packaging.version
to analyse it.
Receive stream configuration
Prior to version 3, some parameters to configure a stream were passed directly
to the constructor (e.g., the maximum number of partial heaps), while others
were set by methods after construction (such as the memory allocator). In
version 3, all these parameters are set at construction time, and they are
held in helper classes spead2.recv.StreamConfig
and
spead2.recv.RingStreamConfig
(spead2::recv::stream_config
and
spead2::recv::ring_stream_config
for C++). Code will need to be
modified to construct these helper objects.
Similarly, for ibverbs there is now a
spread.recv.UdpIbvConfig
that is used to configure the reader. The old
forms of spead.recv.Stream.add_udp_ibv_reader()
are still present but
are deprecated.
In version 2 it was also possible (although not recommended) to change parameters like the memory allocator after readers had already been placed. For efficiency reasons this is no longer supported in version 3.
Send stream configuration
The changes for sending are more minor: the constructor for the Python class
spead2.send.StreamConfig
now only takes keyword arguments, and the
C++ equivalent spead2::send::stream_config
takes no constructor
arguments. To make it convenient to construct temporaries, the
setter methods return the object, allowing configurations to be constructed in
a “fluent” style e.g.:
spead2::send::stream_config().set_max_packet_size(9172).set_rate(1e6)
For ibverbs streams the changes are more significant. There
is now a spead2.send.UdpIbvConfig
class that works similarly
to spead2.send.StreamConfig
, but configures properties specific to
the ibverbs stream. The old constructor is still available (but deprecated);
however, the constants UdpIbvStream.DEFAULT_BUFFER_SIZE
and
UdpIbvStream.DEFAULT_MAX_POLL
have moved to the
UdpIbvConfig
class.
Substreams
A new feature is the ability to create a send stream with multiple destinations and select the destination on a per-heap basis (see Substreams for more information). Supporting this cleanly required a number of changes:
The
spead2.send.InprocStream.queue
attribute has been replaced withqueues
. Similarly, the C++spead2::send::inproc_stream::get_queue()
has been replaced byget_queues()
. The originals are still present but deprecated, and raise aRuntimeError
if the stream was constructed with multiple queues.The constructors for most send stream types now accept a list of endpoints (or queues) rather than a single endpoint (queue). The old constructors are still supported for backwards compatibility, but are deprecated.
The spead2_send and spead2_send.py example programs now take the destination in the form
host:port
instead ofhost port
, and support multiple destinations.
Out-of-order packets
In prior versions of spead2, the packets forming a single heap could be received in any order. Starting with version 3, the default is to assume that packets arrive in order. Refer to Packet ordering for more details.
Loop argument to asyncio functions
The Python asyncio-based classes and functions no longer take a loop
argument. As of Python 3.6, asyncio.get_event_loop()
returns the
executing event loop, so there is no need to pass the loop explicitly.
Command-line arguments in tools
The command-line handling in spead2_send, spead2_recv and
spead2_bench has been overhauled and made more consistent. For
example, spead_bench now supports the --ttl
option, and
--send-ibv
is now an argument-less flag with the interface address given
by --send-bind
(and similarly for receive). See the help for each
command for details of the current options.
Removal of deprecated functionality
The following functions were deprecated in version 2 and have been removed in version 3:
C++ stream constructors that specified a socket but not an
io_service
(they could not be supported with Boost 1.70 onwards).Stream constructors that took both an existing (but unconnected) socket and a buffer size or a port to bind to. The caller should instead bind the socket (if receiving) and set any desired buffer size socket option.
Queue depth for sending with ibverbs
When using ibverbs to send data, heaps were previously considered
complete once the packets were submitted to the hardware. They’re now only
considered complete once the hardware has indicated completion, which allows
for errors to be reported. While there are no breaking API changes, if the
heaps are very small it may be necessary to increase max_heaps in
StreamConfig
so that enough heaps can be in
flight to fully utilise the buffer.