Commit Graph

226 Commits

Author SHA1 Message Date
Jason Rhinelander 780246858f Add `is_unsigned_integer` to bt_{dict,list}_consumer
Also adds missing consume_dict_consumer/consume_list_consumer to
bt_list_consumer to match the bt_dict_consumer interface.
2021-06-08 00:58:20 -03:00
Jason Rhinelander 0287f7834e Minor doc fix 2021-06-02 13:16:19 -03:00
Jason Rhinelander cdc6a9709c Add thread-safe timerid assignment version of add_timer()
I realized after merging the previous PR that it is difficult to
correctly pass ownership into a timer, because something like:

    TimerID x = omq.add_timer([&] { omq.cancel_timer(x); }, 5ms);

doesn't work when the timer job needs to outlive the caller.  My next
approach was:

    auto x = std::make_shared<TimerID>();
    *x = omq.add_timer([&omq, x] { omq.cancel_timer(*x); }, 5ms);

but this has two problems: first, TimerID wasn't default constructible,
and second, there is no guarantee that the assignment to *x happens
before (and is visible to) the access for the cancellation.

This commit fixes both issues: TimerID is now default constructible, and
an overload is added that takes the lvalue reference to the TimerID to
set rather than returning it (and guarantees that it will be set before
the timer is created).
2021-05-25 17:29:25 -03:00
Jason Rhinelander 3991f50547 Bump project version in dev branch (for next release) 2021-05-23 10:36:44 -03:00
Jason Rhinelander 26745299ed Add timer cancellation & timer tests
Updates `add_timer` to return a new opaque TimerID object that can later
be passed to `cancel_timer` to cancel an existing timer.

