Updates for pyoxenmq 1.0.0

Makes some send/connection options more robust to "do nothing" runtime
value, which the Python wrapper needs.

Also found a bunch of doc typos and fixes.

Bump version to 1.2.8 so that new pyoxenmq can build-depend on it.
This commit is contained in:
Jason Rhinelander 2021-10-21 22:30:25 -03:00
parent f0bb2c3d3f
commit 39b6d89037
3 changed files with 29 additions and 30 deletions

View File

@ -17,7 +17,7 @@ cmake_minimum_required(VERSION 3.7)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)") set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)")
project(liboxenmq project(liboxenmq
VERSION 1.2.7 VERSION 1.2.8
LANGUAGES CXX C) LANGUAGES CXX C)
include(GNUInstallDirs) include(GNUInstallDirs)
@ -120,12 +120,8 @@ if(WARNINGS_AS_ERRORS)
target_compile_options(oxenmq PRIVATE -Werror) target_compile_options(oxenmq PRIVATE -Werror)
endif() endif()
set_target_properties(oxenmq PROPERTIES target_compile_features(oxenmq PUBLIC cxx_std_17)
CXX_STANDARD 17 set_target_properties(oxenmq PROPERTIES POSITION_INDEPENDENT_CODE ON)
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
POSITION_INDEPENDENT_CODE ON
)
function(link_dep_libs target linktype libdirs) function(link_dep_libs target linktype libdirs)
foreach(lib ${ARGN}) foreach(lib ${ARGN})

View File

