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 .. code-block:: c++ #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. .. c:macro:: SPEAD2_MAJOR Major version of spead2 e.g., ``3`` for version 3.4.6. .. versionadded: 3.0 .. c:macro:: SPEAD2_MINOR Minor version of spead2 e.g., ``4`` for version 3.4.6. .. c:macro:: SPEAD2_PATCH Patch level of spead2 e.g., ``6`` for version 3.4.6. .. c:macro:: SPEAD2_VERSION Full spead2 version number, as a string constant. In Python, one can get the full version string from :py:data:`spead2.__version__`. Use the classes in :py:mod:`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 :py:class:`spead2.recv.StreamConfig` and :py:class:`spead2.recv.RingStreamConfig` (:cpp:class:`spead2::recv::stream_config` and :cpp:class:`spead2::recv::ring_stream_config` for C++). Code will need to be modified to construct these helper objects. Similarly, for :doc:`ibverbs ` there is now a :class:`spread.recv.UdpIbvConfig` that is used to configure the reader. The old forms of :py:meth:`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 :py:class:`spead2.send.StreamConfig` now only takes keyword arguments, and the C++ equivalent :class:`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.: .. code-block:: c++ spead2::send::stream_config().set_max_packet_size(9172).set_rate(1e6) For :doc:`ibverbs ` streams the changes are more significant. There is now a :py:class:`spead2.send.UdpIbvConfig` class that works similarly to :py:class:`spead2.send.StreamConfig`, but configures properties specific to the ibverbs stream. The old constructor is still available (but deprecated); however, the constants :py:data:`.UdpIbvStream.DEFAULT_BUFFER_SIZE` and :py:data:`.UdpIbvStream.DEFAULT_MAX_POLL` have moved to the :class:`~spead2.send.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 :ref:`py-substreams` for more information). Supporting this cleanly required a number of changes: - The :attr:`spead2.send.InprocStream.queue` attribute has been replaced with :attr:`~spead2.send.InprocStream.queues`. Similarly, the C++ :cpp:func:`spead2::send::inproc_stream::get_queue` has been replaced by :cpp:func:`~spead2::send::inproc_stream::get_queues`. The originals are still present but deprecated, and raise a :py:exc:`RuntimeError` 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 :program:`spead2_send` and :program:`spead2_send.py` example programs now take the destination in the form :samp:`{host}:{port}` instead of :samp:`{host} {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 :ref:`py-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, :py:func:`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 :program:`spead2_send`, :program:`spead2_recv` and :program:`spead2_bench` has been overhauled and made more consistent. For example, :program:`spead_bench` now supports the :option:`!--ttl` option, and :option:`!--send-ibv` is now an argument-less flag with the interface address given by :option:`!--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 :cpp:class:`!io_context` (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 :doc:`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 :py:class:`~spead2.send.StreamConfig` so that enough heaps can be in flight to fully utilise the buffer.