Also adds timer tests, which was omitted (except for one in the tagged
threads section), along with a new test for timer deletion.
2021-05-20 22:05:58 -03:00
Jason Rhinelander 4ef1060e3f
Merge pull request #36 from jagerman/optional-send-parts
Add support for std::optional<T> send arguments
2021-04-20 14:06:16 -03:00
Jason Rhinelander 5ccacafdb1 Add support for std::optional<T> send arguments
If the optional is set it gets applied as if you specified the `T` in
the send(...), if unset it works as if you didn't specify the argument
at all.
2021-04-20 13:54:42 -03:00
Jason Rhinelander 6d20a3614a Don't warn when we can't send back to an non-SN incoming connection
This happens commonly when the remote has gone away and we shouldn't be
warning about it.
2021-04-15 20:17:59 -03:00
Jason Rhinelander 39dce56e14
Merge pull request #34 from jagerman/per-connection-pubkey-routing
Per connection pubkey routing
2021-04-15 15:46:09 -03:00
Jason Rhinelander ac58e5b574 Rename PUBKEY_BASED_ROUTING_ID to EPHEMERAL_ROUTING_ID
And similarly for the connect_option
2021-04-15 15:42:04 -03:00
Jason Rhinelander 99a3f1d840 Bump (and cmake-modernize) version 2021-04-15 15:15:44 -03:00
Jason Rhinelander dc40ebd428 Add connect_option::*; allow per-connection pubkey-based routing setting
Storage server, in particular, needs to disable pubkey-based routing on
its connection to oxend (because it is sharing oxend's own keys), but
wants it by default for SS-to-SS connections.  This allows the oxend
connection to turn it off so that we don't have oxend omq connections
replacing each other.
2021-04-15 15:11:54 -03:00
Jason Rhinelander e3e79e1fb7 Bump version 2021-03-09 15:43:44 -04:00
Jason Rhinelander f9ef827075 Make is_bt_tuple constexpr variables inline
Silence clang misc-definitions-in-headers warnings about it.
2021-02-09 21:46:33 -04:00
Jason Rhinelander 506bd65b05 Add better deferred reply capabilities to Message
This provides an interface for sending a reply to a message later (i.e.
after the Message& itself is no longer valid) by using a new
`send_later()` method of the Message instance that returns an object
that can properly route replies (and can outlive the Message it was
called on).

Intended use is:

    run_this_lambda_later([send=msg.send_later()] {
        send.reply("content");
    });

which is equivalent to:

    run_this_lambda_later([&msg] {
        msg.send_reply("content");
    });

except that it works properly even if the lambda is invoked beyond the
lifetime of `msg`.
2021-01-21 11:59:39 -04:00
Jason Rhinelander 86247bc5c7 Add missing header 2021-01-14 21:48:09 -04:00
Jason Rhinelander 396f591fae Remove deprecated string_view compat shim 2021-01-14 15:32:38 -04:00
Jason Rhinelander b49a94fb83 Export compile commands and use ccache by default 2021-01-14 15:32:38 -04:00
Jason Rhinelander 0738695eb9 Add lokimq compatibility headers 2021-01-14 15:32:38 -04:00
Jason Rhinelander 2ae6b96016 Rename LokiMQ to OxenMQ 2021-01-14 15:32:38 -04:00
Jason Rhinelander bd9313bf19 Fix decoding into a std::byte
Decoding into a std::byte output iterator was not working because the
`*out++ = val` assignment doesn't work when the output is std::byte and
val is a char/unsigned char/uint8_t.  Instead we need to explicitly
cast, but figuring out what we have to cast to is a little bit tricky.

This PR makes it work (and bumps the version for this and the is_hex
fix).
2020-12-14 13:05:14 -04:00
Jason Rhinelander 1959f8747d
Merge pull request #28 from jagerman/is-hex-mod-2
Make lokimq::is_hex check for size being a multiple of 2
2020-12-12 21:06:59 -04:00
Jason Rhinelander 90701e5d62 Make lokimq::is_hex check for size being a multiple of 2
`is_hex()` is a bit misleading as `from_hex()` requires an even-length
hex string, but `is_hex()` also allows odd-length hex strings, which
means currently callers should be doing `if (lokimq::is_hex(str) &&
str.size() % 2 == 0)`, but probably aren't.

Since the main point of `lokimq/hex.h` is for byte<->hex conversions it
doesn't make much sense to allow `is_hex()` to return true for something
that can't be validly decoded via `from_hex()`, thus this PR changes it
to return false.

If someone *really* wants to test for an odd-length hex string (though
I'm skeptical that there is a need for this), this also exposes
`is_hex_digit` so that they could use:

    bool all_hex = std::all_of(str.begin(), str.end(), lokimq::is_hex_digit<char>)
2020-12-12 20:25:01 -04:00
Jason Rhinelander 178bd4f674 Bump version for 1.2.2 release 2020-11-17 12:42:37 -04:00
Jason Rhinelander b1543513bb Don't install when building as a static subdirectory
This is making lokimq headers & static lib get installed when lokimq is
used as a project subdirectory, which is very annoying.

This adds an option for enabling the install lines, and only enables it
if doing a shared library or a top-level project build.
2020-11-17 12:40:59 -04:00
Jason Rhinelander 253f1ee66e Move socket holding into LokiMQ instance
The thread_local `std::map` here can end up being destructed *before*
the LokiMQ instance (if both are being destroyed during thread joining),
in which case we segfault by trying to use the map.  Move the owning
container into the LokiMQ instead (indexed by the thread) to prevent
that.

Also cleans this code up by:

- Don't close control sockets from the proxy thread; socket_t's aren't
necessarily thread safe so this could be causing issues where we trouble
double-closing or using a closed socket.

- We can just let them get closed during destruction of the LokiMQ.

- Avoid needing shared_ptr's; instead we can just use a unique pointer
with raw pointers in the thread_local cache.  This simplifies closing
because all closing will happen during the LokiMQ destruction.
2020-11-17 11:54:39 -04:00
Jason Rhinelander d889f308ae cppzmq 4.7+ compatibility
Updates bundled cppzmq to 4.7.1, and replaces deprecated functions with
new API.
2020-11-13 15:20:30 -04:00
Jason Rhinelander 768a639dea Crank clang to 11 2020-10-23 18:18:18 -03:00
Jason Rhinelander ec0d44e143 Stable release bump 2020-10-19 23:44:24 -03:00
Jason Rhinelander ea484729c7 Fix var::get<I> to return references 2020-10-15 17:43:25 -03:00
Jason Rhinelander 7049d3cb5a Test suite: use different ports for each test
Apple, in particular, often fails tests with an address already in use
if attempt to reuse a port that the process just closed, because it is a
wonderful OS.
2020-10-15 16:55:33 -03:00
Jason Rhinelander 8ed529200b macOS 10.12 compatibility
Add var::get/var::visit implementations of std::get/std::visit that get
used if compiling for an old macos target, and use those.

The issue is that on a <10.14 macos target Apple's libc++ is missing
std::bad_variant_access, and so any method that can throw it (such as
std::get and std::visit) can't be used.  This workaround is ugly, but
such is life when you want to support running on Apple platforms.
2020-10-15 16:55:33 -03:00
Jason Rhinelander 318781a6d4 Update macos build to use 10.14 compatibility 2020-10-15 15:49:54 -03:00
Thomas Winget f37e619d7b add method to get current buffer from bt list/dict consumer 2020-09-25 13:23:23 -03:00
Jason Rhinelander 0ac1d48bc8 Update bundled libzmq version 2020-09-16 11:46:04 -03:00
Jeff Becker 0938e1fc53 allow changing uid as root 2020-09-08 14:48:51 -03:00
Jeff Becker 0c9eeeea43 allow an IPC socket to set which group it is owned by using SOCKET_GID similar to how STARTUP_UMASK is done. 2020-09-08 14:48:51 -03:00
Jason Rhinelander 9467c4682c Add C string bt_value ctor 2020-09-01 17:57:18 -03:00
Jason Rhinelander 8c28c52d41 inline constexpr lokimq constants 2020-08-13 15:55:51 -03:00
Jason Rhinelander faeeaa86d4 Add missing headers to installed header list 2020-08-13 12:38:46 -03:00
Jason Rhinelander 8d3ed4606f Drop const from _id
Makes the TaggedThreadID copyable.
2020-08-10 09:50:21 -03:00
Jason Rhinelander 30faadf01a Add serialization/deserialization of tuples and pairs
On the wire they are just lists, but this lets you put tuples onto and
pull tuples off of the wire.  (Also supports std::pair).

Supports direct serialization (via bt_serialize()/bt_deserialize()),
list/dict consumer deserialization, and conversion from a bt_value or
bt_list via a new bt_tuple() function.
2020-08-03 00:40:49 -03:00
Jason Rhinelander d8d1d8677c Replace visitor class with generic lambda 2020-08-03 00:40:49 -03:00
Jason Rhinelander e5cf174b83 Fix & add tests for send_option::data_parts(...)
data_parts() wasn't currently used anywhere, and was broken: it was
calling bt_deserialize which was just wrong.

This repurposes it to take iterators over strings (or string-like types)
and append those parts as message parts.

Also adds tests for it.
2020-07-20 14:37:01 -03:00
Jason Rhinelander af189a8d72 Wait for tagged workers
The `join()`s could hang if the tagged worker threads aren't ready yet,
so retry sending until they become routable.
2020-07-10 17:54:45 -03:00
Jason Rhinelander d2f852c217 Add test that destruction doesn't throw 2020-07-10 17:54:45 -03:00
Jason Rhinelander ee080e0550 Fix tagged workers not being properly shut down
If the LokiMQ object gets destroyed before having called `start()` then
we'd end up destroying the threads for tagged workers without joining
them.  This listens on the internal worker socket (normally the domain
of the proxy thread) and tells them to QUIT if such a destruction
happens.
2020-07-10 17:54:45 -03:00
Jason Rhinelander 7cd58e4677 Add missing header for BSD pthread naming 2020-07-06 12:04:51 -03:00
Jason Rhinelander 9c54264321 Doc fix - remove "init" and update "start" doc
init() got removed during the tagged threads PR, but the documentation
didn't get updated.  Fixed it.
2020-06-30 18:48:09 -03:00
Jason Rhinelander 932bbb33d7 Allow injecting tasks into lokimq job queue
This allows mixing some outside task into the lokimq job queue for a
category (queued up with native LMQ requests for that category) for use
when there is some external process that is able to generate messages.

For example, the most immediate use for this is to allow an HTTP server
to handle incoming RPC requests and, as soon as they arrive, inject them
into LokiMQ's queue for the "rpc" category so that native LMQ rpc
requests and HTTP rpc requests share the same thread pool and queue.

These injected jobs bypass all of LokiMQ's authentication and response
mechanisms: that's up to the invoked callback itself to manage.

Injected tasks are somewhat similar to batch jobs, but unlike batch jobs
the are queued and prioritized as ordinary external LokiMQ requests.
(Batch jobs, in contrast, have a higher scheduling priority, no queue
limits, and typically a larger available thread pool).
2020-06-30 18:44:11 -03:00