@ -163,9 +163,8 @@ struct address {
/// Returns a QR-code friendly address string. This returns an all-uppercase version of the /// Returns a QR-code friendly address string. This returns an all-uppercase version of the
/// address with "TCP://" or "CURVE://" for the protocol string, and uses upper-case base32z /// address with "TCP://" or "CURVE://" for the protocol string, and uses upper-case base32z
/// encoding for the pubkey (for curve addresses). For literal IPv6 addresses we replace the /// encoding for the pubkey (for curve addresses). For literal IPv6 addresses we surround the
/// surround the /// address with $ instead of [...]
/// address with $ instead of $
/// ///
/// \throws std::logic_error if called on a unix socket address. /// \throws std::logic_error if called on a unix socket address.
std::string qr_address() const; std::string qr_address() const;

View File

@ -448,7 +448,7 @@ private:
/// indices of idle, active workers /// indices of idle, active workers
std::vector<unsigned int> idle_workers; std::vector<unsigned int> idle_workers;
/// Maximum number of general task workers, specified by g`/during construction /// Maximum number of general task workers, specified by set_general_threads()
int general_workers = std::max<int>(1, std::thread::hardware_concurrency()); int general_workers = std::max<int>(1, std::thread::hardware_concurrency());
/// Maximum number of possible worker threads we can have. This is calculated when starting, /// Maximum number of possible worker threads we can have. This is calculated when starting,
@ -786,13 +786,6 @@ public:
* listening in curve25519 mode (otherwise we couldn't verify its authenticity). Should return * listening in curve25519 mode (otherwise we couldn't verify its authenticity). Should return
* empty for not found or if SN lookups are not supported. * empty for not found or if SN lookups are not supported.
* *
* @param allow_incoming is a callback that OxenMQ can use to determine whether an incoming
* connection should be allowed at all and, if so, whether the connection is from a known
* service node. Called with the connecting IP, the remote's verified x25519 pubkey, and the
* called on incoming connections with the (verified) incoming connection
* pubkey (32-byte binary string) to determine whether the given SN should be allowed to
* connect.
*
* @param log a function or callable object that writes a log message. If omitted then all log * @param log a function or callable object that writes a log message. If omitted then all log
* messages are suppressed. * messages are suppressed.
* *
@ -1033,7 +1026,7 @@ public:
* @param pubkey - the public key (32-byte binary string) of the service node to connect to * @param pubkey - the public key (32-byte binary string) of the service node to connect to
* @param options - connection options; see the structs in `connect_option`, in particular: * @param options - connection options; see the structs in `connect_option`, in particular:
* - keep_alive -- how long the SN connection will be kept alive after valid activity * - keep_alive -- how long the SN connection will be kept alive after valid activity
* - remote_hint -- a remote address hint that may be used instead of doing a lookup * - hint -- a remote address hint that may be used instead of doing a lookup
* - ephemeral_routing_id -- allows you to override the EPHEMERAL_ROUTING_ID option for * - ephemeral_routing_id -- allows you to override the EPHEMERAL_ROUTING_ID option for
* this connection. * this connection.
* *
@ -1119,8 +1112,7 @@ public:
* *
* @param linger how long to allow the connection to linger while there are still pending * @param linger how long to allow the connection to linger while there are still pending
* outbound messages to it before disconnecting and dropping any pending messages. (Note that * outbound messages to it before disconnecting and dropping any pending messages. (Note that
* this lingering is internal; the disconnect_remote() call does not block). The default is 1 * this lingering is internal; the disconnect() call does not block). The default is 1 second.
* second.
* *
* If given a pubkey, we try to close an outgoing connection to the given SN if one exists; note * If given a pubkey, we try to close an outgoing connection to the given SN if one exists; note
* however that this is often not particularly useful as messages to that SN can immediately * however that this is often not particularly useful as messages to that SN can immediately
@ -1134,8 +1126,8 @@ public:
* if not already connected). * if not already connected).
* *
* If a new connection is established it will have a relatively short (30s) idle timeout. If * If a new connection is established it will have a relatively short (30s) idle timeout. If
* the connection should stay open longer you should either call `connect(pubkey, IDLETIME)` or * the connection should stay open longer you should either call `connect_sn(pubkey, IDLETIME)`
* pass a a `send_option::keep_alive{IDLETIME}` in `opts`. * or pass a a `send_option::keep_alive{IDLETIME}` in `opts`.
* *
* Note that this method (along with connect) doesn't block waiting for a connection or for the * Note that this method (along with connect) doesn't block waiting for a connection or for the
* message to send; it merely instructs the proxy thread that it should send. ZMQ will * message to send; it merely instructs the proxy thread that it should send. ZMQ will
@ -1289,9 +1281,9 @@ public:
/** /**
* Adds a timer that gets scheduled periodically in the job queue. Normally jobs are not * Adds a timer that gets scheduled periodically in the job queue. Normally jobs are not
* double-booked: that is, a new timed job will not be scheduled if the timer fires before a * double-booked: that is, a new timed job will not be scheduled if the timer fires before a
* previously scheduled callback of the job has not yet completed. If you want to override this * previously scheduled callback of the job has completed. If you want to override this (so
* (so that, under heavy load or long jobs, there can be more than one of the same job scheduled * that, under heavy load or long jobs, there can be more than one of the same job scheduled or
* or running at a time) then specify `squelch` as `false`. * running at a time) then specify `squelch` as `false`.
* *
* The returned value can be kept and later passed into `cancel_timer()` if you want to be able * The returned value can be kept and later passed into `cancel_timer()` if you want to be able
* to cancel a timer. * to cancel a timer.
@ -1427,6 +1419,8 @@ struct outgoing {
/// Specifies the idle timeout for the connection - if a new or existing outgoing connection is used /// Specifies the idle timeout for the connection - if a new or existing outgoing connection is used
/// for the send and its current idle timeout setting is less than this value then it is updated. /// for the send and its current idle timeout setting is less than this value then it is updated.
///
/// A negative value is treated as if the option were not supplied at all.
struct keep_alive { struct keep_alive {
std::chrono::milliseconds time; std::chrono::milliseconds time;
explicit keep_alive(std::chrono::milliseconds time) : time{std::move(time)} {} explicit keep_alive(std::chrono::milliseconds time) : time{std::move(time)} {}
@ -1437,6 +1431,8 @@ struct keep_alive {
/// (This has no effect if specified on a non-request() call). Note that requests failures are only /// (This has no effect if specified on a non-request() call). Note that requests failures are only
/// processed in the CONN_CHECK_INTERVAL timer, so it can be up to that much longer than the time /// processed in the CONN_CHECK_INTERVAL timer, so it can be up to that much longer than the time
/// specified here before a failure callback is invoked. /// specified here before a failure callback is invoked.
///
/// Specifying a negative timeout is equivalent to not specifying the option at all.
struct request_timeout { struct request_timeout {
std::chrono::milliseconds time; std::chrono::milliseconds time;
explicit request_timeout(std::chrono::milliseconds time) : time{std::move(time)} {} explicit request_timeout(std::chrono::milliseconds time) : time{std::move(time)} {}
@ -1482,7 +1478,7 @@ namespace connect_option {
/// the default (OxenMQ::EPHEMERAL_ROUTING_ID). See OxenMQ::EPHEMERAL_ROUTING_ID for a description /// the default (OxenMQ::EPHEMERAL_ROUTING_ID). See OxenMQ::EPHEMERAL_ROUTING_ID for a description
/// of this. /// of this.
/// ///
/// Typically use: `connect_options::ephemeral_routing_id{}` or `connect_options::ephemeral_routing_id{false}`. /// Typically use: `connect_option::ephemeral_routing_id{}` or `connect_option::ephemeral_routing_id{false}`.
struct ephemeral_routing_id { struct ephemeral_routing_id {
bool use_ephemeral_routing_id = true; bool use_ephemeral_routing_id = true;
// Constructor; default construction gives you ephemeral routing id, but the bool parameter can // Constructor; default construction gives you ephemeral routing id, but the bool parameter can
@ -1502,6 +1498,8 @@ struct timeout {
/// milliseconds. If an outgoing connection already exists, the longer of the existing and the /// milliseconds. If an outgoing connection already exists, the longer of the existing and the
/// given keep alive is used. /// given keep alive is used.
/// ///
/// A negative value is treated as if the keep_alive option had not been specified.
///
/// Note that, if not specified, the default keep-alive for a connection established via /// Note that, if not specified, the default keep-alive for a connection established via
/// connect_sn() is 5 minutes (which is much longer than the default for an implicit connect() by /// connect_sn() is 5 minutes (which is much longer than the default for an implicit connect() by
/// calling send() directly with a pubkey.) /// calling send() directly with a pubkey.)
@ -1517,6 +1515,7 @@ struct keep_alive {
/// potentially expensive lookup call). /// potentially expensive lookup call).
struct hint { struct hint {
std::string address; std::string address;
// Constructor taking a hint. If the hint is an empty string then no hint will be used.
explicit hint(std::string_view address) : address{address} {} explicit hint(std::string_view address) : address{address} {}
}; };
@ -1570,6 +1569,7 @@ void apply_send_option(bt_list& parts, bt_dict&, const send_option::data_parts_i
/// `hint` specialization: sets the hint in the control data /// `hint` specialization: sets the hint in the control data
inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::hint& hint) { inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::hint& hint) {
if (hint.connect_hint.empty()) return;
control_data["hint"] = hint.connect_hint; control_data["hint"] = hint.connect_hint;
} }
@ -1590,12 +1590,14 @@ inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option
/// `keep_alive` specialization: increases the outgoing socket idle timeout (if shorter) /// `keep_alive` specialization: increases the outgoing socket idle timeout (if shorter)
inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::keep_alive& timeout) { inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::keep_alive& timeout) {
control_data["keep_alive"] = timeout.time.count(); if (timeout.time >= 0ms)
control_data["keep_alive"] = timeout.time.count();
} }
/// `request_timeout` specialization: set the timeout time for a request /// `request_timeout` specialization: set the timeout time for a request
inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::request_timeout& timeout) { inline void apply_send_option(bt_list&, bt_dict& control_data, const send_option::request_timeout& timeout) {
control_data["request_timeout"] = timeout.time.count(); if (timeout.time >= 0ms)
control_data["request_timeout"] = timeout.time.count();
} }
/// `queue_failure` specialization /// `queue_failure` specialization
@ -1640,10 +1642,12 @@ inline void apply_connect_option(OxenMQ& omq, bool remote, bt_dict& opts, const
else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::timeout ignored for connect_sn(...)"); else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::timeout ignored for connect_sn(...)");
} }
inline void apply_connect_option(OxenMQ& omq, bool remote, bt_dict& opts, const connect_option::keep_alive& ka) { inline void apply_connect_option(OxenMQ& omq, bool remote, bt_dict& opts, const connect_option::keep_alive& ka) {
if (!remote) opts["keep_alive"] = ka.time.count(); if (ka.time < 0ms) return;
else if (!remote) opts["keep_alive"] = ka.time.count();
else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::keep_alive ignored for connect_remote(...)"); else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::keep_alive ignored for connect_remote(...)");
} }
inline void apply_connect_option(OxenMQ& omq, bool remote, bt_dict& opts, const connect_option::hint& hint) { inline void apply_connect_option(OxenMQ& omq, bool remote, bt_dict& opts, const connect_option::hint& hint) {
if (hint.address.empty()) return;
if (!remote) opts["hint"] = hint.address; if (!remote) opts["hint"] = hint.address;
else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::hint ignored for connect_remote(...)"); else omq.log(LogLevel::warn, __FILE__, __LINE__, "connect_option::hint ignored for connect_remote(...)");
} }