Compare commits

...

191 Commits

Author SHA1 Message Date
Alexey Rybalchenko
091d0824d1 ofi: fix Events() signature 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
857aa84fa3 add mlock/zero options to unmanaged region 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
c85d6e079c shm: reduce shm contention when dealing with ack queues 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
4e466514d2 region example: fix msg counter 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
8b4056e408 Update docs 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
b67b80e0ad shmmonitor: add severity setting 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
2c89b24857 shm: eliminate race/deadlock in region subscriptions 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
c6a6a5f21b Check transport type of msg and corresponding region 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
9defa71622 Add GetType() to UnmanagedRegion 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
ed2dcedf03 Add operator<< for fair::mq::Transport 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
a3d56b9aeb configurable transport for region example script 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
8a2641d842 shm: check result of region acquisition 2021-05-07 21:33:15 +02:00
Alexey Rybalchenko
2ca62d06db shm region cache: fix multiple sessions issue 2021-05-07 14:20:00 +02:00
Alexey Rybalchenko
87e0ca5450 add region cache test 2021-05-07 14:20:00 +02:00
Gvozden Neskovic
ef5b3c782e improve message counter cache line use 2021-05-07 14:20:00 +02:00
Gvozden Neskovic
f7ba3052aa use thread local cache to avoid interprocess lock on shm GetData 2021-05-07 14:20:00 +02:00
Dennis Klein
a90dbf64de Fix -Wunused-result
Fixes #281
2021-05-07 13:18:12 +02:00
Dennis Klein
9724f184f4 Fallback to Boost.Filesystem on GCC 8 2021-05-07 13:13:16 +02:00
Dennis Klein
057ba03776 PluginManager: Do not load built-in plugins via dlopen/dlsym
fixes #351
2021-05-05 03:52:12 +02:00
Giulio Eulisse
6dfea32aee Improve Events API
If the call is interrupted by a signal, this will throw, which we clearly do not want. Simplifying the API to let the user decide what to do on error is probably the best option.
2021-05-04 22:54:19 +02:00
Dennis Klein
868fe02ee9 CI: Submit results to CDash for each build step 2021-04-08 16:22:47 +02:00
Dennis Klein
a2016a9361 CI: Add alice-centos-7 environment 2021-04-08 16:22:47 +02:00
Dennis Klein
ea9aede652 Fallback to <boost/filesystem> on GCC 7 2021-04-08 16:22:47 +02:00
Alexey Rybalchenko
77bf12c8e8 docs patch 2021-04-08 12:38:18 +02:00
Alexey Rybalchenko
f3bc9e05a8 shmmonitor: update docs 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
5facc441b8 shmmonitor: add --list-all 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
2602f53585 Add tools: StrStartsWith, StrEndsWith 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
0976465338 shm: reduce delay between monitor daemon launch & HBs 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
9144258b89 shmmonitor: daemon output to file if FAIRMQ_SHMMONITOR_VERBOSE is true 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
be55565617 shmmonitor: use fairlogger 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
d7e2fbecea shmmonitor: refactor to separate monitoring from output 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
72175e5757 shmmonitor: optimize startup to avoid repeated start 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
effba534f0 shmmonitor: add session name and creator id to the output 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
efd42075a9 shmmonitor: enable read only access 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
5228407932 shmmonitor: distinguish daemon from monitor mode (orthogonal) 2021-04-08 10:11:23 +02:00
Alexey Rybalchenko
30e81d58f8 shmmonitor: allow getting shmids based on session/userid 2021-04-08 10:11:23 +02:00
Dennis Klein
2c7c46f2fd Remove codacy badge 2021-03-26 10:06:10 +01:00
Dennis Klein
0a5122bb24 Remove codecov badge 2021-03-26 10:06:10 +01:00
Dennis Klein
fc49687879 builtin devices: Reorganize 2021-03-26 10:06:10 +01:00
Dennis Klein
66a4df0667 fairmq-uuid-gen: Move to tools directory 2021-03-26 10:06:10 +01:00
Dennis Klein
978191fa6c Introduce <fairmq/runDevice.h> 2021-03-26 10:06:10 +01:00
Dennis Klein
cef6d0afcd Introduce <fairmq/Device.h> 2021-03-26 10:06:10 +01:00
Dennis Klein
47ec550792 control plugin: Move to subdirectory for consistency 2021-03-26 10:06:10 +01:00
Dennis Klein
b4aeb320e5 CI: Collect DDS logs on error 2021-03-26 10:06:10 +01:00
Dennis Klein
107248be0a Reorganize includes for consistency 2021-03-26 10:06:10 +01:00
Dennis Klein
68ceaba501 CI: Filter and process warnings and errors 2021-03-26 10:06:10 +01:00
Dennis Klein
4b6cf8b181 Fix aggregate initialization issue before C++20
Use value initialization to prevent

error: temporary of type ... has protected destructor

see https://stackoverflow.com/a/56745475
2021-03-26 10:06:10 +01:00
Dennis Klein
21d6cf9830 CI: Run clang-tidy 2021-03-26 10:06:10 +01:00
Alexey Rybalchenko
bffe74c5cf shm: handle shrink failure gracefully 2021-03-23 13:00:35 +01:00
Dennis Klein
72f319e276 CI: Adapt to new alfaci build hosts 2021-03-23 11:06:33 +01:00
Alexey Rybalchenko
62438bd99e shm: Improve error message when segment cannot be opened 2021-03-18 09:02:08 +01:00
Alexey Rybalchenko
c8ad684b18 Add --shm-no-cleanup option
When true, device will skip the segment cleanup even when it is the last
segment user
2021-03-18 09:02:08 +01:00
Alexey Rybalchenko
a5ec83208d Update docs 2021-03-11 12:14:00 +01:00
Alexey Rybalchenko
fc2241ece7 Fix incorrect channel index passed to OnData callback 2021-03-11 12:14:00 +01:00
Alexey Rybalchenko
1f26883b75 Formatting 2021-03-11 12:14:00 +01:00
Alexey Rybalchenko
edbdc57332 shm: make shmId also available as uint64_t 2021-03-11 12:14:00 +01:00
Alexey Rybalchenko
0fd2fcadc2 shm: Make sure no event notifications are missed 2021-03-11 12:14:00 +01:00
Alexey Rybalchenko
9b48b31a75 shm: Make sure all region events are fired 2021-03-11 12:14:00 +01:00
Dennis Klein
cb4335e59f Add test coverage for --channel-config name selector 2021-03-05 02:02:14 +01:00
Giulio Eulisse
ce4584b3d8 Provide a better syntax for --channel-config
The current syntax is ambiguous because it treats assignments
(like address=127.0.0.1) and selectors (name=my-channel) using
the symbol equal `"`.

This allows:

my-channel:address=127.0.0.1

as alternative syntax, which clearly separates the role of my-channel
from the associated properties.
2021-03-05 02:02:14 +01:00
Alexey Rybalchenko
bbc1dd4600 Add optional file output to FairMQSink 2021-03-01 15:33:45 +01:00
Dennis Klein
8327810942 Warn on unknown --channel-config args 2021-03-01 08:37:57 +01:00
Dennis Klein
c37742e3b4 Update Copyright string 2021-03-01 08:37:57 +01:00
Alexey Rybalchenko
93dff3c5a7 Fix regression in shmmonitor 2021-02-19 09:54:29 +01:00
Alexey Rybalchenko
2b3e38d9a4 shmmonitor: non-interactive mode checks and quits 2021-02-10 10:36:08 +01:00
Alexey Rybalchenko
c6b13cd3a1 Fix shmem::Message::SetUsedSize(0) 2021-01-25 13:46:40 +01:00
Alexey Rybalchenko
c5487a11ed Remove custom implementation for enum hashing 2021-01-25 13:46:40 +01:00
Alexey Rybalchenko
4a09154a91 17-ify namespaces 2021-01-25 13:46:40 +01:00
Alexey Rybalchenko
d9a5e82160 Cleanup tools includes 2021-01-25 13:46:40 +01:00
Alexey Rybalchenko
751c53171c Replace tools::make_unique with std::make_unique 2021-01-25 13:46:40 +01:00
Alexey Rybalchenko
6815c9c172 zmq: implement alignment 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
02a3980343 Remove useless parameter from implementation 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
38b34785e0 format & remove unused variable 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
be94ceb7a7 zmq: simplify SetUsedSize implementation 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
afadbb53e4 zmq: correct accounting for msg size > 2GB 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
749d28a3b5 DeviceRunner: check FAIRMQ_SEVERITY env var for severity 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
29f45fa77d Rename TransferResult to TransferCode 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
ea746b17d0 Remove deprecated methods 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
636846fcdb Bump C++ standard requirement to C++17 2021-01-13 12:36:32 +01:00
Alexey Rybalchenko
f46d446d52 shm: do mlock/zeroing under shmem lock 2020-12-04 13:27:45 +01:00
Alexey Rybalchenko
db0937f339 shm: ensure local segments are complete for region subscriptions 2020-11-25 13:41:23 +01:00
Alexey Rybalchenko
bb1ce794b6 Let single message methods also return int64_t 2020-11-17 14:04:20 +01:00
Dennis Klein
9e2373b55d extern/asio: Bump to 1.18.0 2020-11-13 15:55:52 +01:00
Dennis Klein
c51e88e114 CI: Do not run unstable tests on macOS 10.14 hosts 2020-11-13 02:58:09 +01:00
Dennis Klein
f9219dab65 CI: Remove old options 2020-11-13 02:58:09 +01:00
Alexey Rybalchenko
0806720f61 Bump DDS version to 3.5.3 (multiple sessions support) 2020-11-13 02:58:09 +01:00
Alexey Rybalchenko
e39d17d09e Apply suggestions from -Wrange-loop-analysis 2020-11-13 02:58:09 +01:00
Alexey Rybalchenko
a14502242f DDS command UI: return EXIT_FAILURE on errors 2020-11-13 02:58:09 +01:00
Alexey Rybalchenko
d3697ec97b SDK: add WaitForPublisherCount() and related ctor arg 2020-11-13 02:58:09 +01:00
Dennis Klein
73377c5100 CI: Update macOS builds 2020-11-05 15:12:02 +01:00
Alexey Rybalchenko
49d8a1b4dd DeviceRunner: Set log severity only if one was provided 2020-10-19 10:23:08 +02:00
Alexey Rybalchenko
f14f507584 SDK: Remove instance limit from DDSSession 2020-10-09 13:35:55 +02:00
Alexey Rybalchenko
8dd0b25c06 Make BasicTopology actually movable 2020-10-09 13:35:55 +02:00
Christian Tacke
7edf436919 Improve PMIx Package Finding on Debian
Debian's libpmix-dev package installs everything below
/usr/lib/ARCH-TRIPLET/pmix2.
For some reasoning behind this,
see: https://bugs.debian.org/882033

CMake does not search there by default, so help it.

Also add myself to CONTRIBUTORS.
2020-10-08 17:27:12 +02:00
Alexey Rybalchenko
0e5978b160 Properties: add output support for shorts 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
71b1866d7b small includes cleanup 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
6699711e17 FairMQChannel: Refactor, moving short methods to header 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
120760da0a FairMQChannel: avoid copy when iterating over endpoints 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
d03a504ccd shmem: fail earlier if given an unsupported socket type 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
cf004f69b2 FairMQChannel: replace ResetChannel() with Invalidate() 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
cfa18ccfce FairMQChannel: remove artifacts from no longer used optimizations 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
e332e20dbd Remove thread-safety from channel methods 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
3ab10ced7a FairMQChannel: remove deprecated methods 2020-10-06 16:17:37 +02:00
Alexey Rybalchenko
1b30f3ac14 Update return types in ofi::Socket 2020-09-23 09:29:57 +02:00
Alexey Rybalchenko
35c7959c53 Workaround Cpp17MoveInsertable issue on xcode 12 2020-09-22 05:33:29 +02:00
Alexey Rybalchenko
5ea8ffeb34 Update command format in PMIx plugin 2020-09-17 14:22:03 +02:00
Alexey Rybalchenko
04ee1db8e5 Avoid default session id in shmem tests 2020-09-17 14:22:03 +02:00
Dennis Klein
4a15a38dd4 Tests.Device: Set correct log level for FairLogger 1.[7-8] 2020-09-16 15:43:58 +02:00
Dennis Klein
0f5e1b6815 Tests.SDK: Reduce timeout by factor 1000 because new machines can be fast enough to complete within 1ms 2020-09-16 15:43:58 +02:00
Dennis Klein
5e6ad47223 CI: Run macOS checks on newer environment 2020-09-16 15:43:58 +02:00
Alexey Rybalchenko
6932f88c84 Adjust transfer methods behaviour when interrupted
A transer is attempted even if the transport has been interrupted
(with a timeout). When the timeout is reached, transfer methods will
return TransferResult::interrupted (-3).
2020-09-16 15:43:58 +02:00
Alexey Rybalchenko
5e97d85956 Cleanup includes 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
fdbf289364 Update monitor & debug tools for multiple segments 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
266843cda5 Shm: initial multiple segments support 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
b126ede45a Shm: Verbosity switch for Cleanup methods 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
12e6a874db Remove built-in devices from the main lib 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
73109fe6d3 Shm: configurable allocation strategy 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
3b2d2a0ac8 Shm: Refactor to localize segment access 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
72a45f78b3 Shm: Add Monitor::GetDebugInfo() 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
b63f31d0e0 Shm: Provide debug infos only in debug mode 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
70a583d08d Shm: Provide segment/msg debug infos 2020-09-08 16:56:35 +02:00
Alexey Rybalchenko
fe9b87e4e2 Improve error reporting in SDK/fairmq-dds-command-ui 2020-09-07 12:52:43 +02:00
Alexey Rybalchenko
2ac27905e7 Move fairmq-dds-command-ui to SDK 2020-09-03 17:34:05 +02:00
Alexey Rybalchenko
690e8a0370 Retry on EINTR in blocking zmq calls 2020-08-28 18:22:03 +02:00
Alexey Rybalchenko
1f0c94f898 Fix tag mismatch in topology files 2020-08-17 12:39:10 +02:00
Alexey Rybalchenko
62ed4e5f80 Avoid unconditional call to now() when allocating message 2020-08-13 14:16:12 +02:00
neskovic@gmail.com
f1d6b18668 Message counter: use relaxed/acquire memory ordering 2020-08-13 11:49:55 +02:00
Alexey Rybalchenko
c0153a6b55 shmMonitor: Adjust output slightly 2020-08-07 14:27:14 +02:00
Alexey Rybalchenko
86a1dd38a2 ShmMonitor: Use FairLogger for timestamp calculation 2020-08-07 14:27:14 +02:00
Alexey Rybalchenko
be8ab06cc1 Bump FairLogger requirement to 1.6 2020-08-07 14:27:14 +02:00
Alexey Rybalchenko
b0f73017e2 shmmonitor: add output with -v (non-interactive) 2020-08-06 12:24:01 +02:00
Alexey Rybalchenko
b83655d5da MessageBadAlloc: report amount of available memory 2020-08-06 12:24:01 +02:00
Alexey Rybalchenko
9c27051cdc BenchmarkSampler: add alignment parameter 2020-08-06 12:24:01 +02:00
Alexey Rybalchenko
65f9519917 Add error handling for mlock 2020-08-06 12:24:01 +02:00
Alexey Rybalchenko
b5545c1575 Add helpers for AggregatedTopologyState 2020-07-17 12:41:53 +02:00
Alexey Rybalchenko
3eca8e9def Add test for shm transport options 2020-07-15 13:59:53 +02:00
Alexey Rybalchenko
beb7766fca Shm: add options to zero and/or mlock the segment 2020-07-15 13:59:53 +02:00
Giulio Eulisse
bf909f94dc ofi: adapt to the new API for FairMQSocket::Events 2020-07-15 13:58:47 +02:00
Dennis Klein
1140c4c6ab SDK: Provide comparison operator for device and topo states 2020-07-15 13:01:23 +02:00
Alexey Rybalchenko
a6da208e79 Add Undefined and Mixed state for use in SDK 2020-07-15 13:01:23 +02:00
Giulio Eulisse
ba3a82b1df Update FairMQSocket.h 2020-07-15 12:09:54 +02:00
Giulio Eulisse
e8cc104344 Add API to extract ZMQ_EVENTS from socket backend 2020-07-15 12:09:54 +02:00
Alexey Rybalchenko
d5d5c27958 QC examples: fix incorrect topology path 2020-07-09 23:34:28 +02:00
Alexey Rybalchenko
5a7dcd9fc1 SDK: warn if given path translates to no selected tasks 2020-07-09 23:34:28 +02:00
Alexey Rybalchenko
78b1c188bf Shm: report correct size when opening segment 2020-06-30 20:58:53 +02:00
Alexey Rybalchenko
66bc7ba762 Remove useless variable 2020-06-30 20:58:53 +02:00
Alexey Rybalchenko
88bc1f7a06 Shm: throw if requested message size exceeds total segment size 2020-06-30 20:58:53 +02:00
Alexey Rybalchenko
f70201610b Do not attemp to find random port for non-TCP protocols 2020-06-30 20:58:53 +02:00
Alexey Rybalchenko
fc7f6f1116 Enable Boost_NO_BOOST_CMAKE for tests 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
8125489776 Handle out_of_range when locating RegionInfo 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
6dd0a44308 Make shmid an 8-digit hex number 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
afe2dcaa02 BenchmarkSampler: add memset option 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
aeab9e5407 Socket.h: refactor to reduce duplicate code 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
539e5602a6 Expose fair::mq::shmem::Monitor::Cleanup() API 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
beb510ded8 Adjust example 1 docs 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
d1c51e0f1f Use region linger setting in region example 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
f885b4618e Optimize unmanaged region ReceiveAcks 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
3364da9541 Add linger setting for unmanaged region 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
7aec6f91de Fix typo 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
9e2a002942 Add -Og flag to Debug build 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
52c6264faf Fix message counter in region example 2020-06-29 14:44:49 +02:00
Alexey Rybalchenko
79489bb501 Add missing includes 2020-06-10 13:55:15 +02:00
Alexey Rybalchenko
c60dd9965c Add copyright entry for PicoSHA2 2020-06-05 18:16:13 +02:00
Alexey Rybalchenko
79ca436b74 Zmq: let GetData of an empty message return nullptr 2020-06-05 18:16:13 +02:00
Alexey Rybalchenko
36d4f3c937 Use SHA2 instead of boost::hash to generate shmem id 2020-06-05 18:16:13 +02:00
Alexey Rybalchenko
bdf895ae9e Add PicoSHA2 dependency 2020-06-05 18:16:13 +02:00
Alexey Rybalchenko
42986e664c Add PicoSHA2 submodule 2020-06-05 18:16:13 +02:00
Giulio Eulisse
dd47b34e06 Add ability to retrieve ZMQ_FD 2020-06-03 19:44:00 +02:00
Alexey Rybalchenko
a59c902c74 MemoryResource: propagate alignment 2020-06-03 19:41:40 +02:00
Alexey Rybalchenko
dabc48c21a Shm: fix incorrect ptr range check 2020-05-29 23:34:27 +02:00
Alexey Rybalchenko
236d5a8608 Let default shm segm size be multiple of page size
To allow potential optimizations (e.g. huge pages)
2020-05-28 17:23:18 +02:00
Alexey Rybalchenko
5a782e8726 Add a test for unregisted options 2020-05-28 17:23:18 +02:00
Alexey Rybalchenko
5008fa4732 Fix regression in handling unregistered options 2020-05-28 17:23:18 +02:00
Alexey Rybalchenko
b5bb476b0d Adjust program options style to disallow guessing 2020-05-25 14:03:12 +02:00
Giulio Eulisse
ea7ae04025 Adapt to requests by @rbx 2020-05-25 08:36:57 +02:00
Giulio Eulisse
02692e7002 Initiate termination process on SIGTERM as well 2020-05-25 08:36:57 +02:00
Alexey Rybalchenko
53a4d17f8b Alignment part I - Interface and shmem send 2020-05-20 19:34:27 +02:00
Giulio Eulisse
20544e1f18 Do not handle double SIGTERM as abort
A double SIGTERM, or even worse a SIGINT + SIGTERM combination should
not result in an abort, given such a signal really means "die whenever
you want" and can only be generated programmatically. If one wants the
child to die programmatically, they should use SIGKILL.

On the other hand that bashing ctrl-c (i.e. SIGINT) multiple times
on the keyboard really means abort.
2020-05-20 12:14:18 +02:00
Dennis Klein
b32e04db60 Do not search external GTest by default
Can be overridden by -DUSE_EXTERNAL_GTEST=ON.
2020-05-19 10:53:02 +02:00
Alexey Rybalchenko
0d03c76a75 Shm: throw on bad_alloc, option to disable 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
2916a491b9 Format 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
b56e32eb11 Replace exit()s with exceptions 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
4b516de81a Minor formatting 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
361fb0cba5 Zmq: refactor to use namespaces 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
df574c6466 Zmq: header only 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
dbdabd23a4 Zmq: remove global (static) state, refactor 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
ccbf0be572 Shmem: refactor, clean includes, make header only 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
7a67719a3c Remove useless members 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
f4a54ff550 Minor refactoring 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
d22023bcb5 Implement bulk callbacks for unmanaged regions 2020-05-18 14:32:19 +02:00
Alexey Rybalchenko
a15d59c725 Remove nanomsg transport 2020-05-11 17:38:16 +02:00
264 changed files with 7682 additions and 9234 deletions

View File

@@ -1,3 +1,3 @@
---
Checks: '*,-google-*,-fuchsia-*,-cert-*,-llvm-header-guard,-readability-named-parameter,-misc-non-private-member-variables-in-classes,-*-magic-numbers,-llvm-include-order,-hicpp-no-array-decay,-performance-unnecessary-value-param,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-modernize-use-trailing-return-type,-readability-redundant-member-init'
Checks: 'cppcoreguidelines-*,misc-unused-alias-decls,misc-unused-parameters,modernize-deprecated-headers,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-using,performance-faster-string-find,performance-for-range-copy,performance-unnecessary-copy-initialization,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-container-size-empty,readability-delete-null-pointer,readability-redundant-member-init,readability-redundant-string-init,readability-static-accessed-through-instance,readability-string-compare'
HeaderFilterRegex: '/(fairmq/)'

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "extern/asio"]
path = extern/asio
url = https://github.com/chriskohlhoff/asio
[submodule "extern/PicoSHA2"]
path = extern/PicoSHA2
url = https://github.com/okdshin/PicoSHA2

View File

@@ -18,11 +18,7 @@ get_git_version()
project(FairMQ VERSION ${PROJECT_VERSION} LANGUAGES CXX)
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
if(BUILD_OFI_TRANSPORT OR BUILD_SDK OR BUILD_PMIX_PLUGIN)
set(PROJECT_MIN_CXX_STANDARD 14)
else()
set(PROJECT_MIN_CXX_STANDARD 11)
endif()
set(PROJECT_MIN_CXX_STANDARD 17)
set_fairmq_defaults()
@@ -31,28 +27,30 @@ include(CTest)
# Build options ################################################################
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
DEFAULT ON)
fairmq_build_option(BUILD_TESTING "Build tests."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_NANOMSG_TRANSPORT "Build nanomsg transport."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
DEFAULT OFF)
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
DEFAULT OFF)
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
DEFAULT OFF)
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
DEFAULT ON)
fairmq_build_option(BUILD_TESTING "Build tests."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
DEFAULT OFF)
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
DEFAULT OFF)
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
DEFAULT OFF)
fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended."
DEFAULT OFF)
fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease performance)."
DEFAULT OFF)
################################################################################
@@ -65,11 +63,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if(BUILD_NANOMSG_TRANSPORT)
find_package2(PRIVATE nanomsg REQUIRED)
set(PROJECT_nanomsg_VERSION 1.1.3) # Once upstream releases 1.1.5, we should bump again and use version check
endif()
if(BUILD_OFI_TRANSPORT)
find_package2(PRIVATE asiofi REQUIRED
VERSION 0.3.1
@@ -79,19 +72,13 @@ if(BUILD_OFI_TRANSPORT)
)
endif()
if(BUILD_NANOMSG_TRANSPORT)
find_package2(PRIVATE msgpack REQUIRED
VERSION 3.1.0
)
endif()
if(BUILD_SDK_COMMANDS)
find_package2(PRIVATE Flatbuffers REQUIRED)
endif()
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
find_package2(PRIVATE DDS REQUIRED
VERSION 3.0
VERSION 3.5.3
)
set(DDS_Boost_COMPONENTS system log log_setup regex filesystem thread)
set(DDS_Boost_VERSION 1.67)
@@ -105,7 +92,7 @@ endif()
if(BUILD_FAIRMQ OR BUILD_SDK)
find_package2(PUBLIC FairLogger REQUIRED
VERSION 1.2.0
VERSION 1.6.0
)
foreach(dep IN LISTS FairLogger_PACKAGE_DEPENDENCIES)
@@ -145,7 +132,7 @@ endif()
if(BUILD_SDK)
find_package2(BUNDLED asio
VERSION 1.13.0
VERSION 1.18.0
)
if(NOT asio_FOUND)
build_bundled(asio extern/asio)
@@ -157,10 +144,14 @@ if(BUILD_FAIRMQ)
find_package2(PRIVATE ZeroMQ REQUIRED
VERSION 4.1.4
)
build_bundled(PicoSHA2 extern/PicoSHA2)
find_package2(PRIVATE PicoSHA2 REQUIRED)
endif()
if(BUILD_TESTING)
find_package2(PRIVATE GTest VERSION 1.7.0)
if(USE_EXTERNAL_GTEST)
find_package2(PRIVATE GTest VERSION 1.7.0)
endif()
if(NOT GTest_FOUND)
build_bundled(GTest extern/googletest)
find_package2(PRIVATE GTest REQUIRED)
@@ -215,9 +206,6 @@ endif()
if(BUILD_PMIX_PLUGIN)
list(APPEND PROJECT_PACKAGE_COMPONENTS pmix_plugin)
endif()
if(BUILD_NANOMSG_TRANSPORT)
list(APPEND PROJECT_PACKAGE_COMPONENTS nanomsg_transport)
endif()
if(BUILD_OFI_TRANSPORT)
list(APPEND PROJECT_PACKAGE_COMPONENTS ofi_transport)
endif()
@@ -270,7 +258,7 @@ install_cmake_package()
# Summary ######################################################################
message(STATUS " ")
message(STATUS " ${Cyan}CXX STANDARD${CR} ${BGreen}C++${CMAKE_CXX_STANDARD}${CR} (>= C++${PROJECT_MIN_CXX_STANDARD}, change with ${BMagenta}-DCMAKE_CXX_STANDARD=17${CR})")
message(STATUS " ${Cyan}CXX STANDARD${CR} ${BGreen}C++${CMAKE_CXX_STANDARD}${CR} (>= C++${PROJECT_MIN_CXX_STANDARD}, change with ${BMagenta}-DCMAKE_CXX_STANDARD=20${CR})")
if(CMAKE_CXX_FLAGS)
message(STATUS " ")
message(STATUS " ${Cyan}GLOBAL CXX FLAGS${CR} ${BGreen}${CMAKE_CXX_FLAGS}${CR}")
@@ -320,16 +308,10 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
endif()
elseif(${dep} STREQUAL GTest)
get_filename_component(prefix ${GTEST_INCLUDE_DIRS}/.. ABSOLUTE)
elseif(${dep} STREQUAL msgpack)
get_target_property(msgpack_include msgpackc-cxx INTERFACE_INCLUDE_DIRECTORIES)
get_filename_component(prefix ${msgpack_include}/.. ABSOLUTE)
elseif(${dep} STREQUAL asiofi)
set(prefix ${asiofi_ROOT})
elseif(${dep} STREQUAL OFI)
get_filename_component(prefix ${${dep}_INCLUDE_DIRS}/.. ABSOLUTE)
elseif(${dep} STREQUAL nanomsg)
get_target_property(nn_include nanomsg INTERFACE_INCLUDE_DIRECTORIES)
get_filename_component(prefix ${nn_include}/.. ABSOLUTE)
elseif(${dep} STREQUAL DDS)
set(prefix "${DDS_INSTALL_PREFIX}")
elseif(${dep} STREQUAL Boost)
@@ -378,16 +360,10 @@ else()
set(tests_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
endif()
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
if(BUILD_NANOMSG_TRANSPORT)
set(nn_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=OFF${CR})")
else()
set(nn_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=ON${CR})")
endif()
message(STATUS " ${BWhite}nanomsg_transport${CR} ${nn_summary}")
if(BUILD_OFI_TRANSPORT)
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (requires C++14) (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
else()
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (requires C++14) (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
endif()
message(STATUS " ${BWhite}ofi_transport${CR} ${ofi_summary}")
if(BUILD_DDS_PLUGIN)
@@ -397,9 +373,9 @@ else()
endif()
message(STATUS " ${BWhite}dds_plugin${CR} ${dds_summary}")
if(BUILD_PMIX_PLUGIN)
set(pmix_summary "${BGreen}YES${CR} EXPERIMENTAL (requires C++14) (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
set(pmix_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
else()
set(pmix_summary "${BRed} NO${CR} EXPERIMENTAL (requires C++14) (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
set(pmix_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
endif()
message(STATUS " ${BWhite}pmix_plugin${CR} ${pmix_summary}")
if(BUILD_EXAMPLES)
@@ -415,9 +391,9 @@ else()
endif()
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
if(BUILD_SDK)
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (required C++14) (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
else()
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (required C++14) (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
endif()
message(STATUS " ${BWhite}sdk${CR} ${sdk_summary}")
if(BUILD_SDK_COMMANDS)
@@ -451,4 +427,10 @@ message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX
message(STATUS " ")
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
message(STATUS " ")
if(FAIRMQ_DEBUG_MODE)
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BGreen}${FAIRMQ_DEBUG_MODE}${CR} (disable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=OFF${CR})")
else()
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
endif()
message(STATUS " ")
################################################################################

View File

@@ -8,5 +8,6 @@ Lebedev, Andrey
Mrnjavac, Teo <teo.m@cern.ch>
Neskovic, Gvozden
Richter, Matthias
Tacke, Christian
Uhlig, Florian
Wenzel, Sandro

View File

@@ -23,6 +23,10 @@ Files: extern/asio
Copyright: 2003-2019, Christopher M. Kohlhoff (chris at kohlhoff dot com)
License: BSL-1.0
Files: extern/PicoSHA2
Copyright: 2017 okdshin
License: MIT
License: LGPL-3.0-only
[see LICENSE file]
@@ -102,3 +106,22 @@ License: BSL-1.0
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,86 +1,69 @@
################################################################################
# Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
# copied verbatim in the file "LICENSE" #
################################################################################
Set(CTEST_SOURCE_DIRECTORY $ENV{SOURCEDIR})
Set(CTEST_BINARY_DIRECTORY $ENV{BUILDDIR})
Set(CTEST_SITE $ENV{SITE})
Set(CTEST_BUILD_NAME $ENV{LABEL})
Set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
Set(CTEST_PROJECT_NAME "FairMQ")
Find_Program(CTEST_GIT_COMMAND NAMES git)
Set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
cmake_host_system_information(RESULT fqdn QUERY FQDN)
Set(BUILD_COMMAND "make")
Set(CTEST_BUILD_COMMAND "${BUILD_COMMAND} -j$ENV{number_of_processors}")
set(CTEST_SOURCE_DIRECTORY .)
set(CTEST_BINARY_DIRECTORY build)
set(CTEST_CMAKE_GENERATOR "Ninja")
set(CTEST_USE_LAUNCHERS ON)
set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo")
String(TOUPPER $ENV{ctest_model} _Model)
Set(configure_options "-DCMAKE_BUILD_TYPE=$ENV{ctest_model}")
if(NOT NCPUS)
if(ENV{SLURM_CPUS_PER_TASK})
set(NCPUS $ENV{SLURM_CPUS_PER_TASK})
else()
include(ProcessorCount)
ProcessorCount(NCPUS)
if(NCPUS EQUAL 0)
set(NCPUS 1)
endif()
endif()
endif()
Set(CTEST_USE_LAUNCHERS 1)
Set(configure_options "${configure_options};-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}")
if ("$ENV{CTEST_SITE}" STREQUAL "")
set(CTEST_SITE "${fqdn}")
else()
set(CTEST_SITE $ENV{CTEST_SITE})
endif()
Set(configure_options "${configure_options};-DDISABLE_COLOR=ON")
Set(configure_options "${configure_options};-DCMAKE_PREFIX_PATH=$ENV{SIMPATH}")
Set(configure_options "${configure_options};-DBUILD_NANOMSG_TRANSPORT=ON")
# Set(configure_options "${configure_options};-DBUILD_OFI_TRANSPORT=ON")
Set(configure_options "${configure_options};-DBUILD_DDS_PLUGIN=ON")
Set(configure_options "${configure_options};-DBUILD_SDK=ON")
Set(configure_options "${configure_options};-DBUILD_SDK_COMMANDS=ON")
Set(configure_options "${configure_options};-DFAST_BUILD=ON")
Set(configure_options "${configure_options};-DCOTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES=-j$ENV{number_of_processors}")
if ("$ENV{LABEL}" STREQUAL "")
set(CTEST_BUILD_NAME "build")
else()
set(CTEST_BUILD_NAME $ENV{LABEL})
endif()
Set(EXTRA_FLAGS $ENV{EXTRA_FLAGS})
If(EXTRA_FLAGS)
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
EndIf()
ctest_start(Continuous)
If($ENV{ctest_model} MATCHES Profile)
Find_Program(GCOV_COMMAND gcov)
If(GCOV_COMMAND)
Message("Found GCOV: ${GCOV_COMMAND}")
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
EndIf(GCOV_COMMAND)
EndIf()
list(APPEND options
"-DDISABLE_COLOR=ON"
"-DBUILD_SDK_COMMANDS=ON"
"-DBUILD_SDK=ON"
"-DBUILD_DDS_PLUGIN=ON")
if(RUN_STATIC_ANALYSIS)
list(APPEND options "-DRUN_STATIC_ANALYSIS=ON")
endif()
list(JOIN options ";" optionsstr)
ctest_configure(OPTIONS "${optionsstr}")
If($ENV{ctest_model} MATCHES Nightly OR $ENV{ctest_model} MATCHES Profile)
Ctest_Empty_Binary_Directory(${CTEST_BINARY_DIRECTORY})
EndIf()
ctest_submit()
Ctest_Start($ENV{ctest_model})
ctest_build(FLAGS "-j${NCPUS}")
Ctest_Configure(BUILD "${CTEST_BINARY_DIRECTORY}"
OPTIONS "${configure_options}"
)
ctest_submit()
Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
PARALLEL_LEVEL 1
SCHEDULE_RANDOM ON
RETURN_VALUE _ctest_test_ret_val)
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
# PARALLEL_LEVEL $ENV{number_of_processors}
PARALLEL_LEVEL $ENV{number_of_processors}
RETURN_VALUE _ctest_test_ret_val
)
ctest_submit()
If(GCOV_COMMAND)
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS coverage)
EndIf()
If("$ENV{do_codecov_upload}")
Execute_Process(COMMAND curl https://codecov.io/bash -o codecov_uploader.sh
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
TIMEOUT 60)
Execute_Process(COMMAND bash ./codecov_uploader.sh -X gcov
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
TIMEOUT 60)
EndIf()
Ctest_Submit()
if (_ctest_test_ret_val)
if(_ctest_test_ret_val)
Message(FATAL_ERROR "Some tests failed.")
endif()

111
Jenkinsfile vendored
View File

@@ -1,60 +1,69 @@
#!groovy
def specToLabel(Map spec) {
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
}
def jobMatrix(String prefix, List specs, Closure callback) {
def jobMatrix(String type, List specs) {
def nodes = [:]
for (spec in specs) {
def label = specToLabel(spec)
def fairsoft = spec.fairsoft
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
def label = "${type}/${job}"
def selector = "${spec.os}-${spec.ver}-${spec.arch}"
def os = spec.os
def compiler = spec.compiler
nodes["${prefix}/${label}"] = {
node(label) {
githubNotify(context: "${prefix}/${label}", description: 'Building ...', status: 'PENDING')
def ver = spec.ver
def check = spec.check
nodes[label] = {
node(selector) {
githubNotify(context: "${label}", description: 'Building ...', status: 'PENDING')
try {
deleteDir()
checkout scm
sh """\
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc9/) {
sh '''\
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /MacOS/) {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
def jobscript = 'job.sh'
def ctestcmd = "ctest -S FairMQTest.cmake -V --output-on-failure"
sh "echo \"set -e\" >> ${jobscript}"
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
if (selector =~ /^macos/) {
sh """\
echo \"export DDS_ROOT=\\\"\\\$(brew --prefix dds)\\\"\" >> ${jobscript}
echo \"${ctestcmd}\" >> ${jobscript}
"""
sh "cat ${jobscript}"
sh "bash ${jobscript}"
} else {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
def static_analysis = "OFF"
if (selector =~ /^fedora/) {
static_analysis = "ON"
}
def containercmd = "singularity exec -B/shared ${env.SINGULARITY_CONTAINER_ROOT}/fairmq/${os}.${ver}.sif bash -l -c \\\"${ctestcmd} -DRUN_STATIC_ANALYSIS=${static_analysis}\\\""
sh """\
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
echo \"echo \\\"*** Compute node .........: \\\$(hostname -f)\\\"\" >> ${jobscript}
echo \"unset http_proxy\" >> ${jobscript}
echo \"unset HTTP_PROXY\" >> ${jobscript}
echo \"${containercmd}\" >> ${jobscript}
"""
sh "cat ${jobscript}"
sh "test/ci/slurm-submit.sh \"FairMQ \${JOB_BASE_NAME} ${label}\" ${jobscript}"
withChecks('Static Analysis') {
if (static_analysis == "ON") {
recordIssues(enabledForFailure: true,
tools: [gcc(pattern: 'build/Testing/Temporary/*.log')],
filters: [excludeFile('extern/*'), excludeFile('usr/*')],
skipBlames: true)
}
}
}
sh '''\
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
echo "export SOURCEDIR=$PWD" >> Dart.cfg
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
echo "export GIT_BRANCH=$JOB_BASE_NAME" >> Dart.cfg
echo "echo \\\$PATH" >> Dart.cfg
'''
sh 'cat Dart.cfg'
callback.call(spec, label)
deleteDir()
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
githubNotify(context: "${label}", description: 'Success', status: 'SUCCESS')
} catch (e) {
def tarball = "${prefix}_${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test .DDS/"
archiveArtifacts tarball
deleteDir()
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
githubNotify(context: "${label}", description: 'Error', status: 'ERROR')
throw e
}
}
@@ -66,26 +75,16 @@ def jobMatrix(String prefix, List specs, Closure callback) {
pipeline{
agent none
stages {
stage("Run CI Matrix") {
stage("CI") {
steps{
script {
def build_jobs = jobMatrix('build', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
sh './Dart.sh alfa_ci Dart.cfg'
}
def builds = jobMatrix('build', [
[os: 'alice-centos', ver: '7', arch: 'x86_64', compiler: 'gcc-7'],
[os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10'],
[os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12'],
])
def profile_jobs = jobMatrix('codecov', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
withCredentials([string(credentialsId: 'fairmq_codecov_token', variable: 'CODECOV_TOKEN')]) {
sh './Dart.sh codecov Dart.cfg'
}
}
parallel(build_jobs + profile_jobs)
parallel(builds)
}
}
}

View File

@@ -1,81 +0,0 @@
#!groovy
def specToLabel(Map spec) {
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
}
def buildMatrix(List specs, Closure callback) {
def nodes = [:]
for (spec in specs) {
def label = specToLabel(spec)
def fairsoft = spec.fairsoft
def os = spec.os
def compiler = spec.compiler
nodes[label] = {
node(label) {
try {
deleteDir()
checkout scm
sh """\
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc9/) {
sh '''\
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /MacOS/) {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
} else {
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
}
sh '''\
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
echo "export SOURCEDIR=$PWD" >> Dart.cfg
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
echo "export GIT_BRANCH=dev" >> Dart.cfg
echo "echo \\\$PATH" >> Dart.cfg
'''
sh 'cat Dart.cfg'
callback.call(spec, label)
deleteDir()
} catch (e) {
def tarball = "${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
archiveArtifacts tarball
deleteDir()
throw e
}
}
}
}
return nodes
}
pipeline{
agent none
triggers { cron('H 2 * * *') }
stages {
stage("Run Nightly Build/Test Matrix") {
steps{
script {
parallel(buildMatrix([
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
]) { spec, label ->
sh './Dart.sh Nightly Dart.cfg'
sh './Dart.sh Profile Dart.cfg'
})
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
<!-- {#mainpage} -->
# FairMQ [![license](https://alfa-ci.gsi.de/shields/badge/license-LGPL--3.0-orange.svg)](COPYRIGHT) [![build status](https://alfa-ci.gsi.de/buildStatus/icon?job=FairRootGroup/FairMQ/master)](https://alfa-ci.gsi.de/blue/organizations/jenkins/FairRootGroup%2FFairMQ/branches) [![test coverage master branch](https://codecov.io/gh/FairRootGroup/FairMQ/branch/master/graph/badge.svg)](https://codecov.io/gh/FairRootGroup/FairMQ/branch/master) [![Coverity Badge](https://alfa-ci.gsi.de/shields/coverity/scan/fairrootgroup-fairmq.svg)](https://scan.coverity.com/projects/fairrootgroup-fairmq) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6b648d95d68d4c4eae833b84f84d299c)](https://www.codacy.com/app/dennisklein/FairMQ?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=FairRootGroup/FairMQ&amp;utm_campaign=Badge_Grade)
# FairMQ [![license](https://alfa-ci.gsi.de/shields/badge/license-LGPL--3.0-orange.svg)](COPYRIGHT) [![build status](https://alfa-ci.gsi.de/buildStatus/icon?job=FairRootGroup/FairMQ/dev)](https://alfa-ci.gsi.de/blue/organizations/jenkins/FairRootGroup%2FFairMQ/branches) [![Coverity Badge](https://alfa-ci.gsi.de/shields/coverity/scan/fairrootgroup-fairmq.svg)](https://scan.coverity.com/projects/fairrootgroup-fairmq)
C++ Message Queuing Library and Framework
@@ -21,7 +21,7 @@ FairMQ is designed to help implementing large-scale data processing workflows ne
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
FairMQ provides multiple implementations for its API (so-called "transports",
e.g. `zeromq`, `shmem`, `nanomsg`, and `ofi` (in development)) to cover a variety of use cases
e.g. `zeromq`, `shmem` and `ofi` (in development)) to cover a variety of use cases
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
are communicating through message passing. FairMQ does not only allow the user to use different transport but also to mix them; i.e: A Device can communicate using different transport on different channels at the same time. Device execution is modelled as a simple state machine that
@@ -47,7 +47,7 @@ cmake --build fairmq_build --target install
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `MSGPACK`, `NANOMSG`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
## Usage
@@ -86,7 +86,7 @@ If your project shares a dependency with FairMQ or if you want to omit a certain
Optionally, you can require certain FairMQ package components and a minimum version:
```cmake
find_package(FairMQ 1.1.0 COMPONENTS nanomsg_transport dds_plugin)
find_package(FairMQ 1.1.0 COMPONENTS dds_plugin)
```
When building FairMQ, CMake will print a summary table of all available package components.
@@ -101,8 +101,6 @@ When building FairMQ, CMake will print a summary table of all available package
* [Doxygen](http://www.doxygen.org/)
* [FairLogger](https://github.com/FairRootGroup/FairLogger)
* [GTest](https://github.com/google/googletest) (optionally bundled)
* [Msgpack](https://msgpack.org/index.html)
* [nanomsg](http://nanomsg.org/)
* [PMIx](https://pmix.org/)
* [ZeroMQ](http://zeromq.org/)
@@ -117,7 +115,6 @@ On command line:
* `-DDISABLE_COLOR=ON` disables coloured console output.
* `-DBUILD_TESTING=OFF` disables building of tests.
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
* `-DBUILD_NANOMSG_TRANSPORT=ON` enables building of nanomsg transport.
* `-DBUILD_OFI_TRANSPORT=ON` enables building of the experimental OFI transport.
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
@@ -182,4 +179,3 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
1. [DDS](docs/Plugins.md#731-dds)
2. [PMIx](docs/Plugins.md#732-pmix)
8. [Controller SDK](docs/SDK.md)

View File

@@ -145,7 +145,7 @@ macro(set_fairmq_defaults)
# Configure build types
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo" "Nightly" "Profile" "Experimental" "AddressSan" "ThreadSan")
set(_warnings "-Wshadow -Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-g ${_warnings}")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${_warnings}")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${_warnings} -DNDEBUG")
set(CMAKE_CXX_FLAGS_NIGHTLY "-O2 -g ${_warnings}")
@@ -203,6 +203,13 @@ macro(set_fairmq_defaults)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
endif()
endif()
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
set(FAIRMQ_HAS_STD_FILESYSTEM 0)
else()
set(FAIRMQ_HAS_STD_FILESYSTEM 1)
endif()
endmacro()
function(join VALUES GLUE OUTPUT)
@@ -498,6 +505,8 @@ function(build_bundled package bundle)
set(${package}_BUILD_INCLUDE_DIR ${${package}_SOURCE_DIR}/asio/include CACHE PATH "Bundled ${package} build-interface include dir")
set(${package}_INSTALL_INCLUDE_DIR ${PROJECT_INSTALL_INCDIR}/bundled CACHE PATH "Bundled ${package} install-interface include dir")
set(${package}_ROOT ${${package}_SOURCE_DIR}/asio)
elseif(${package} STREQUAL PicoSHA2)
set(${package}_ROOT ${${package}_SOURCE_DIR})
endif()
string(TOUPPER ${package} package_upper)

View File

@@ -6,28 +6,35 @@
# copied verbatim in the file "LICENSE" #
################################################################################
# The "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix" part in all
# the PATH_SUFFIXES is here to be able to find Debian's
# libpmix-dev package. It installs everything below
# /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix
find_path(PMIx_INCLUDE_DIR
NAMES pmix.h
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES include
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
)
find_path(PMIx_LIBRARY_DIR
NAMES libpmix.dylib libpmix.so
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES lib lib64
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
)
find_library(PMIx_LIBRARY_SHARED
NAMES libpmix.dylib libpmix.so
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES lib lib64
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
)
find_file(PMIx_VERSION_FILE
NAMES pmix_version.h
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
PATH_SUFFIXES include
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
)
file(READ "${PMIx_VERSION_FILE}" __version_raw)

21
cmake/FindPicoSHA2.cmake Normal file
View File

@@ -0,0 +1,21 @@
################################################################################
# Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
# copied verbatim in the file "LICENSE" #
################################################################################
find_path(PicoSHA2_INCLUDE_DIR NAMES picosha2.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PicoSHA2
REQUIRED_VARS PicoSHA2_INCLUDE_DIR
)
if(PicoSHA2_FOUND)
add_library(PicoSHA2 INTERFACE IMPORTED)
set_target_properties(PicoSHA2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PicoSHA2_INCLUDE_DIR}"
)
endif()

View File

@@ -18,7 +18,7 @@ Topology configuration is currently happening via setup scripts. This is very ru
## 1.2 Communication Patterns
FairMQ devices communicate via the communication patterns offered by ZeroMQ (or nanomsg): PUSH-PULL, PUB-SUB, REQ-REP, PAIR, [more info here](http://api.zeromq.org/4-0:zmq-socket). Each transport may provide further patterns.
FairMQ devices communicate via the communication patterns offered by ZeroMQ: PUSH-PULL, PUB-SUB, REQ-REP, PAIR, [more info here](http://api.zeromq.org/4-0:zmq-socket). Each transport may provide further patterns.
## 1.3 State Machine

View File

@@ -2,7 +2,7 @@
# 2. Transport Interface
The communication layer is available through the transport interface. Three interface implementations are currently available. Main implementation uses the [ZeroMQ](http://zeromq.org) library. Alternative implementation relies on the [nanomsg](http://nanomsg.org) library. Third transport implementation is using shared memory via boost::interprocess & ZeroMQ combination.
The communication layer is available through the transport interface. Three interface implementations are currently available. Main implementation uses the [ZeroMQ](http://zeromq.org) library. Second transport implementation is using shared memory via boost::interprocess & ZeroMQ combination.
Here is an overview to give an idea how the interface is implemented:
@@ -10,20 +10,20 @@ Here is an overview to give an idea how the interface is implemented:
Currently, the transports have been tested to work with these communication patterns:
| | zeromq | nanomsg | shmem |
| ------------- |--------| ------- | ----- |
| PAIR | yes | yes | yes |
| PUSH/PULL | yes | yes | yes |
| PUB/SUB | yes | yes | no |
| REQ/REP | yes | yes | yes |
| | zeromq | shmem |
| ------------- |--------| ----- |
| PAIR | yes | yes |
| PUSH/PULL | yes | yes |
| PUB/SUB | yes | no |
| REQ/REP | yes | yes |
The next table shows the supported address types for each transport implementation:
| | zeromq | nanomsg | shmem | comment |
| ----------- | ------ | ------- | ----- | --------------------------------------------- |
| `inproc://` | yes | yes | yes | in process: useful for unit testing |
| `ipc://` | yes | yes | yes | inter process comm: useful on single machine |
| `tcp://` | yes | yes | yes | useful for any communication, local or remote |
| | zeromq | shmem | comment |
| ----------- | ------ | ----- | --------------------------------------------- |
| `inproc://` | yes | yes | in process: useful for unit testing |
| `ipc://` | yes | yes | inter process comm: useful on single machine |
| `tcp://` | yes | yes | useful for any communication, local or remote |
## 2.1 Message

View File

@@ -7,10 +7,10 @@
################################################################################
add_library(Example11Lib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(Example11Lib PUBLIC FairMQ)
@@ -34,23 +34,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BIN
add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.1-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh nanomsg)
set_tests_properties(Example.1-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
endif()
add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
# install
install(
TARGETS
fairmq-ex-1-1-sampler
fairmq-ex-1-1-sink
TARGETS
fairmq-ex-1-1-sampler
fairmq-ex-1-1-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -59,7 +54,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-1.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-1.sh
)

View File

@@ -17,8 +17,7 @@ Sampler::Sampler()
: fText()
, fMaxIterations(0)
, fNumIterations(0)
{
}
{}
void Sampler::InitTask()
{
@@ -32,25 +31,22 @@ bool Sampler::ConditionalRun()
// create a copy of the data with new(), that will be deleted after the transfer is complete
string* text = new string(fText);
// create message object with a pointer to the data buffer,
// its size,
// create message object with a pointer to the data buffer, its size,
// custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer
FairMQMessagePtr msg(NewMessage(const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
text));
FairMQMessagePtr msg(NewMessage(
const_cast<char*>(text->c_str()),
text->length(),
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
text));
LOG(info) << "Sending \"" << fText << "\"";
// in case of error or transfer interruption, return false to go to IDLE state
// in case of error or transfer interruption, return false to go to the Ready state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
if (Send(msg, "data") < 0)
{
if (Send(msg, "data") < 0) {
return false;
}
else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
} else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
@@ -58,8 +54,6 @@ bool Sampler::ConditionalRun()
return true;
}
Sampler::~Sampler()
{
}
Sampler::~Sampler() {}
} // namespace example_1_1

View File

@@ -33,23 +33,22 @@ void Sink::InitTask()
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
}
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
// handler is called whenever a message arrives on "data", with a reference to the message and a
// sub-channel index (here 0)
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
{
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
// return true if want to be called again (otherwise return false go to IDLE state)
// return true if you want the handler to be called again (otherwise return false go to the
// Ready state)
return true;
}
Sink::~Sink()
{
}
Sink::~Sink() {}
} // namespace example_1_1

View File

@@ -7,12 +7,12 @@
################################################################################
add_library(Example1N1Lib STATIC
"Sampler.cxx"
"Sampler.h"
"Processor.cxx"
"Processor.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Processor.cxx"
"Processor.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(Example1N1Lib PUBLIC FairMQ)
@@ -42,24 +42,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_B
add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.1-n-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh nanomsg)
set_tests_properties(Example.1-n-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
endif()
add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
# install
install(
TARGETS
fairmq-ex-1-n-1-sampler
fairmq-ex-1-n-1-processor
fairmq-ex-1-n-1-sink
TARGETS
fairmq-ex-1-n-1-sampler
fairmq-ex-1-n-1-processor
fairmq-ex-1-n-1-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -69,12 +64,12 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-n-1.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-1-n-1.sh
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
DESTINATION ${PROJECT_INSTALL_DATADIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
DESTINATION ${PROJECT_INSTALL_DATADIR}
)

View File

@@ -13,9 +13,7 @@ add_subdirectory(copypush)
add_subdirectory(dds)
add_subdirectory(multipart)
add_subdirectory(multiple-channels)
if(BUILD_NANOMSG_TRANSPORT)
add_subdirectory(multiple-transports)
endif()
add_subdirectory(multiple-transports)
add_subdirectory(n-m)
add_subdirectory(qc)
add_subdirectory(readout)

View File

@@ -32,7 +32,7 @@ This example demonstrates how to work with multiple channels and multiplex betwe
## Multiple Transports
This examples shows how to combine different channel transports (zeromq/nanomsg/shmem) inside of one device and/or topology.
This examples shows how to combine different channel transports (zeromq/shmem) inside of one device and/or topology.
## n-m

View File

@@ -17,22 +17,12 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-builtin-devices.sh.in ${CMAKE
add_test(NAME Example.BuiltinDevices.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq)
set_tests_properties(Example.BuiltinDevices.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.BuiltinDevices.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh nanomsg)
set_tests_properties(Example.BuiltinDevices.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
endif()
add_test(NAME Example.BuiltinDevices.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem)
set_tests_properties(Example.BuiltinDevices.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
add_test(NAME Example.BuiltinDevices.multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq true 2)
set_tests_properties(Example.BuiltinDevices.multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.BuiltinDevices.multipart.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh nanomsg true 2)
set_tests_properties(Example.BuiltinDevices.multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
endif()
add_test(NAME Example.BuiltinDevices.multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem true 2)
set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
@@ -44,7 +34,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-builtin-devices.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-builtin-devices.sh
)

View File

@@ -7,10 +7,10 @@
################################################################################
add_library(ExampleCopyPushLib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleCopyPushLib PUBLIC FairMQ)
@@ -35,23 +35,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURREN
add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.CopyPush.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh nanomsg)
set_tests_properties(Example.CopyPush.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
endif()
add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
# install
install(
TARGETS
fairmq-ex-copypush-sampler
fairmq-ex-copypush-sink
TARGETS
fairmq-ex-copypush-sampler
fairmq-ex-copypush-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -60,7 +55,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-copypush.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-copypush.sh
)

View File

@@ -29,7 +29,7 @@ target_link_libraries(fairmq-ex-dds-sink PRIVATE ExampleDDSLib)
add_custom_target(ExampleDDS DEPENDS fairmq-ex-dds-sampler fairmq-ex-dds-processor fairmq-ex-dds-sink)
list(JOIN Boost_LIBRARY_DIRS ":" LIB_DIR)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/sdk)
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml @ONLY)

View File

@@ -7,10 +7,10 @@
################################################################################
add_library(ExampleMultipartLib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleMultipartLib PUBLIC FairMQ)
@@ -34,11 +34,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multipart.sh.in ${CMAKE_CURRE
add_test(NAME Example.Multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh zeromq)
set_tests_properties(Example.Multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.Multipart.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh nanomsg)
set_tests_properties(Example.Multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
endif()
add_test(NAME Example.Multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh shmem)
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
@@ -50,12 +45,12 @@ endif()
# install
install(
TARGETS
fairmq-ex-multipart-sampler
fairmq-ex-multipart-sink
TARGETS
fairmq-ex-multipart-sampler
fairmq-ex-multipart-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -64,7 +59,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multipart.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multipart.sh
)

View File

@@ -7,12 +7,12 @@
################################################################################
add_library(ExampleMultipleChannelsLib STATIC
"Sampler.cxx"
"Sampler.h"
"Broadcaster.cxx"
"Broadcaster.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Broadcaster.cxx"
"Broadcaster.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleMultipleChannelsLib PUBLIC FairMQ)
@@ -39,21 +39,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMA
add_test(NAME Example.MultipleChannels.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.MultipleChannels.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh nanomsg)
set_tests_properties(Example.MultipleChannels.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
endif()
# install
install(
TARGETS
fairmq-ex-multiple-channels-sampler
fairmq-ex-multiple-channels-broadcaster
fairmq-ex-multiple-channels-sink
TARGETS
fairmq-ex-multiple-channels-sampler
fairmq-ex-multiple-channels-broadcaster
fairmq-ex-multiple-channels-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -62,7 +57,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multiple-channels.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multiple-channels.sh
)

View File

@@ -7,12 +7,12 @@
################################################################################
add_library(ExampleMultipleTransportsLib STATIC
"Sampler1.cxx"
"Sampler1.h"
"Sampler2.cxx"
"Sampler2.h"
"Sink.cxx"
"Sink.h"
"Sampler1.cxx"
"Sampler1.h"
"Sampler2.cxx"
"Sampler2.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleMultipleTransportsLib PUBLIC FairMQ)
@@ -41,13 +41,13 @@ set_tests_properties(Example.MultipleTransports PROPERTIES TIMEOUT "30" RUN_SERI
# install
install(
TARGETS
fairmq-ex-multiple-transports-sampler1
fairmq-ex-multiple-transports-sampler2
fairmq-ex-multiple-transports-sink
TARGETS
fairmq-ex-multiple-transports-sampler1
fairmq-ex-multiple-transports-sampler2
fairmq-ex-multiple-transports-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for install directories
@@ -56,7 +56,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multiple-transports.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-multiple-transports.sh
)

View File

@@ -1,12 +1,12 @@
Multiple Transports example
===========================
This example demonstrates use of multiple transports (zeromq/nanomsg/shmem) within the same topology and/or device. It is a simple topology consisting of two samplers and a sink. The devices are connected via 3 channels:
This example demonstrates use of multiple transports (zeromq/shmem) within the same topology and/or device. It is a simple topology consisting of two samplers and a sink. The devices are connected via 3 channels:
![Multiple Transports example](../../docs/images/example_multiple_transports.png?raw=true "Multiple Transports example")
Each device has main transport that it uses. By default it is ZeroMQ, and can be overriden via the `--transport` cmd option. The device will initialize additional transports if any of the channels have them configured (e.g. as an option to `--channel-config`).
In this example sampler1 and sink are started with `--transport shmem`, making shared memory their main transport, sampler2 with `--transport nanomsg`. Additionally, the ack channel is configured to use zeromq as its transport.
In this example sampler1 and sink are started with `--transport shmem`, making shared memory their main transport, sampler2 with `--transport zeromq`. Additionally, the ack channel is configured to use zeromq as its transport.
The main two things that a transport does is transfer of data and allocation of memory for the messages. By default, new messages are created via the main device transport. If a message has been created with one transport and is to be transferred with another, it has to be copied into a new message of the target transport. This happens automatically behind the scenes. To avoid this copy the device can create messages via `NewMessageFor(const string& channelName, int subChannelIndex, ...)` method, that creates the messages via the transport of the given channel (check sampler1 and sink for an example) or as the channel directly to create a message.

View File

@@ -13,7 +13,7 @@ xterm -geometry 80x30+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER1 &
SAMPLER2="fairmq-ex-multiple-transports-sampler2"
SAMPLER2+=" --id sampler2"
SAMPLER2+=" --severity debug"
SAMPLER2+=" --transport nanomsg"
SAMPLER2+=" --transport shmem"
SAMPLER2+=" --channel-config name=data2,type=push,method=bind,address=tcp://127.0.0.1:5556"
xterm -geometry 80x30+0+450 -hold -e @EX_BIN_DIR@/$SAMPLER2 &
@@ -22,6 +22,6 @@ SINK+=" --id sink1"
SINK+=" --severity debug"
SINK+=" --transport shmem"
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555"
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=nanomsg"
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=shmem"
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq"
xterm -geometry 80x30+500+225 -hold -e @EX_BIN_DIR@/$SINK &

View File

@@ -14,7 +14,7 @@ SINK+=" --max-iterations 1"
SINK+=" --control static --color false"
SINK+=" --transport shmem"
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555"
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=nanomsg"
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=zeromq"
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq"
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$!
@@ -37,7 +37,7 @@ SAMPLER2+=" --session $SESSION"
SAMPLER2+=" --verbosity veryhigh"
SAMPLER2+=" --max-iterations 1"
SAMPLER2+=" --control static --color false"
SAMPLER2+=" --transport nanomsg"
SAMPLER2+=" --transport zeromq"
SAMPLER2+=" --channel-config name=data2,type=push,method=bind,address=tcp://127.0.0.1:5556"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER2 &
SAMPLER2_PID=$!

View File

@@ -18,7 +18,7 @@ target_link_libraries(fairmq-ex-n-m-receiver PRIVATE FairMQ)
add_custom_target(ExampleNM DEPENDS fairmq-ex-n-m-synchronizer fairmq-ex-n-m-sender fairmq-ex-n-m-receiver)
list(JOIN Boost_LIBRARY_DIRS ":" LIB_DIR)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/sdk)
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-topology.xml @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-pair-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-pair-topology.xml @ONLY)

View File

@@ -10,7 +10,7 @@
<exe reachable="true">fairmq-ex-n-m-synchronizer --id sync --rate 100 --color false -P dds --channel-config name=sync,type=pub,method=bind</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="write">fmqchan_sync</id>
<name access="write">fmqchan_sync</name>
</properties>
</decltask>
@@ -18,8 +18,8 @@
<exe reachable="true">fairmq-ex-n-m-sender --id sender%taskIndex% --timeframe-size 100000 --num-receivers ${numReceivers} --color false -P dds --channel-config name=sync,type=sub,method=connect name=data,type=pair,method=connect,numSockets=${numReceivers} --dds-i data:%taskIndex%</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="read">fmqchan_sync</id>
<name access="read">fmqchan_data</id>
<name access="read">fmqchan_sync</name>
<name access="read">fmqchan_data</name>
</properties>
</decltask>
@@ -27,7 +27,7 @@
<exe reachable="true">fairmq-ex-n-m-receiver --id receiver%taskIndex% --num-senders ${numSenders} --color false -P dds --max-timeframes 10 --channel-config name=data,type=pair,method=bind,numSockets=${numSenders}</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="write">fmqchan_data</id>
<name access="write">fmqchan_data</name>
</properties>
</decltask>

View File

@@ -10,7 +10,7 @@
<exe reachable="true">fairmq-ex-n-m-synchronizer --id sync --rate 100 --color false -P dds --channel-config name=sync,type=pub,method=bind</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="write">fmqchan_sync</id>
<name access="write">fmqchan_sync</name>
</properties>
</decltask>
@@ -18,8 +18,8 @@
<exe reachable="true">fairmq-ex-n-m-sender --id sender%taskIndex% --timeframe-size 100000 --num-receivers ${numReceivers} --color false -P dds --channel-config name=sync,type=sub,method=connect name=data,type=push,method=connect,numSockets=${numReceivers}</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="read">fmqchan_sync</id>
<name access="read">fmqchan_data</id>
<name access="read">fmqchan_sync</name>
<name access="read">fmqchan_data</name>
</properties>
</decltask>
@@ -27,7 +27,7 @@
<exe reachable="true">fairmq-ex-n-m-receiver --id receiver%taskIndex% --num-senders ${numSenders} --color false -P dds --max-timeframes 10 --channel-config name=data,type=pull,method=bind</exe>
<env reachable="false">fairmq-ex-n-m-env.sh</env>
<properties>
<name access="write">fmqchan_data</id>
<name access="write">fmqchan_data</name>
</properties>
</decltask>

View File

@@ -21,7 +21,7 @@ target_link_libraries(fairmq-ex-qc-sink PRIVATE FairMQ)
add_custom_target(ExampleQC DEPENDS fairmq-ex-qc-sampler fairmq-ex-qc-dispatcher fairmq-ex-qc-task fairmq-ex-qc-sink)
list(JOIN Boost_LIBRARY_DIRS ":" LIB_DIR)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/sdk)
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-qc-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-qc-topology.xml @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-qc-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-qc-env.sh @ONLY)

View File

@@ -51,7 +51,7 @@ fairmq-dds-command-ui -c k
fairmq-dds-command-ui -c b
fairmq-dds-command-ui -c x
fairmq-dds-command-ui -c j
allexceptqctasks="main/(Sampler|QCDispatcher|Sink)"
allexceptqctasks="main/(Sampler|QCDispatcher|Sink).*"
fairmq-dds-command-ui -c r -p $allexceptqctasks
qctask="main/QCTask.*"
qcdispatcher="main/QCDispatcher.*"

View File

@@ -29,15 +29,15 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh
# install
install(
TARGETS
fairmq-ex-readout-readout
fairmq-ex-readout-builder
fairmq-ex-readout-processor
fairmq-ex-readout-sender
fairmq-ex-readout-receiver
TARGETS
fairmq-ex-readout-readout
fairmq-ex-readout-builder
fairmq-ex-readout-processor
fairmq-ex-readout-sender
fairmq-ex-readout-receiver
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -47,13 +47,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout.sh.in ${CMAKE
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-readout.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-readout.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-readout-processing.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-readout-processing.sh
)

View File

@@ -37,10 +37,10 @@ class Readout : public FairMQDevice
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("rb",
0,
10000000,
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
--fNumUnackedMsgs;
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
fNumUnackedMsgs -= blocks.size();
if (fMaxIterations > 0) {
LOG(debug) << "Received ack";
LOG(debug) << "Received " << blocks.size() << " acks";
}
}
));

View File

@@ -7,10 +7,10 @@
################################################################################
add_library(ExampleRegionLib STATIC
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
"Sampler.cxx"
"Sampler.h"
"Sink.cxx"
"Sink.h"
)
target_link_libraries(ExampleRegionLib PUBLIC FairMQ)
@@ -32,25 +32,20 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh)
add_test(NAME Example.Region.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh zeromq)
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.Region.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh nanomsg)
set_tests_properties(Example.Region.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
endif()
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
add_test(NAME Example.Region.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh shmem)
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
# install
install(
TARGETS
fairmq-ex-region-sampler
fairmq-ex-region-sink
TARGETS
fairmq-ex-region-sampler
fairmq-ex-region-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -59,7 +54,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-region.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-region.sh
)

View File

@@ -5,12 +5,6 @@
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* Sampler.cpp
*
* @since 2014-10-10
* @author A. Rybalchenko
*/
#include "Sampler.h"
@@ -23,36 +17,44 @@ namespace example_region
Sampler::Sampler()
: fMsgSize(10000)
, fLinger(100)
, fMaxIterations(0)
, fNumIterations(0)
, fRegion(nullptr)
, fNumUnackedMsgs(0)
{
}
{}
void Sampler::InitTask()
{
fMsgSize = fConfig->GetProperty<int>("msg-size");
fLinger = fConfig->GetProperty<uint32_t>("region-linger");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
LOG(warn) << ">>>" << info.event;
LOG(warn) << "id: " << info.id;
LOG(warn) << "ptr: " << info.ptr;
LOG(warn) << "size: " << info.size;
LOG(warn) << "flags: " << info.flags;
LOG(info) << "Region event: " << info.event << ": "
<< (info.managed ? "managed" : "unmanaged")
<< ", id: " << info.id
<< ", ptr: " << info.ptr
<< ", size: " << info.size
<< ", flags: " << info.flags;
});
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data",
0,
10000000,
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
--fNumUnackedMsgs;
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data", // region is created using the transport of this channel...
0, // ... and this sub-channel
10000000, // region size
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
lock_guard<mutex> lock(fMtx);
fNumUnackedMsgs -= blocks.size();
if (fMaxIterations > 0) {
LOG(debug) << "Received ack";
LOG(info) << "Received " << blocks.size() << " acks";
}
}
},
"", // path, if a region is backed by a file
0, // flags that are passed for region creation
fair::mq::RegionConfig{true, true} // additional config: { call mlock on the region, zero the region memory }
));
fRegion->SetLinger(fLinger);
}
bool Sampler::ConditionalRun()
@@ -69,9 +71,9 @@ bool Sampler::ConditionalRun()
// LOG(info) << "check: " << static_cast<char*>(fRegion->GetData())[3];
// std::this_thread::sleep_for(std::chrono::seconds(1));
lock_guard<mutex> lock(fMtx);
++fNumUnackedMsgs;
if (Send(msg, "data", 0) > 0) {
++fNumUnackedMsgs;
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
@@ -83,13 +85,15 @@ bool Sampler::ConditionalRun()
void Sampler::ResetTask()
{
// if not all messages acknowledged, wait for a bit. But only once, since receiver could be already dead.
if (fNumUnackedMsgs != 0) {
LOG(debug) << "waiting for all acknowledgements... (" << fNumUnackedMsgs << ")";
this_thread::sleep_for(chrono::milliseconds(500));
LOG(debug) << "done, still unacked: " << fNumUnackedMsgs;
}
fRegion.reset();
{
lock_guard<mutex> lock(fMtx);
if (fNumUnackedMsgs != 0) {
LOG(info) << "Done, still not acknowledged: " << fNumUnackedMsgs;
} else {
LOG(info) << "All acknowledgements received.";
}
}
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents();
}

View File

@@ -15,7 +15,8 @@
#ifndef FAIRMQEXAMPLEREGIONSAMPLER_H
#define FAIRMQEXAMPLEREGIONSAMPLER_H
#include <atomic>
#include <mutex>
#include <cstdint>
#include "FairMQDevice.h"
@@ -35,10 +36,12 @@ class Sampler : public FairMQDevice
private:
int fMsgSize;
uint32_t fLinger;
uint64_t fMaxIterations;
uint64_t fNumIterations;
FairMQUnmanagedRegionPtr fRegion;
std::atomic<uint64_t> fNumUnackedMsgs;
std::mutex fMtx;
uint64_t fNumUnackedMsgs;
};
} // namespace example_region

View File

@@ -30,11 +30,12 @@ void Sink::InitTask()
// Get the fMaxIterations value from the command line options (via fConfig)
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
LOG(warn) << ">>>" << info.event;
LOG(warn) << "id: " << info.id;
LOG(warn) << "ptr: " << info.ptr;
LOG(warn) << "size: " << info.size;
LOG(warn) << "flags: " << info.flags;
LOG(info) << "Region event: " << info.event << ": "
<< (info.managed ? "managed" : "unmanaged")
<< ", id: " << info.id
<< ", ptr: " << info.ptr
<< ", size: " << info.size
<< ", flags: " << info.flags;
});
}

View File

@@ -2,9 +2,14 @@
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
transport="shmem"
msgSize="1000000"
if [[ $1 =~ ^[0-9]+$ ]]; then
if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
if [[ $2 =~ ^[0-9]+$ ]]; then
msgSize=$1
fi
@@ -13,13 +18,13 @@ SAMPLER+=" --id sampler1"
SAMPLER+=" --severity debug"
SAMPLER+=" --msg-size $msgSize"
# SAMPLER+=" --rate 10"
SAMPLER+=" --transport shmem"
SAMPLER+=" --transport $transport"
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777,sndKernelSize=212992"
xterm -geometry 80x23+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
xterm -geometry 120x60+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
SINK="fairmq-ex-region-sink"
SINK+=" --id sink1"
SINK+=" --severity debug"
SINK+=" --transport shmem"
SINK+=" --transport $transport"
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:7777,rcvKernelSize=212992"
xterm -geometry 80x23+500+0 -hold -e @EX_BIN_DIR@/$SINK &
xterm -geometry 120x60+750+0 -hold -e @EX_BIN_DIR@/$SINK &

View File

@@ -15,6 +15,7 @@ void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
("region-linger", bpo::value<uint32_t>()->default_value(100), "Linger period for regions")
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
}

View File

@@ -23,6 +23,7 @@ SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1"
SAMPLER+=" --msg-size $msgSize"
SAMPLER+=" --region-linger 500"
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$!
@@ -30,6 +31,7 @@ SAMPLER_PID=$!
SINK="fairmq-ex-region-sink"
SINK+=" --id sink1"
SINK+=" --transport $transport"
SINK+=" --severity debug"
SINK+=" --session $SESSION"
SINK+=" --verbosity veryhigh"
SINK+=" --control static --color false"

View File

@@ -7,10 +7,10 @@
################################################################################
add_library(ExampleReqRepLib STATIC
"Client.cxx"
"Client.h"
"Server.cxx"
"Server.h"
"Client.cxx"
"Client.h"
"Server.cxx"
"Server.h"
)
target_link_libraries(ExampleReqRepLib PUBLIC FairMQ)
@@ -35,23 +35,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-req-rep.sh.in ${CMAKE_CURRENT
add_test(NAME Example.ReqRep.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh zeromq)
set_tests_properties(Example.ReqRep.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
if(BUILD_NANOMSG_TRANSPORT)
add_test(NAME Example.ReqRep.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh nanomsg)
set_tests_properties(Example.ReqRep.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
endif()
add_test(NAME Example.ReqRep.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh shmem)
set_tests_properties(Example.ReqRep.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
# install
install(
TARGETS
fairmq-ex-req-rep-client
fairmq-ex-req-rep-server
TARGETS
fairmq-ex-req-rep-client
fairmq-ex-req-rep-server
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
@@ -60,7 +55,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-req-rep.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-req-rep.sh
)

1
extern/PicoSHA2 vendored Submodule

Submodule extern/PicoSHA2 added at 599843c396

2
extern/asio vendored

View File

@@ -1,5 +1,5 @@
################################################################################
# Copyright (C) 2012-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, #
@@ -62,6 +62,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
target_link_libraries(${target}
PRIVATE
FairLogger::FairLogger
Threads::Threads
PUBLIC
Boost::boost
)
@@ -145,6 +146,7 @@ if(BUILD_FAIRMQ)
# libFairMQ header files #
##########################
set(FAIRMQ_PUBLIC_HEADER_FILES
Device.h
DeviceRunner.h
EventManager.h
FairMQChannel.h
@@ -169,19 +171,21 @@ if(BUILD_FAIRMQ)
Plugin.h
PluginManager.h
PluginServices.h
runDevice.h
runFairMQDevice.h
shmem/Monitor.h
)
set(FAIRMQ_PRIVATE_HEADER_FILES
devices/FairMQBenchmarkSampler.h
devices/FairMQMerger.h
devices/FairMQMultiplier.h
devices/FairMQProxy.h
devices/FairMQSink.h
devices/FairMQSplitter.h
devices/BenchmarkSampler.h
devices/Merger.h
devices/Multiplier.h
devices/Proxy.h
devices/Sink.h
devices/Splitter.h
plugins/Builtin.h
plugins/config/Config.h
plugins/Control.h
plugins/control/Control.h
shmem/Message.h
shmem/Poller.h
shmem/UnmanagedRegion.h
@@ -190,23 +194,14 @@ if(BUILD_FAIRMQ)
shmem/Common.h
shmem/Manager.h
shmem/Region.h
zeromq/FairMQMessageZMQ.h
zeromq/FairMQPollerZMQ.h
zeromq/FairMQUnmanagedRegionZMQ.h
zeromq/FairMQSocketZMQ.h
zeromq/FairMQTransportFactoryZMQ.h
zeromq/Context.h
zeromq/Message.h
zeromq/Poller.h
zeromq/UnmanagedRegion.h
zeromq/Socket.h
zeromq/TransportFactory.h
)
if(BUILD_NANOMSG_TRANSPORT)
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
nanomsg/FairMQMessageNN.h
nanomsg/FairMQPollerNN.h
nanomsg/FairMQUnmanagedRegionNN.h
nanomsg/FairMQSocketNN.h
nanomsg/FairMQTransportFactoryNN.h
)
endif()
if(BUILD_OFI_TRANSPORT)
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
ofi/Context.h
@@ -229,11 +224,6 @@ if(BUILD_FAIRMQ)
FairMQPoller.cxx
FairMQSocket.cxx
FairMQTransportFactory.cxx
devices/FairMQBenchmarkSampler.cxx
devices/FairMQMerger.cxx
devices/FairMQMultiplier.cxx
devices/FairMQProxy.cxx
devices/FairMQSplitter.cxx
Plugin.cxx
PluginManager.cxx
PluginServices.cxx
@@ -242,31 +232,11 @@ if(BUILD_FAIRMQ)
Properties.cxx
SuboptParser.cxx
plugins/config/Config.cxx
plugins/Control.cxx
shmem/Message.cxx
shmem/Poller.cxx
shmem/Socket.cxx
shmem/TransportFactory.cxx
shmem/Manager.cxx
shmem/Region.cxx
zeromq/FairMQMessageZMQ.cxx
zeromq/FairMQPollerZMQ.cxx
zeromq/FairMQUnmanagedRegionZMQ.cxx
zeromq/FairMQSocketZMQ.cxx
zeromq/FairMQTransportFactoryZMQ.cxx
plugins/control/Control.cxx
MemoryResources.cxx
shmem/Monitor.cxx
)
if(BUILD_NANOMSG_TRANSPORT)
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
nanomsg/FairMQMessageNN.cxx
nanomsg/FairMQPollerNN.cxx
nanomsg/FairMQUnmanagedRegionNN.cxx
nanomsg/FairMQSocketNN.cxx
nanomsg/FairMQTransportFactoryNN.cxx
)
endif()
if(BUILD_OFI_TRANSPORT)
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
ofi/Context.cxx
@@ -282,7 +252,7 @@ if(BUILD_FAIRMQ)
# configure files #
###################
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run/startMQBenchmark.sh.in ${CMAKE_CURRENT_BINARY_DIR}/startMQBenchmark.sh)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/devices/startMQBenchmark.sh.in ${CMAKE_CURRENT_BINARY_DIR}/startMQBenchmark.sh)
#################################
# define libFairMQ build target #
@@ -307,12 +277,13 @@ if(BUILD_FAIRMQ)
# preprocessor definitions #
############################
target_compile_definitions(${_target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
if(BUILD_NANOMSG_TRANSPORT)
target_compile_definitions(${_target} PRIVATE BUILD_NANOMSG_TRANSPORT)
if(FAIRMQ_DEBUG_MODE)
target_compile_definitions(${_target} PUBLIC FAIRMQ_DEBUG_MODE)
endif()
if(BUILD_OFI_TRANSPORT)
target_compile_definitions(${_target} PRIVATE BUILD_OFI_TRANSPORT)
endif()
target_compile_definitions(${_target} PUBLIC FAIRMQ_HAS_STD_FILESYSTEM=${FAIRMQ_HAS_STD_FILESYSTEM})
#######################
@@ -330,16 +301,13 @@ if(BUILD_FAIRMQ)
##################
# link libraries #
##################
if(BUILD_NANOMSG_TRANSPORT)
set(NANOMSG_DEPS nanomsg msgpackc-cxx)
endif()
if(BUILD_OFI_TRANSPORT)
set(OFI_DEPS
asiofi::asiofi
Boost::container
)
endif()
set(optional_deps ${NANOMSG_DEPS} ${OFI_DEPS})
set(optional_deps ${OFI_DEPS})
if(optional_deps)
list(REMOVE_DUPLICATES optional_deps)
endif()
@@ -362,7 +330,7 @@ if(BUILD_FAIRMQ)
PRIVATE # only libFairMQ links against private dependencies
libzmq
${NANOMSG_DEPS}
PicoSHA2
${OFI_DEPS}
)
set_target_properties(${_target} PROPERTIES
@@ -389,39 +357,49 @@ if(BUILD_FAIRMQ)
###############
# executables #
###############
add_executable(fairmq-bsampler run/runBenchmarkSampler.cxx)
add_executable(fairmq-bsampler devices/runBenchmarkSampler.cxx)
target_link_libraries(fairmq-bsampler FairMQ)
add_executable(fairmq-merger run/runMerger.cxx)
add_executable(fairmq-merger devices/runMerger.cxx)
target_link_libraries(fairmq-merger FairMQ)
add_executable(fairmq-multiplier run/runMultiplier.cxx)
add_executable(fairmq-multiplier devices/runMultiplier.cxx)
target_link_libraries(fairmq-multiplier FairMQ)
add_executable(fairmq-proxy run/runProxy.cxx)
add_executable(fairmq-proxy devices/runProxy.cxx)
target_link_libraries(fairmq-proxy FairMQ)
add_executable(fairmq-sink run/runSink.cxx)
add_executable(fairmq-sink devices/runSink.cxx)
target_link_libraries(fairmq-sink FairMQ)
add_executable(fairmq-splitter run/runSplitter.cxx)
add_executable(fairmq-splitter devices/runSplitter.cxx)
target_link_libraries(fairmq-splitter FairMQ)
add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx)
target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
if(FAIRMQ_DEBUG_MODE)
target_compile_definitions(fairmq-shmmonitor PUBLIC FAIRMQ_DEBUG_MODE)
endif()
target_link_libraries(fairmq-shmmonitor PUBLIC
Threads::Threads
$<$<PLATFORM_ID:Linux>:rt>
Boost::boost
Boost::date_time
$<$<NOT:${FAIRMQ_HAS_STD_FILESYSTEM}>:Boost::filesystem>
Boost::program_options
FairLogger::FairLogger
PicoSHA2
)
target_include_directories(fairmq-shmmonitor PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
)
target_compile_definitions(fairmq-shmmonitor PUBLIC FAIRMQ_HAS_STD_FILESYSTEM=${FAIRMQ_HAS_STD_FILESYSTEM})
add_executable(fairmq-uuid-gen run/runUuidGenerator.cxx)
target_link_libraries(fairmq-uuid-gen FairMQ)
add_executable(fairmq-uuid-gen tools/runUuidGenerator.cxx)
target_link_libraries(fairmq-uuid-gen PUBLIC
Boost::program_options
Tools
)
###########

21
fairmq/Device.h Normal file
View File

@@ -0,0 +1,21 @@
/********************************************************************************
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_DEVICE_H
#define FAIR_MQ_DEVICE_H
#include <FairMQDevice.h>
namespace fair::mq
{
using Device = ::FairMQDevice;
} // namespace fair::mq
#endif /* FAIR_MQ_DEVICE_H */

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -8,10 +8,14 @@
#include "DeviceRunner.h"
#include <exception>
#include <fairmq/Tools.h>
#include <fairmq/tools/Strings.h>
#include <fairmq/tools/Version.h>
#include <fairmq/Version.h>
#include <fairlogger/Logger.h>
#include <exception>
using namespace std;
using namespace fair::mq;
@@ -52,7 +56,13 @@ bool DeviceRunner::HandleGeneralOptions(const fair::mq::ProgOptions& config, boo
fair::Logger::SetConsoleSeverity("nolog");
} else {
fair::Logger::SetConsoleColor(color);
fair::Logger::SetConsoleSeverity(severity);
auto envFairMQSeverity = getenv("FAIRMQ_SEVERITY");
if (envFairMQSeverity) {
severity = envFairMQSeverity;
}
if (severity != "") {
fair::Logger::SetConsoleSeverity(severity);
}
}
if (printLogo) {
@@ -150,8 +160,8 @@ auto DeviceRunner::Run() -> int
// Handle --version
if (fConfig.Count("version")) {
cout << "FairMQ version: " << FAIRMQ_GIT_VERSION << endl;
cout << "User device version: " << fDevice->GetVersion() << endl;
LOGV(info, verylow) << "FairMQ version: " << FAIRMQ_GIT_VERSION;
LOGV(info, verylow) << "User device version: " << fDevice->GetVersion();
fDevice->ChangeState(fair::mq::Transition::End);
return 0;
}

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -9,19 +9,18 @@
#ifndef FAIR_MQ_DEVICERUNNER_H
#define FAIR_MQ_DEVICERUNNER_H
#include <fairmq/Device.h>
#include <fairmq/EventManager.h>
#include <fairmq/PluginManager.h>
#include <fairmq/ProgOptions.h>
#include <FairMQDevice.h>
#include <FairMQLogger.h>
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace fair {
namespace mq {
namespace fair::mq
{
/**
* @class DeviceRunner DeviceRunner.h <fairmq/DeviceRunner.h>
@@ -74,7 +73,7 @@ class DeviceRunner
std::vector<std::string> fRawCmdLineArgs;
fair::mq::ProgOptions fConfig;
std::unique_ptr<FairMQDevice> fDevice;
std::unique_ptr<Device> fDevice;
PluginManager fPluginManager;
const bool fPrintLogo;
@@ -89,7 +88,6 @@ struct ModifyRawCmdLineArgs : Event<DeviceRunner&> {};
struct InstantiateDevice : Event<DeviceRunner&> {};
} /* namespace hooks */
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIR_MQ_DEVICERUNNER_H */

View File

@@ -21,9 +21,7 @@
#include <boost/functional/hash.hpp>
#include <boost/signals2.hpp>
namespace fair
{
namespace mq
namespace fair::mq
{
// Inherit from this base event type to create custom event types
@@ -137,7 +135,6 @@ class EventManager
}
}; /* class EventManager */
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIR_MQ_EVENTMANAGER_H */

View File

@@ -7,11 +7,15 @@
********************************************************************************/
#include "FairMQChannel.h"
#include <fairmq/tools/Strings.h>
#include <fairmq/Properties.h>
#include <fairlogger/Logger.h>
#include <boost/algorithm/string.hpp> // join/split
#include <cstddef> // size_t
#include <regex>
#include <set>
#include <random>
@@ -77,31 +81,30 @@ FairMQChannel::FairMQChannel(const string& name, const string& type, const strin
, fPortRangeMin(DefaultPortRangeMin)
, fPortRangeMax(DefaultPortRangeMax)
, fAutoBind(DefaultAutoBind)
, fIsValid(false)
, fValid(false)
, fMultipart(false)
, fModified(true)
, fReset(false)
, fMtx()
{}
{
// LOG(warn) << "Constructing channel '" << fName << "'";
}
FairMQChannel::FairMQChannel(const string& name, int index, const fair::mq::Properties& properties)
: FairMQChannel(tools::ToString(name, "[", index, "]"), "unspecified", "unspecified", "unspecified", nullptr)
{
string prefix(tools::ToString("chans.", name, ".", index, "."));
fType = GetPropertyOrDefault(properties, string(prefix + "type"), fType);
fMethod = GetPropertyOrDefault(properties, string(prefix + "method"), fMethod);
fAddress = GetPropertyOrDefault(properties, string(prefix + "address"), fAddress);
fTransportType = TransportTypes.at(GetPropertyOrDefault(properties, string(prefix + "transport"), TransportNames.at(fTransportType)));
fSndBufSize = GetPropertyOrDefault(properties, string(prefix + "sndBufSize"), fSndBufSize);
fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), fRcvBufSize);
fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), fSndKernelSize);
fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), fRcvKernelSize);
fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), fLinger);
fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), fRateLogging);
fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), fPortRangeMin);
fPortRangeMax = GetPropertyOrDefault(properties, string(prefix + "portRangeMax"), fPortRangeMax);
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), fAutoBind);
fType = GetPropertyOrDefault(properties, string(prefix + "type"), std::string(DefaultType));
fMethod = GetPropertyOrDefault(properties, string(prefix + "method"), std::string(DefaultMethod));
fAddress = GetPropertyOrDefault(properties, string(prefix + "address"), std::string(DefaultAddress));
fTransportType = TransportType(GetPropertyOrDefault(properties, string(prefix + "transport"), std::string(DefaultTransportName)));
fSndBufSize = GetPropertyOrDefault(properties, string(prefix + "sndBufSize"), DefaultSndBufSize);
fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), DefaultRcvBufSize);
fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), DefaultSndKernelSize);
fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), DefaultRcvKernelSize);
fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), DefaultLinger);
fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), DefaultRateLogging);
fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), DefaultPortRangeMin);
fPortRangeMax = GetPropertyOrDefault(properties, string(prefix + "portRangeMax"), DefaultPortRangeMax);
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), DefaultAutoBind);
}
FairMQChannel::FairMQChannel(const FairMQChannel& chan)
@@ -125,10 +128,8 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan, const string& newName)
, fPortRangeMin(chan.fPortRangeMin)
, fPortRangeMax(chan.fPortRangeMax)
, fAutoBind(chan.fAutoBind)
, fIsValid(false)
, fValid(false)
, fMultipart(chan.fMultipart)
, fModified(chan.fModified)
, fReset(false)
{}
FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
@@ -137,372 +138,34 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
return *this;
}
{
// TODO: replace this with std::scoped_lock (c++17)
lock(fMtx, chan.fMtx);
lock_guard<mutex> lock1(fMtx, adopt_lock);
lock_guard<mutex> lock2(chan.fMtx, adopt_lock);
fTransportFactory = nullptr;
fTransportType = chan.fTransportType;
fSocket = nullptr;
fName = chan.fName;
fType = chan.fType;
fMethod = chan.fMethod;
fAddress = chan.fAddress;
fSndBufSize = chan.fSndBufSize;
fRcvBufSize = chan.fRcvBufSize;
fSndKernelSize = chan.fSndKernelSize;
fRcvKernelSize = chan.fRcvKernelSize;
fLinger = chan.fLinger;
fRateLogging = chan.fRateLogging;
fPortRangeMin = chan.fPortRangeMin;
fPortRangeMax = chan.fPortRangeMax;
fAutoBind = chan.fAutoBind;
fIsValid = false;
fMultipart = chan.fMultipart;
fModified = chan.fModified;
fReset = false;
}
fTransportFactory = nullptr;
fTransportType = chan.fTransportType;
fSocket = nullptr;
fName = chan.fName;
fType = chan.fType;
fMethod = chan.fMethod;
fAddress = chan.fAddress;
fSndBufSize = chan.fSndBufSize;
fRcvBufSize = chan.fRcvBufSize;
fSndKernelSize = chan.fSndKernelSize;
fRcvKernelSize = chan.fRcvKernelSize;
fLinger = chan.fLinger;
fRateLogging = chan.fRateLogging;
fPortRangeMin = chan.fPortRangeMin;
fPortRangeMax = chan.fPortRangeMax;
fAutoBind = chan.fAutoBind;
fValid = false;
fMultipart = chan.fMultipart;
return *this;
}
FairMQSocket & FairMQChannel::GetSocket() const
{
assert(fSocket);
return *fSocket;
}
string FairMQChannel::GetName() const
{
lock_guard<mutex> lock(fMtx);
return fName;
}
string FairMQChannel::GetPrefix() const
{
lock_guard<mutex> lock(fMtx);
string prefix = fName;
prefix = prefix.erase(fName.rfind('['));
return prefix;
}
string FairMQChannel::GetIndex() const
{
lock_guard<mutex> lock(fMtx);
string indexStr = fName;
indexStr.erase(indexStr.rfind(']'));
indexStr.erase(0, indexStr.rfind('[') + 1);
return indexStr;
}
string FairMQChannel::GetType() const
try {
lock_guard<mutex> lock(fMtx);
return fType;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetType: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
string FairMQChannel::GetMethod() const
try {
lock_guard<mutex> lock(fMtx);
return fMethod;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetMethod: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
string FairMQChannel::GetAddress() const
try {
lock_guard<mutex> lock(fMtx);
return fAddress;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetAddress: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
string FairMQChannel::GetTransportName() const
try {
lock_guard<mutex> lock(fMtx);
return TransportNames.at(fTransportType);
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetTransportName: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
Transport FairMQChannel::GetTransportType() const
try {
lock_guard<mutex> lock(fMtx);
return fTransportType;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetTransportType: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetSndBufSize() const
try {
lock_guard<mutex> lock(fMtx);
return fSndBufSize;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetSndBufSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetRcvBufSize() const
try {
lock_guard<mutex> lock(fMtx);
return fRcvBufSize;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetRcvBufSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetSndKernelSize() const
try {
lock_guard<mutex> lock(fMtx);
return fSndKernelSize;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetSndKernelSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetRcvKernelSize() const
try {
lock_guard<mutex> lock(fMtx);
return fRcvKernelSize;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetRcvKernelSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetLinger() const
try {
lock_guard<mutex> lock(fMtx);
return fLinger;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetLinger: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetRateLogging() const
try {
lock_guard<mutex> lock(fMtx);
return fRateLogging;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetRateLogging: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetPortRangeMin() const
try {
lock_guard<mutex> lock(fMtx);
return fPortRangeMin;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMin: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
int FairMQChannel::GetPortRangeMax() const
try {
lock_guard<mutex> lock(fMtx);
return fPortRangeMax;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMax: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
bool FairMQChannel::GetAutoBind() const
try {
lock_guard<mutex> lock(fMtx);
return fAutoBind;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::GetAutoBind: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateType(const string& type)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fType = type;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateType: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateMethod(const string& method)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fMethod = method;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateMethod: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateAddress(const string& address)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fAddress = address;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateAddress: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateTransport(const string& transport)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fTransportType = TransportTypes.at(transport);
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateTransport: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateSndBufSize(const int sndBufSize)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fSndBufSize = sndBufSize;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateSndBufSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateRcvBufSize(const int rcvBufSize)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fRcvBufSize = rcvBufSize;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateRcvBufSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateSndKernelSize(const int sndKernelSize)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fSndKernelSize = sndKernelSize;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateSndKernelSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateRcvKernelSize(const int rcvKernelSize)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fRcvKernelSize = rcvKernelSize;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateRcvKernelSize: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateLinger(const int duration)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fLinger = duration;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateLinger: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateRateLogging(const int rateLogging)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fRateLogging = rateLogging;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateRateLogging: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdatePortRangeMin(const int minPort)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fPortRangeMin = minPort;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdatePortRangeMin: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdatePortRangeMax(const int maxPort)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fPortRangeMax = maxPort;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdatePortRangeMax: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateAutoBind(const bool autobind)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fAutoBind = autobind;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateAutoBind: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
auto FairMQChannel::SetModified(const bool modified) -> void
try {
lock_guard<mutex> lock(fMtx);
fModified = modified;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::SetModified: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
void FairMQChannel::UpdateName(const string& name)
try {
lock_guard<mutex> lock(fMtx);
fIsValid = false;
fName = name;
fModified = true;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::UpdateName: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
bool FairMQChannel::IsValid() const
try {
lock_guard<mutex> lock(fMtx);
return fIsValid;
} catch (exception& e) {
LOG(error) << "Exception caught in FairMQChannel::IsValid: " << e.what();
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
}
bool FairMQChannel::Validate()
try {
lock_guard<mutex> lock(fMtx);
stringstream ss;
ss << "Validating channel '" << fName << "'... ";
if (fIsValid) {
if (fValid) {
ss << "ALREADY VALID";
LOG(debug) << ss.str();
return true;
@@ -535,7 +198,7 @@ try {
} else {
vector<string> endpoints;
boost::algorithm::split(endpoints, fAddress, boost::algorithm::is_any_of(";"));
for (const auto endpoint : endpoints) {
for (const auto& endpoint : endpoints) {
string address;
if (endpoint[0] == '@' || endpoint[0] == '+' || endpoint[0] == '>') {
address = endpoint.substr(1);
@@ -637,7 +300,7 @@ try {
throw ChannelConfigurationError(tools::ToString("invalid socket rate logging interval (cannot be negative): '", fRateLogging, "'"));
}
fIsValid = true;
fValid = true;
ss << "VALID";
LOG(debug) << ss.str();
return true;
@@ -648,8 +311,6 @@ try {
void FairMQChannel::Init()
{
lock_guard<mutex> lock(fMtx);
fSocket = fTransportFactory->CreateSocket(fType, fName);
// set linger duration (how long socket should wait for outstanding transfers before shutdown)
@@ -670,19 +331,22 @@ void FairMQChannel::Init()
bool FairMQChannel::ConnectEndpoint(const string& endpoint)
{
lock_guard<mutex> lock(fMtx);
return fSocket->Connect(endpoint);
}
bool FairMQChannel::BindEndpoint(string& endpoint)
{
lock_guard<mutex> lock(fMtx);
// try to bind to the configured port. If it fails, try random one (if AutoBind is on).
if (fSocket->Bind(endpoint)) {
return true;
} else {
// auto-bind only implemented for TCP
size_t protocolPos = endpoint.find(':');
string protocol = endpoint.substr(0, protocolPos);
if (protocol != "tcp") {
return false;
}
if (fAutoBind) {
// number of attempts when choosing a random port
int numAttempts = 0;
@@ -712,10 +376,3 @@ bool FairMQChannel::BindEndpoint(string& endpoint)
}
}
void FairMQChannel::ResetChannel()
{
lock_guard<mutex> lock(fMtx);
fIsValid = false;
// TODO: implement channel resetting
}

View File

@@ -13,7 +13,6 @@
#include <FairMQUnmanagedRegion.h>
#include <FairMQSocket.h>
#include <fairmq/Transports.h>
#include <FairMQLogger.h>
#include <FairMQParts.h>
#include <fairmq/Properties.h>
#include <FairMQMessage.h>
@@ -24,9 +23,14 @@
#include <mutex>
#include <stdexcept>
#include <utility> // std::move
#include <cstddef> // size_t
#include <cstdint> // int64_t
/**
* @class FairMQChannel FairMQChannel.h <FairMQChannel.h>
* @brief Wrapper class for FairMQSocket and related methods
*
* The class is not thread-safe.
*/
class FairMQChannel
{
friend class FairMQDevice;
@@ -68,23 +72,20 @@ class FairMQChannel
FairMQChannel(const FairMQChannel&, const std::string& name);
/// Move constructor
FairMQChannel(FairMQChannel&&) = delete;
// FairMQChannel(FairMQChannel&&) = delete;
/// Assignment operator
FairMQChannel& operator=(const FairMQChannel&);
/// Move assignment operator
FairMQChannel& operator=(FairMQChannel&&) = delete;
// FairMQChannel& operator=(FairMQChannel&&) = delete;
/// Destructor
virtual ~FairMQChannel()
{
// LOG(debug) << "Destroying channel " << fName;
}
virtual ~FairMQChannel() { /* LOG(warn) << "Destroying channel '" << fName << "'"; */ }
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
FairMQSocket& GetSocket() const;
FairMQSocket& GetSocket() const { assert(fSocket); return *fSocket; }
bool Bind(const std::string& address)
{
@@ -102,139 +103,142 @@ class FairMQChannel
/// Get channel name
/// @return Returns full channel name (e.g. "data[0]")
std::string GetChannelName() const __attribute__((deprecated("Use GetName()"))) { return GetName(); }
std::string GetName() const ;
std::string GetName() const { return fName; }
/// Get channel prefix
/// @return Returns channel prefix (e.g. "data" in "data[0]")
std::string GetChannelPrefix() const __attribute__((deprecated("Use GetPrefix()"))) { return GetPrefix(); }
std::string GetPrefix() const;
std::string GetPrefix() const
{
std::string prefix = fName;
prefix = prefix.erase(fName.rfind('['));
return prefix;
}
/// Get channel index
/// @return Returns channel index (e.g. 0 in "data[0]")
std::string GetChannelIndex() const __attribute__((deprecated("Use GetIndex()"))) { return GetIndex(); }
std::string GetIndex() const;
std::string GetIndex() const
{
std::string indexStr = fName;
indexStr.erase(indexStr.rfind(']'));
indexStr.erase(0, indexStr.rfind('[') + 1);
return indexStr;
}
/// Get socket type
/// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
std::string GetType() const;
std::string GetType() const { return fType; }
/// Get socket method
/// @return Returns socket method (bind/connect)
std::string GetMethod() const;
std::string GetMethod() const { return fMethod; }
/// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
/// @return Returns socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
std::string GetAddress() const;
std::string GetAddress() const { return fAddress; }
/// Get channel transport name ("default", "zeromq", "nanomsg" or "shmem")
/// @return Returns channel transport name (e.g. "default", "zeromq", "nanomsg" or "shmem")
std::string GetTransportName() const;
/// Get channel transport name ("default", "zeromq" or "shmem")
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
std::string GetTransportName() const { return fair::mq::TransportName(fTransportType); }
/// Get channel transport type
/// @return Returns channel transport type
fair::mq::Transport GetTransportType() const;
fair::mq::Transport GetTransportType() const { return fTransportType; }
/// Get socket send buffer size (in number of messages)
/// @return Returns socket send buffer size (in number of messages)
int GetSndBufSize() const;
int GetSndBufSize() const { return fSndBufSize; }
/// Get socket receive buffer size (in number of messages)
/// @return Returns socket receive buffer size (in number of messages)
int GetRcvBufSize() const;
int GetRcvBufSize() const { return fRcvBufSize; }
/// Get socket kernel transmit send buffer size (in bytes)
/// @return Returns socket kernel transmit send buffer size (in bytes)
int GetSndKernelSize() const;
int GetSndKernelSize() const { return fSndKernelSize; }
/// Get socket kernel transmit receive buffer size (in bytes)
/// @return Returns socket kernel transmit receive buffer size (in bytes)
int GetRcvKernelSize() const;
int GetRcvKernelSize() const { return fRcvKernelSize; }
/// Get linger duration (in milliseconds)
/// @return Returns linger duration (in milliseconds)
int GetLinger() const;
int GetLinger() const { return fLinger; }
/// Get socket rate logging interval (in seconds)
/// @return Returns socket rate logging interval (in seconds)
int GetRateLogging() const;
int GetRateLogging() const { return fRateLogging; }
/// Get start of the port range for automatic binding
/// @return start of the port range
int GetPortRangeMin() const;
int GetPortRangeMin() const { return fPortRangeMin; }
/// Get end of the port range for automatic binding
/// @return end of the port range
int GetPortRangeMax() const;
int GetPortRangeMax() const { return fPortRangeMax; }
/// Set automatic binding (pick random port if bind fails)
/// @return true/false, true if automatic binding is enabled
bool GetAutoBind() const;
/// Set socket type
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
void UpdateType(const std::string& type);
/// Set socket method
/// @param method Socket method (bind/connect)
void UpdateMethod(const std::string& method);
/// Set socket address
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
void UpdateAddress(const std::string& address);
/// Set channel transport
/// @param transport transport string ("default", "zeromq", "nanomsg" or "shmem")
void UpdateTransport(const std::string& transport);
/// Set socket send buffer size
/// @param sndBufSize Socket send buffer size (in number of messages)
void UpdateSndBufSize(const int sndBufSize);
/// Set socket receive buffer size
/// @param rcvBufSize Socket receive buffer size (in number of messages)
void UpdateRcvBufSize(const int rcvBufSize);
/// Set socket kernel transmit send buffer size (in bytes)
/// @param sndKernelSize Socket send buffer size (in bytes)
void UpdateSndKernelSize(const int sndKernelSize);
/// Set socket kernel transmit receive buffer size (in bytes)
/// @param rcvKernelSize Socket receive buffer size (in bytes)
void UpdateRcvKernelSize(const int rcvKernelSize);
/// Set linger duration (in milliseconds)
/// @param duration linger duration (in milliseconds)
void UpdateLinger(const int duration);
/// Set socket rate logging interval (in seconds)
/// @param rateLogging Socket rate logging interval (in seconds)
void UpdateRateLogging(const int rateLogging);
/// Set start of the port range for automatic binding
/// @param minPort start of the port range
void UpdatePortRangeMin(const int minPort);
/// Set end of the port range for automatic binding
/// @param maxPort end of the port range
void UpdatePortRangeMax(const int maxPort);
/// Set automatic binding (pick random port if bind fails)
/// @param autobind true/false, true to enable automatic binding
void UpdateAutoBind(const bool autobind);
bool GetAutoBind() const { return fAutoBind; }
/// Set channel name
/// @param name Arbitrary channel name
void UpdateChannelName(const std::string& name) __attribute__((deprecated("Use UpdateName()"))) { UpdateName(name); }
void UpdateName(const std::string& name);
void UpdateName(const std::string& name) { fName = name; Invalidate(); }
/// Set socket type
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
void UpdateType(const std::string& type) { fType = type; Invalidate(); }
/// Set socket method
/// @param method Socket method (bind/connect)
void UpdateMethod(const std::string& method) { fMethod = method; Invalidate(); }
/// Set socket address
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
void UpdateAddress(const std::string& address) { fAddress = address; Invalidate(); }
/// Set channel transport
/// @param transport transport string ("default", "zeromq" or "shmem")
void UpdateTransport(const std::string& transport) { fTransportType = fair::mq::TransportType(transport); Invalidate(); }
/// Set socket send buffer size
/// @param sndBufSize Socket send buffer size (in number of messages)
void UpdateSndBufSize(const int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); }
/// Set socket receive buffer size
/// @param rcvBufSize Socket receive buffer size (in number of messages)
void UpdateRcvBufSize(const int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); }
/// Set socket kernel transmit send buffer size (in bytes)
/// @param sndKernelSize Socket send buffer size (in bytes)
void UpdateSndKernelSize(const int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); }
/// Set socket kernel transmit receive buffer size (in bytes)
/// @param rcvKernelSize Socket receive buffer size (in bytes)
void UpdateRcvKernelSize(const int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); }
/// Set linger duration (in milliseconds)
/// @param duration linger duration (in milliseconds)
void UpdateLinger(const int duration) { fLinger = duration; Invalidate(); }
/// Set socket rate logging interval (in seconds)
/// @param rateLogging Socket rate logging interval (in seconds)
void UpdateRateLogging(const int rateLogging) { fRateLogging = rateLogging; Invalidate(); }
/// Set start of the port range for automatic binding
/// @param minPort start of the port range
void UpdatePortRangeMin(const int minPort) { fPortRangeMin = minPort; Invalidate(); }
/// Set end of the port range for automatic binding
/// @param maxPort end of the port range
void UpdatePortRangeMax(const int maxPort) { fPortRangeMax = maxPort; Invalidate(); }
/// Set automatic binding (pick random port if bind fails)
/// @param autobind true/false, true to enable automatic binding
void UpdateAutoBind(const bool autobind) { fAutoBind = autobind; Invalidate(); }
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
/// @return true if channel settings are valid, false otherwise.
bool IsValid() const;
/// Validates channel configuration
/// @return true if channel settings are valid, false otherwise.
bool ValidateChannel() __attribute__((deprecated("Use Validate()"))) { return Validate(); }
bool IsValid() const { return fValid; }
/// Validates channel configuration
/// @return true if channel settings are valid, false otherwise.
@@ -246,14 +250,14 @@ class FairMQChannel
bool BindEndpoint(std::string& endpoint);
/// Resets the channel (requires validation to be used again).
void ResetChannel();
/// invalidates the channel (requires validation to be used again).
void Invalidate() { fValid = false; }
/// Sends a message to the socket queue.
/// @param msg Constant reference of unique_ptr to a FairMQMessage
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
int Send(FairMQMessagePtr& msg, int sndTimeoutInMs = -1)
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(FairMQMessagePtr& msg, int sndTimeoutInMs = -1)
{
CheckSendCompatibility(msg);
return fSocket->Send(msg, sndTimeoutInMs);
@@ -262,8 +266,8 @@ class FairMQChannel
/// Receives a message from the socket queue.
/// @param msg Constant reference of unique_ptr to a FairMQMessage
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
int Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs = -1)
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs = -1)
{
CheckReceiveCompatibility(msg);
return fSocket->Receive(msg, rcvTimeoutInMs);
@@ -272,7 +276,7 @@ class FairMQChannel
/// Send a vector of messages
/// @param msgVec message vector reference
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(std::vector<FairMQMessagePtr>& msgVec, int sndTimeoutInMs = -1)
{
CheckSendCompatibility(msgVec);
@@ -282,7 +286,7 @@ class FairMQChannel
/// Receive a vector of messages
/// @param msgVec message vector reference
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(std::vector<FairMQMessagePtr>& msgVec, int rcvTimeoutInMs = -1)
{
CheckReceiveCompatibility(msgVec);
@@ -292,7 +296,7 @@ class FairMQChannel
/// Send FairMQParts
/// @param parts FairMQParts reference
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(FairMQParts& parts, int sndTimeoutInMs = -1)
{
return Send(parts.fParts, sndTimeoutInMs);
@@ -301,7 +305,7 @@ class FairMQChannel
/// Receive FairMQParts
/// @param parts FairMQParts reference
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(FairMQParts& parts, int rcvTimeoutInMs = -1)
{
return Receive(parts.fParts, rcvTimeoutInMs);
@@ -312,10 +316,7 @@ class FairMQChannel
unsigned long GetMessagesTx() const { return fSocket->GetMessagesTx(); }
unsigned long GetMessagesRx() const { return fSocket->GetMessagesRx(); }
auto Transport() -> FairMQTransportFactory*
{
return fTransportFactory.get();
};
auto Transport() -> FairMQTransportFactory* { return fTransportFactory.get(); };
template<typename... Args>
FairMQMessagePtr NewMessage(Args&&... args)
@@ -335,14 +336,10 @@ class FairMQChannel
return Transport()->NewStaticMessage(data);
}
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
template<typename... Args>
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
{
return Transport()->CreateUnmanagedRegion(size, callback, path, flags);
}
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
{
return Transport()->CreateUnmanagedRegion(size, userFlags, callback, path, flags);
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
}
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::DEFAULT;
@@ -380,13 +377,9 @@ class FairMQChannel
int fPortRangeMax;
bool fAutoBind;
bool fIsValid;
bool fValid;
bool fMultipart;
bool fModified;
bool fReset;
mutable std::mutex fMtx;
void CheckSendCompatibility(FairMQMessagePtr& msg)
{
@@ -443,8 +436,6 @@ class FairMQChannel
fTransportFactory = factory;
fTransportType = factory->GetType();
}
auto SetModified(const bool modified) -> void;
};
#endif /* FAIRMQCHANNEL_H_ */

View File

@@ -24,34 +24,6 @@
using namespace std;
using namespace fair::mq;
static map<Transition, State> backwardsCompatibilityWaitForEndOfStateHelper =
{
{ Transition::InitDevice, State::InitializingDevice },
{ Transition::CompleteInit, State::Initialized },
{ Transition::Bind, State::Bound },
{ Transition::Connect, State::DeviceReady },
{ Transition::InitTask, State::Ready },
{ Transition::Run, State::Ready },
{ Transition::Stop, State::Ready },
{ Transition::ResetTask, State::DeviceReady },
{ Transition::ResetDevice, State::Idle }
};
static map<int, Transition> backwardsCompatibilityChangeStateHelper =
{
{ FairMQDevice::Event::INIT_DEVICE, Transition::InitDevice },
{ FairMQDevice::Event::internal_DEVICE_READY, Transition::Auto },
{ FairMQDevice::Event::INIT_TASK, Transition::InitTask },
{ FairMQDevice::Event::internal_READY, Transition::Auto },
{ FairMQDevice::Event::RUN, Transition::Run },
{ FairMQDevice::Event::STOP, Transition::Stop },
{ FairMQDevice::Event::RESET_TASK, Transition::ResetTask },
{ FairMQDevice::Event::RESET_DEVICE, Transition::ResetDevice },
{ FairMQDevice::Event::internal_IDLE, Transition::Auto },
{ FairMQDevice::Event::END, Transition::End },
{ FairMQDevice::Event::ERROR_FOUND, Transition::ErrorFound }
};
constexpr const char* FairMQDevice::DefaultId;
constexpr int FairMQDevice::DefaultIOThreads;
constexpr const char* FairMQDevice::DefaultTransportName;
@@ -103,7 +75,7 @@ FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
: fTransportFactory(nullptr)
, fTransports()
, fChannels()
, fInternalConfig(config ? nullptr : tools::make_unique<ProgOptions>())
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
, fConfig(config ? config : fInternalConfig.get())
, fId(DefaultId)
, fDefaultTransportType(DefaultTransportType)
@@ -244,16 +216,6 @@ void FairMQDevice::TransitionTo(const fair::mq::State s)
}
}
bool FairMQDevice::ChangeState(const int transition)
{
return ChangeState(backwardsCompatibilityChangeStateHelper.at(transition));
}
void FairMQDevice::WaitForEndOfState(Transition transition)
{
WaitForState(backwardsCompatibilityWaitForEndOfStateHelper.at(transition));
}
void FairMQDevice::InitWrapper()
{
// run initialization once CompleteInit transition is requested
@@ -390,7 +352,6 @@ void FairMQDevice::AttachChannels(vector<FairMQChannel*>& chans)
if ((*itr)->Validate()) {
(*itr)->Init();
if (AttachChannel(**itr)) {
(*itr)->SetModified(false);
// remove the channel from the uninitialized container
itr = chans.erase(itr);
} else {
@@ -525,7 +486,6 @@ void FairMQDevice::RunWrapper()
}
PostRun();
} catch (const out_of_range& oor) {
LOG(error) << "out of range: " << oor.what();
LOG(error) << "incorrect/incomplete channel configuration?";
@@ -543,17 +503,12 @@ void FairMQDevice::HandleSingleChannelInput()
{
bool proceed = true;
if (fMsgInputs.size() > 0)
{
while (!NewStatePending() && proceed)
{
if (fMsgInputs.size() > 0) {
while (!NewStatePending() && proceed) {
proceed = HandleMsgInput(fInputChannelKeys.at(0), fMsgInputs.begin()->second, 0);
}
}
else if (fMultipartInputs.size() > 0)
{
while (!NewStatePending() && proceed)
{
} else if (fMultipartInputs.size() > 0) {
while (!NewStatePending() && proceed) {
proceed = HandleMultipartInput(fInputChannelKeys.at(0), fMultipartInputs.begin()->second, 0);
}
}
@@ -563,75 +518,55 @@ void FairMQDevice::HandleMultipleChannelInput()
{
// check if more than one transport is used
fMultitransportInputs.clear();
for (const auto& k : fInputChannelKeys)
{
for (const auto& k : fInputChannelKeys) {
fair::mq::Transport t = fChannels.at(k).at(0).fTransportType;
if (fMultitransportInputs.find(t) == fMultitransportInputs.end())
{
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
fMultitransportInputs.insert(pair<fair::mq::Transport, vector<string>>(t, vector<string>()));
fMultitransportInputs.at(t).push_back(k);
}
else
{
} else {
fMultitransportInputs.at(t).push_back(k);
}
}
for (const auto& mi : fMsgInputs)
{
for (auto& i : fChannels.at(mi.first))
{
for (const auto& mi : fMsgInputs) {
for (auto& i : fChannels.at(mi.first)) {
i.fMultipart = false;
}
}
for (const auto& mi : fMultipartInputs)
{
for (auto& i : fChannels.at(mi.first))
{
for (const auto& mi : fMultipartInputs) {
for (auto& i : fChannels.at(mi.first)) {
i.fMultipart = true;
}
}
// if more than one transport is used, handle poll of each in a separate thread
if (fMultitransportInputs.size() > 1)
{
if (fMultitransportInputs.size() > 1) {
HandleMultipleTransportInput();
}
else // otherwise poll directly
{
} else { // otherwise poll directly
bool proceed = true;
FairMQPollerPtr poller(fChannels.at(fInputChannelKeys.at(0)).at(0).fTransportFactory->CreatePoller(fChannels, fInputChannelKeys));
while (!NewStatePending() && proceed)
{
while (!NewStatePending() && proceed) {
poller->Poll(200);
// check which inputs are ready and call their data handlers if they are.
for (const auto& ch : fInputChannelKeys)
{
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i)
{
if (poller->CheckInput(ch, i))
{
if (fChannels.at(ch).at(i).fMultipart)
{
for (const auto& ch : fInputChannelKeys) {
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
if (poller->CheckInput(ch, i)) {
if (fChannels.at(ch).at(i).fMultipart) {
proceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
}
else
{
} else {
proceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
}
if (!proceed)
{
if (!proceed) {
break;
}
}
}
if (!proceed)
{
if (!proceed) {
break;
}
}
@@ -645,64 +580,49 @@ void FairMQDevice::HandleMultipleTransportInput()
fMultitransportProceed = true;
for (const auto& i : fMultitransportInputs)
{
for (const auto& i : fMultitransportInputs) {
threads.emplace_back(thread(&FairMQDevice::PollForTransport, this, fTransports.at(i.first).get(), i.second));
}
for (thread& t : threads)
{
for (thread& t : threads) {
t.join();
}
}
void FairMQDevice::PollForTransport(const FairMQTransportFactory* factory, const vector<string>& channelKeys)
{
try
{
try {
FairMQPollerPtr poller(factory->CreatePoller(fChannels, channelKeys));
while (!NewStatePending() && fMultitransportProceed)
{
while (!NewStatePending() && fMultitransportProceed) {
poller->Poll(500);
for (const auto& ch : channelKeys)
{
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i)
{
if (poller->CheckInput(ch, i))
{
for (const auto& ch : channelKeys) {
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
if (poller->CheckInput(ch, i)) {
lock_guard<mutex> lock(fMultitransportMutex);
if (!fMultitransportProceed)
{
if (!fMultitransportProceed) {
break;
}
if (fChannels.at(ch).at(i).fMultipart)
{
if (fChannels.at(ch).at(i).fMultipart) {
fMultitransportProceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
}
else
{
} else {
fMultitransportProceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
}
if (!fMultitransportProceed)
{
if (!fMultitransportProceed) {
break;
}
}
}
if (!fMultitransportProceed)
{
if (!fMultitransportProceed) {
break;
}
}
}
}
catch (exception& e)
{
} catch (exception& e) {
LOG(error) << "FairMQDevice::PollForTransport() failed: " << e.what() << ", going to ERROR state.";
throw runtime_error(tools::ToString("FairMQDevice::PollForTransport() failed: ", e.what(), ", going to ERROR state."));
}
@@ -712,12 +632,9 @@ bool FairMQDevice::HandleMsgInput(const string& chName, const InputMsgCallback&
{
unique_ptr<FairMQMessage> input(fChannels.at(chName).at(i).fTransportFactory->CreateMessage());
if (Receive(input, chName, i) >= 0)
{
if (Receive(input, chName, i) >= 0) {
return callback(input, i);
}
else
{
} else {
return false;
}
}
@@ -726,12 +643,9 @@ bool FairMQDevice::HandleMultipartInput(const string& chName, const InputMultipa
{
FairMQParts input;
if (Receive(input, chName, i) >= 0)
{
return callback(input, 0);
}
else
{
if (Receive(input, chName, i) >= 0) {
return callback(input, i);
} else {
return false;
}
}

View File

@@ -9,24 +9,23 @@
#ifndef FAIRMQDEVICE_H_
#define FAIRMQDEVICE_H_
#include <StateMachine.h>
#include <FairMQTransportFactory.h>
#include <fairmq/Transports.h>
#include <fairmq/StateQueue.h>
#include <FairMQChannel.h>
#include <FairMQLogger.h>
#include <FairMQMessage.h>
#include <FairMQParts.h>
#include <FairMQTransportFactory.h>
#include <FairMQUnmanagedRegion.h>
#include <FairMQLogger.h>
#include <fairmq/ProgOptions.h>
#include <fairmq/StateMachine.h>
#include <fairmq/StateQueue.h>
#include <fairmq/Transports.h>
#include <fairmq/tools/Version.h>
#include <vector>
#include <memory> // unique_ptr
#include <algorithm> // find
#include <string>
#include <chrono>
#include <iostream>
#include <unordered_map>
#include <functional>
#include <stdexcept>
@@ -35,58 +34,21 @@
#include <cstddef>
#include <utility> // pair
#include <fairmq/tools/Version.h>
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
using InputMsgCallback = std::function<bool(FairMQMessagePtr&, int)>;
using InputMultipartCallback = std::function<bool(FairMQParts&, int)>;
namespace fair
{
namespace mq
namespace fair::mq
{
struct OngoingTransition : std::runtime_error { using std::runtime_error::runtime_error; };
}
}
class FairMQDevice
{
friend class FairMQChannel;
public:
// backwards-compatibility enum for old state machine interface, todo: delete this
enum Event
{
INIT_DEVICE,
internal_DEVICE_READY,
INIT_TASK,
internal_READY,
RUN,
STOP,
RESET_TASK,
RESET_DEVICE,
internal_IDLE,
END,
ERROR_FOUND
};
// backwards-compatibility enum for old state machine interface, todo: delete this
enum State
{
OK,
Error,
IDLE,
INITIALIZING_DEVICE,
DEVICE_READY,
INITIALIZING_TASK,
READY,
RUNNING,
RESETTING_TASK,
RESETTING_DEVICE,
EXITING
};
/// Default constructor
FairMQDevice();
/// Constructor with external fair::mq::ProgOptions
@@ -129,8 +91,8 @@ class FairMQDevice
/// @param chan channel name
/// @param i channel index
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
int Send(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
{
return GetChannel(channel, index).Send(msg, sndTimeoutInMs);
}
@@ -140,8 +102,8 @@ class FairMQDevice
/// @param chan channel name
/// @param i channel index
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
int Receive(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
{
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
}
@@ -151,7 +113,7 @@ class FairMQDevice
/// @param chan channel name
/// @param i channel index
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(FairMQParts& parts, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
{
return GetChannel(channel, index).Send(parts.fParts, sndTimeoutInMs);
@@ -162,7 +124,7 @@ class FairMQDevice
/// @param chan channel name
/// @param i channel index
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(FairMQParts& parts, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
{
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
@@ -217,45 +179,17 @@ class FairMQDevice
}
// creates unamanaged region with the default device transport
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
template<typename... Args>
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
{
return Transport()->CreateUnmanagedRegion(size, callback, path, flags);
}
// creates unamanaged region with the default device transport
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size,
const int64_t userFlags,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
{
return Transport()->CreateUnmanagedRegion(size, userFlags, callback, path, flags);
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
}
// creates unmanaged region with the transport of the specified channel
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel,
int index,
const size_t size,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
template<typename... Args>
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, Args&&... args)
{
return GetChannel(channel, index).NewUnmanagedRegion(size, callback, path, flags);
}
// creates unmanaged region with the transport of the specified channel
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel,
int index,
const size_t size,
const int64_t userFlags,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
{
return GetChannel(channel, index).NewUnmanagedRegion(size, userFlags, callback, path, flags);
return GetChannel(channel, index).NewUnmanagedRegion(std::forward<Args>(args)...);
}
template<typename ...Ts>
@@ -302,7 +236,7 @@ class FairMQDevice
}
/// Adds a transport to the device if it doesn't exist
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
/// @param transport Transport string ("zeromq"/"shmem")
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
/// Assigns config to the device
@@ -391,10 +325,10 @@ class FairMQDevice
void PrintRegisteredChannels()
{
if (fChannelRegistry.size() < 1) {
std::cout << "no channels registered." << std::endl;
LOGV(info, verylow) << "no channels registered.";
} else {
for (const auto& c : fChannelRegistry) {
std::cout << c.first << ":" << c.second.first << ":" << c.second.second << std::endl;
LOGV(info, verylow) << c.first << ":" << c.second.first << ":" << c.second.second;
}
}
}
@@ -417,7 +351,7 @@ class FairMQDevice
int GetInitTimeoutInS() const { return fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout); }
/// Sets the default transport for the device
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
/// @param transport Transport string ("zeromq"/"shmem")
void SetTransport(const std::string& transport) { fConfig->SetProperty("transport", transport); }
/// Gets the default transport name
std::string GetTransportName() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
@@ -478,8 +412,6 @@ class FairMQDevice
/// Called in the RUNNING state once after executing the Run()/ConditionalRun() method
virtual void PostRun() {}
virtual void Pause() __attribute__((deprecated("PAUSE state is removed. This method is never called. To pause Run, go to READY with STOP transition and back to RUNNING with RUN to resume."))) {}
/// Resets the user task (to be overloaded in child classes)
virtual void ResetTask() {}
@@ -487,36 +419,64 @@ class FairMQDevice
virtual void Reset() {}
public:
/// @brief Request a device state transition
/// @param transition state transition
///
/// The state transition may not happen immediately, but when the current state evaluates the
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
/// @brief Request a device state transition
/// @param transition state transition
///
/// The state transition may not happen immediately, but when the current state evaluates the
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::GetTransition(transition)); }
bool ChangeState(const int transition) __attribute__((deprecated("Use ChangeState(const fair::mq::Transition transition).")));
void WaitForEndOfState(const fair::mq::Transition transition) __attribute__((deprecated("Use WaitForState(fair::mq::State expectedState).")));
void WaitForEndOfState(const std::string& transition) __attribute__((deprecated("Use WaitForState(fair::mq::State expectedState)."))) { WaitForState(transition); }
/// @brief waits for the next state (any) to occur
fair::mq::State WaitForNextState() { return fStateQueue.WaitForNext(); }
/// @brief waits for the specified state to occur
/// @param state state to wait for
void WaitForState(fair::mq::State state) { fStateQueue.WaitForState(state); }
/// @brief waits for the specified state to occur
/// @param state state to wait for
void WaitForState(const std::string& state) { WaitForState(fair::mq::GetState(state)); }
void TransitionTo(const fair::mq::State state);
/// @brief Subscribe with a callback to state changes
/// @param key id to identify your subscription
/// @param callback callback (called with the new state as the parameter)
///
/// The callback is called at the beginning of a new state.
/// The callback is called from the thread the state is running in.
void SubscribeToStateChange(const std::string& key, std::function<void(const fair::mq::State)> callback) { fStateMachine.SubscribeToStateChange(key, callback); }
/// @brief Unsubscribe from state changes
/// @param key id (that was used when subscribing)
void UnsubscribeFromStateChange(const std::string& key) { fStateMachine.UnsubscribeFromStateChange(key); }
/// @brief Subscribe with a callback to incoming state transitions
/// @param key id to identify your subscription
/// @param callback callback (called with the incoming transition as the parameter)
/// The callback is called when new transition is initiated.
/// The callback is called from the thread that initiates the transition (via ChangeState).
void SubscribeToNewTransition(const std::string& key, std::function<void(const fair::mq::Transition)> callback) { fStateMachine.SubscribeToNewTransition(key, callback); }
/// @brief Unsubscribe from state transitions
/// @param key id (that was used when subscribing)
void UnsubscribeFromNewTransition(const std::string& key) { fStateMachine.UnsubscribeFromNewTransition(key); }
bool CheckCurrentState(const int /* state */) const __attribute__((deprecated("Use NewStatePending()."))) { return !fStateMachine.NewStatePending(); }
bool CheckCurrentState(const std::string& /* state */) const __attribute__((deprecated("Use NewStatePending()."))) { return !fStateMachine.NewStatePending(); }
/// Returns true is a new state has been requested, signaling the current handler to stop.
/// @brief Returns true if a new state has been requested, signaling the current handler to stop.
bool NewStatePending() const { return fStateMachine.NewStatePending(); }
/// @brief Returns the current state
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
/// @brief Returns the name of the current state as a string
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
/// @brief Returns name of the given state as a string
/// @param state state
static std::string GetStateName(const fair::mq::State state) { return fair::mq::GetStateName(state); }
/// @brief Returns name of the given transition as a string
/// @param transition transition
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::GetTransitionName(transition); }
static constexpr const char* DefaultId = "";

View File

@@ -11,19 +11,34 @@
#include <cstddef> // for size_t
#include <memory> // unique_ptr
#include <stdexcept>
#include <fairmq/Transports.h>
using fairmq_free_fn = void(void* data, void* hint);
class FairMQTransportFactory;
namespace fair::mq
{
struct Alignment
{
size_t alignment;
explicit operator size_t() const { return alignment; }
};
} // namespace fair::mq
class FairMQMessage
{
public:
FairMQMessage() = default;
FairMQMessage(FairMQTransportFactory* factory):fTransport{factory} {}
FairMQMessage(FairMQTransportFactory* factory) : fTransport(factory) {}
virtual void Rebuild() = 0;
virtual void Rebuild(fair::mq::Alignment alignment) = 0;
virtual void Rebuild(const size_t size) = 0;
virtual void Rebuild(const size_t size, fair::mq::Alignment alignment) = 0;
virtual void Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
virtual void* GetData() const = 0;
@@ -33,7 +48,7 @@ class FairMQMessage
virtual fair::mq::Transport GetType() const = 0;
FairMQTransportFactory* GetTransport() { return fTransport; }
//void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
virtual void Copy(const FairMQMessage& msg) = 0;
@@ -45,16 +60,14 @@ class FairMQMessage
using FairMQMessagePtr = std::unique_ptr<FairMQMessage>;
namespace fair
{
namespace mq
namespace fair::mq
{
using Message = FairMQMessage;
using MessagePtr = FairMQMessagePtr;
struct MessageError : std::runtime_error { using std::runtime_error::runtime_error; };
struct MessageBadAlloc : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIRMQMESSAGE_H_ */

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -9,8 +9,9 @@
#ifndef FAIRMQPOLLER_H_
#define FAIRMQPOLLER_H_
#include <string>
#include <memory>
#include <stdexcept>
#include <string>
class FairMQPoller
{
@@ -26,16 +27,13 @@ class FairMQPoller
using FairMQPollerPtr = std::unique_ptr<FairMQPoller>;
namespace fair
{
namespace mq
namespace fair::mq
{
using Poller = FairMQPoller;
using PollerPtr = FairMQPollerPtr;
struct PollerError : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIRMQPOLLER_H_ */

View File

@@ -9,26 +9,42 @@
#ifndef FAIRMQSOCKET_H_
#define FAIRMQSOCKET_H_
#include "FairMQMessage.h"
#include <memory>
#include <ostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <memory>
#include "FairMQMessage.h"
class FairMQTransportFactory;
namespace fair::mq
{
enum class TransferCode : int
{
success = 0,
error = -1,
timeout = -2,
interrupted = -3
};
} // namespace fair::mq
class FairMQSocket
{
public:
FairMQSocket() {}
FairMQSocket(FairMQTransportFactory* fac): fTransport(fac) {}
FairMQSocket(FairMQTransportFactory* fac) : fTransport(fac) {}
virtual std::string GetId() const = 0;
virtual bool Bind(const std::string& address) = 0;
virtual bool Connect(const std::string& address) = 0;
virtual int Send(FairMQMessagePtr& msg, int timeout = -1) = 0;
virtual int Receive(FairMQMessagePtr& msg, int timeout = -1) = 0;
virtual int64_t Send(FairMQMessagePtr& msg, int timeout = -1) = 0;
virtual int64_t Receive(FairMQMessagePtr& msg, int timeout = -1) = 0;
virtual int64_t Send(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
virtual int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
@@ -37,6 +53,10 @@ class FairMQSocket
virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0;
virtual void GetOption(const std::string& option, void* value, size_t* valueSize) = 0;
/// If the backend supports it, fills the unsigned integer @a events with the ZMQ_EVENTS value
/// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in
/// the future.
virtual int Events(uint32_t* events) = 0;
virtual void SetLinger(const int value) = 0;
virtual int GetLinger() const = 0;
virtual void SetSndBufSize(const int value) = 0;
@@ -54,7 +74,7 @@ class FairMQSocket
virtual unsigned long GetMessagesRx() const = 0;
FairMQTransportFactory* GetTransport() { return fTransport; }
void SetTransport(FairMQTransportFactory* transport) { fTransport=transport; }
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
virtual ~FairMQSocket() {};
@@ -64,16 +84,13 @@ class FairMQSocket
using FairMQSocketPtr = std::unique_ptr<FairMQSocket>;
namespace fair
{
namespace mq
namespace fair::mq
{
using Socket = FairMQSocket;
using SocketPtr = FairMQSocketPtr;
struct SocketError : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIRMQSOCKET_H_ */

View File

@@ -8,15 +8,16 @@
#include <FairMQTransportFactory.h>
#include <fairmq/shmem/TransportFactory.h>
#include <zeromq/FairMQTransportFactoryZMQ.h>
#ifdef BUILD_NANOMSG_TRANSPORT
#include <nanomsg/FairMQTransportFactoryNN.h>
#endif /* BUILD_NANOMSG_TRANSPORT */
#include <fairmq/zeromq/TransportFactory.h>
#ifdef BUILD_OFI_TRANSPORT
#include <fairmq/ofi/TransportFactory.h>
#endif
#include <FairMQLogger.h>
#include <fairmq/tools/Unique.h>
#include <fairmq/tools/Strings.h>
#include <fairlogger/Logger.h>
#include <memory>
#include <string>
@@ -39,15 +40,10 @@ auto FairMQTransportFactory::CreateTransportFactory(const string& type,
}
if (type == "zeromq") {
return make_shared<FairMQTransportFactoryZMQ>(finalId, config);
return make_shared<fair::mq::zmq::TransportFactory>(finalId, config);
} else if (type == "shmem") {
return make_shared<fair::mq::shmem::TransportFactory>(finalId, config);
}
#ifdef BUILD_NANOMSG_TRANSPORT
else if (type == "nanomsg") {
return make_shared<FairMQTransportFactoryNN>(finalId, config);
}
#endif /* BUILD_NANOMSG_TRANSPORT */
#ifdef BUILD_OFI_TRANSPORT
else if (type == "ofi") {
return make_shared<fair::mq::ofi::TransportFactory>(finalId, config);
@@ -57,15 +53,12 @@ auto FairMQTransportFactory::CreateTransportFactory(const string& type,
LOG(error) << "Unavailable transport requested: "
<< "\"" << type << "\""
<< ". Available are: "
<< "\"zeromq\""
<< "\"zeromq\","
<< "\"shmem\""
#ifdef BUILD_NANOMSG_TRANSPORT
<< ", \"nanomsg\""
#endif /* BUILD_NANOMSG_TRANSPORT */
#ifdef BUILD_OFI_TRANSPORT
<< ", and \"ofi\""
#endif /* BUILD_OFI_TRANSPORT */
<< ". Exiting.";
exit(EXIT_FAILURE);
throw fair::mq::TransportFactoryError(fair::mq::tools::ToString("Unavailable transport requested: ", type));
}
}

View File

@@ -9,7 +9,6 @@
#ifndef FAIRMQTRANSPORTFACTORY_H_
#define FAIRMQTRANSPORTFACTORY_H_
#include <FairMQLogger.h>
#include <FairMQMessage.h>
#include <FairMQPoller.h>
#include <FairMQSocket.h>
@@ -18,14 +17,14 @@
#include <fairmq/Transports.h>
#include <string>
#include <memory>
#include <memory> // shared_ptr
#include <vector>
#include <unordered_map>
#include <stdexcept>
#include <cstddef> // size_t
class FairMQChannel;
namespace fair { namespace mq { class ProgOptions; } }
namespace fair::mq { class ProgOptions; }
class FairMQTransportFactory
{
@@ -47,13 +46,22 @@ class FairMQTransportFactory
fair::mq::ChannelResource* GetMemoryResource() { return &fMemoryResource; }
operator fair::mq::ChannelResource*() { return &fMemoryResource; }
/// @brief Create empty FairMQMessage
/// @brief Create empty FairMQMessage (for receiving)
/// @return pointer to FairMQMessage
virtual FairMQMessagePtr CreateMessage() = 0;
/// @brief Create empty FairMQMessage (for receiving), align received buffer to specified alignment
/// @param alignment alignment to align received buffer to
/// @return pointer to FairMQMessage
virtual FairMQMessagePtr CreateMessage(fair::mq::Alignment alignment) = 0;
/// @brief Create new FairMQMessage of specified size
/// @param size message size
/// @return pointer to FairMQMessage
virtual FairMQMessagePtr CreateMessage(const size_t size) = 0;
/// @brief Create new FairMQMessage of specified size and alignment
/// @param size message size
/// @param alignment message alignment
/// @return pointer to FairMQMessage
virtual FairMQMessagePtr CreateMessage(const size_t size, fair::mq::Alignment alignment) = 0;
/// @brief Create new FairMQMessage with user provided buffer and size
/// @param data pointer to user provided buffer
/// @param size size of the user provided buffer
@@ -84,7 +92,8 @@ class FairMQTransportFactory
/// @param path optional parameter to pass to the underlying transport
/// @param flags optional parameter to pass to the underlying transport
/// @return pointer to UnmanagedRegion
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
/// @brief Create new UnmanagedRegion
/// @param size size of the region
/// @param userFlags flags to be stored with the region, have no effect on the transport, but can be retrieved from the region by the user
@@ -92,7 +101,8 @@ class FairMQTransportFactory
/// @param path optional parameter to pass to the underlying transport
/// @param flags optional parameter to pass to the underlying transport
/// @return pointer to UnmanagedRegion
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0, fair::mq::RegionConfig cfg = fair::mq::RegionConfig()) = 0;
/// @brief Subscribe to region events (creation, destruction, ...)
/// @param callback the callback that is called when a region event occurs
@@ -161,15 +171,12 @@ class FairMQTransportFactory
}
};
namespace fair
{
namespace mq
namespace fair::mq
{
using TransportFactory = FairMQTransportFactory;
struct TransportFactoryError : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIRMQTRANSPORTFACTORY_H_ */

View File

@@ -10,9 +10,11 @@
#define FAIRMQUNMANAGEDREGION_H_
#include <cstddef> // size_t
#include <cstdint> // uint32_t
#include <memory> // std::unique_ptr
#include <functional> // std::function
#include <ostream> // std::ostream
#include <vector>
class FairMQTransportFactory;
@@ -26,21 +28,24 @@ enum class FairMQRegionEvent : int
struct FairMQRegionInfo
{
FairMQRegionInfo()
: id(0)
: managed(true)
, id(0)
, ptr(nullptr)
, size(0)
, flags(0)
, event(FairMQRegionEvent::created)
{}
FairMQRegionInfo(uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
: id(_id)
FairMQRegionInfo(bool _managed, uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
: managed(_managed)
, id(_id)
, ptr(_ptr)
, size(_size)
, flags(_flags)
, event (_event)
, event(_event)
{}
bool managed; // managed/unmanaged
uint64_t id; // id of the region
void* ptr; // pointer to the start of the region
size_t size; // region size
@@ -48,19 +53,33 @@ struct FairMQRegionInfo
FairMQRegionEvent event;
};
struct FairMQRegionBlock {
void* ptr;
size_t size;
void* hint;
FairMQRegionBlock(void* p, size_t s, void* h)
: ptr(p), size(s), hint(h)
{}
};
using FairMQRegionCallback = std::function<void(void*, size_t, void*)>;
using FairMQRegionBulkCallback = std::function<void(const std::vector<FairMQRegionBlock>&)>;
using FairMQRegionEventCallback = std::function<void(FairMQRegionInfo)>;
class FairMQUnmanagedRegion
{
public:
FairMQUnmanagedRegion() {}
FairMQUnmanagedRegion(FairMQTransportFactory* factory): fTransport(factory) {}
FairMQUnmanagedRegion(FairMQTransportFactory* factory) : fTransport(factory) {}
virtual void* GetData() const = 0;
virtual size_t GetSize() const = 0;
virtual uint64_t GetId() const = 0;
virtual uint16_t GetId() const = 0;
virtual void SetLinger(uint32_t linger) = 0;
virtual uint32_t GetLinger() const = 0;
virtual fair::mq::Transport GetType() const = 0;
FairMQTransportFactory* GetTransport() { return fTransport; }
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
@@ -86,19 +105,31 @@ inline std::ostream& operator<<(std::ostream& os, const FairMQRegionEvent& event
}
}
namespace fair
{
namespace mq
namespace fair::mq
{
struct RegionConfig {
bool lock;
bool zero;
RegionConfig()
: lock(false), zero(false)
{}
RegionConfig(bool l, bool z)
: lock(l), zero(z)
{}
};
using RegionCallback = FairMQRegionCallback;
using RegionBulkCallback = FairMQRegionBulkCallback;
using RegionEventCallback = FairMQRegionEventCallback;
using RegionEvent = FairMQRegionEvent;
using RegionInfo = FairMQRegionInfo;
using RegionBlock = FairMQRegionBlock;
using UnmanagedRegion = FairMQUnmanagedRegion;
using UnmanagedRegionPtr = FairMQUnmanagedRegionPtr;
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIRMQUNMANAGEDREGION_H_ */

View File

@@ -12,25 +12,25 @@
* Created on May 14, 2015, 5:01 PM
*/
#include <fairmq/PropertyOutput.h>
#include "JSONParser.h"
#include "FairMQLogger.h"
#include <fairmq/Tools.h>
#include "FairMQChannel.h"
#include <fairmq/PropertyOutput.h>
#include <fairmq/tools/Strings.h>
#include <fairlogger/Logger.h>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/any.hpp>
#include <ios>
#include <iomanip>
using namespace std;
using namespace fair::mq;
using namespace fair::mq::tools;
using namespace boost::property_tree;
namespace fair
{
namespace mq
namespace fair::mq
{
fair::mq::Properties PtreeParser(const ptree& pt, const string& id)
@@ -183,5 +183,4 @@ void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties
}
} // helper namespace
} // namespace mq
} // namespace fair
} // namespace fair::mq

View File

@@ -15,19 +15,13 @@
#ifndef FAIR_MQ_JSONPARSER_H
#define FAIR_MQ_JSONPARSER_H
#include <string>
#include <vector>
#include <unordered_map>
#include <exception>
#include <fairmq/Properties.h>
#include <boost/property_tree/ptree_fwd.hpp>
#include "FairMQChannel.h"
#include <fairmq/Properties.h>
#include <stdexcept>
#include <string>
namespace fair
{
namespace mq
namespace fair::mq
{
struct ParserError : std::runtime_error { using std::runtime_error::runtime_error; };
@@ -45,7 +39,6 @@ void SubChannelParser(const boost::property_tree::ptree& tree, fair::mq::Propert
} // helper namespace
} // namespace mq
} // namespace fair
} // namespace fair::mq
#endif /* FAIR_MQ_JSONPARSER_H */

View File

@@ -15,8 +15,8 @@
#include <fairmq/FairMQTransportFactory.h>
#include <fairmq/MemoryResources.h>
namespace fair {
namespace mq {
namespace fair::mq
{
using BytePmrAllocator = pmr::polymorphic_allocator<fair::mq::byte>;
@@ -62,5 +62,4 @@ FairMQMessagePtr getMessage(ContainerT &&container_, FairMQMemoryResource *targe
return message;
}
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq

View File

@@ -15,8 +15,7 @@
#include <fairmq/FairMQTransportFactory.h>
#include <fairmq/MemoryResources.h>
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t /*alignment*/)
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t alignment)
{
return setMessage(factory->CreateMessage(bytes));
return setMessage(factory->CreateMessage(bytes, fair::mq::Alignment{alignment}));
}

View File

@@ -15,18 +15,19 @@
#ifndef FAIR_MQ_MEMORY_RESOURCES_H
#define FAIR_MQ_MEMORY_RESOURCES_H
#include <fairmq/FairMQMessage.h>
#include <FairMQMessage.h>
class FairMQTransportFactory;
#include <boost/container/container_fwd.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
#include <cstring>
#include <stdexcept>
#include <utility>
namespace fair {
namespace mq {
namespace fair::mq
{
using byte = unsigned char;
namespace pmr = boost::container::pmr;
@@ -106,7 +107,6 @@ class ChannelResource : public FairMQMemoryResource
};
};
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIR_MQ_MEMORY_RESOURCES_H */

View File

@@ -9,7 +9,6 @@
#ifndef FAIR_MQ_PLUGIN_H
#define FAIR_MQ_PLUGIN_H
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Version.h>
#include <fairmq/PluginServices.h>
@@ -25,9 +24,7 @@
#include <tuple>
#include <utility>
namespace fair
{
namespace mq
namespace fair::mq
{
/**
@@ -134,13 +131,12 @@ class Plugin
PluginServices* fPluginServices;
}; /* class Plugin */
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#define REGISTER_FAIRMQ_PLUGIN(KLASS, NAME, VERSION, MAINTAINER, HOMEPAGE, PROGOPTIONS) \
static auto Make_##NAME##_Plugin(fair::mq::PluginServices* pluginServices) -> std::unique_ptr<fair::mq::Plugin> \
{ \
return fair::mq::tools::make_unique<KLASS>(std::string{#NAME}, VERSION, std::string{MAINTAINER}, std::string{HOMEPAGE}, pluginServices); \
return std::make_unique<KLASS>(std::string{#NAME}, VERSION, std::string{MAINTAINER}, std::string{HOMEPAGE}, pluginServices); \
} \
BOOST_DLL_ALIAS(Make_##NAME##_Plugin, make_##NAME##_plugin) \
BOOST_DLL_ALIAS(PROGOPTIONS, get_##NAME##_plugin_progoptions)

View File

@@ -200,7 +200,19 @@ auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
// Load symbol
if (fPluginFactories.find(pluginName) == fPluginFactories.end()) {
try {
LoadSymbols(pluginName, dll::program_location());
if ("control" == pluginName) {
try {
fPluginProgOptions.insert({pluginName, plugins::ControlPluginProgramOptions().value()});
}
catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
} else if ("config" == pluginName) {
try {
fPluginProgOptions.insert({pluginName, plugins::ConfigPluginProgramOptions().value()});
}
catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
} else {
LoadSymbols(pluginName, dll::program_location());
}
fPluginOrder.push_back(pluginName);
} catch (boost::system::system_error& e) {
throw PluginLoadError(ToString("An error occurred while loading static plugin ", pluginName, ": ", e.what()));
@@ -211,7 +223,13 @@ auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
auto fair::mq::PluginManager::InstantiatePlugin(const string& pluginName) -> void
{
if (fPlugins.find(pluginName) == fPlugins.end()) {
fPlugins[pluginName] = fPluginFactories[pluginName](*fPluginServices);
if ("control" == pluginName) {
fPlugins[pluginName] = plugins::Make_control_Plugin(fPluginServices.get());
} else if ("config" == pluginName) {
fPlugins[pluginName] = plugins::Make_config_Plugin(fPluginServices.get());
} else {
fPlugins[pluginName] = fPluginFactories[pluginName](*fPluginServices);
}
}
}

View File

@@ -11,7 +11,6 @@
#include <fairmq/Plugin.h>
#include <fairmq/PluginServices.h>
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Strings.h>
#define BOOST_FILESYSTEM_VERSION 3
@@ -31,9 +30,7 @@
#include <vector>
#include <utility> // forward
namespace fair
{
namespace mq
namespace fair::mq
{
/**
@@ -80,7 +77,7 @@ class PluginManager
auto ForEachPluginProgOptions(std::function<void (boost::program_options::options_description)> func) const -> void { for(const auto& pair : fPluginProgOptions) { func(pair.second); } }
template<typename... Args>
auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); }
auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = std::make_unique<PluginServices>(std::forward<Args>(args)...); }
auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
@@ -126,7 +123,6 @@ class PluginManager
std::map<std::string, boost::program_options::options_description> fPluginProgOptions;
}; /* class PluginManager */
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIR_MQ_PLUGINMANAGER_H */

View File

@@ -17,17 +17,16 @@
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <condition_variable>
#include <functional>
#include <map>
#include <mutex>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <mutex>
#include <map>
#include <condition_variable>
#include <stdexcept>
#include <vector>
namespace fair
{
namespace mq
namespace fair::mq
{
/**
@@ -280,7 +279,6 @@ class PluginServices
std::condition_variable fReleaseDeviceControlCondition;
}; /* class PluginServices */
} /* namespace mq */
} /* namespace fair */
} // namespace fair::mq
#endif /* FAIR_MQ_PLUGINSERVICES_H */

View File

@@ -39,9 +39,7 @@ struct ValInfo
string origin;
};
namespace fair
{
namespace mq
namespace fair::mq
{
ValInfo ConvertVarValToValInfo(const po::variable_value& v)
@@ -79,7 +77,7 @@ ProgOptions::ProgOptions()
fAllOptions.add_options()
("help,h", "Print help")
("version,v", "Print version")
("severity", po::value<string>()->default_value("debug"), "Log severity level (console): trace, debug, info, state, warn, error, fatal, nolog")
("severity", po::value<string>()->default_value(""), "Log severity level (console): trace, debug, info, state, warn, error, fatal, nolog.")
("file-severity", po::value<string>()->default_value("debug"), "Log severity level (file): trace, debug, info, state, warn, error, fatal, nolog")
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level: veryhigh, high, medium, low")
("color", po::value<bool >()->default_value(true), "Log color (true/false)")
@@ -117,16 +115,24 @@ void ProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUn
// clear the container because it was filled with default values and subsequent calls to store() do not overwrite the existing values
fVarMap.clear();
if (allowUnregistered) {
po::command_line_parser parser(argc, argv);
parser.options(fAllOptions).allow_unregistered();
po::parsed_options parsed = parser.run();
fUnregisteredOptions = po::collect_unrecognized(parsed.options, po::include_positional);
po::store(parsed, fVarMap);
} else {
po::store(po::parse_command_line(argc, argv, fAllOptions), fVarMap);
po::command_line_parser parser(argc, argv);
parser.options(fAllOptions);
if (allowUnregistered) {
parser.allow_unregistered();
}
using namespace po::command_line_style;
style_t style = style_t(allow_short | short_allow_adjacent | short_allow_next | allow_long | long_allow_adjacent | long_allow_next | allow_sticky | allow_dash_for_short);
parser.style(style);
po::parsed_options parsed = parser.run();
fUnregisteredOptions = po::collect_unrecognized(parsed.options, po::include_positional);
po::store(parsed, fVarMap);
}
void ProgOptions::Notify()
@@ -441,6 +447,4 @@ void ProgOptions::PrintOptionsRaw() const
}
}
} // namespace mq
} // namespace fair
} // namespace fair::mq

View File

@@ -26,9 +26,7 @@
#include <vector>
#include <stdexcept>
namespace fair
{
namespace mq
namespace fair::mq
{
struct PropertyNotFoundError : std::runtime_error { using std::runtime_error::runtime_error; };
@@ -270,7 +268,6 @@ class ProgOptions
mutable std::mutex fMtx;
};
} // namespace mq
} // namespace fair
} // namespace fair::mq
#endif /* FAIR_MQ_PROGOPTIONS_H */

View File

@@ -9,13 +9,10 @@
#ifndef FAIR_MQ_PROGOPTIONSFWD_H
#define FAIR_MQ_PROGOPTIONSFWD_H
namespace fair
{
namespace mq
namespace fair::mq
{
class ProgOptions;
}
}
using FairMQProgOptions = fair::mq::ProgOptions;

View File

@@ -7,17 +7,13 @@
********************************************************************************/
#include <fairmq/Properties.h>
#include <fairmq/Tools.h>
#include <boost/filesystem.hpp>
using namespace std;
using namespace fair::mq::tools;
using boost::any_cast;
namespace fair
{
namespace mq
namespace fair::mq
{
template<class T>
@@ -76,9 +72,11 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
{ type_index(typeid(const char*)), [](const Property& p) { return pair<string, string>{ string(any_cast<const char*>(p)), "string" }; } },
{ type_index(typeid(string)), [](const Property& p) { return pair<string, string>{ any_cast<string>(p), "string" }; } },
{ type_index(typeid(int)), [](const Property& p) { return getString<int>(p, "int"); } },
{ type_index(typeid(short)), [](const Property& p) { return getString<short>(p, "short"); } },
{ type_index(typeid(long)), [](const Property& p) { return getString<long>(p, "long"); } },
{ type_index(typeid(long long)), [](const Property& p) { return getString<long long>(p, "long long"); } },
{ type_index(typeid(unsigned)), [](const Property& p) { return getString<unsigned>(p, "unsigned"); } },
{ type_index(typeid(unsigned short)), [](const Property& p) { return getString<unsigned short>(p, "unsigned short"); } },
{ type_index(typeid(unsigned long)), [](const Property& p) { return getString<unsigned long>(p, "unsigned long"); } },
{ type_index(typeid(unsigned long long)), [](const Property& p) { return getString<unsigned long long>(p, "unsigned long long"); } },
{ type_index(typeid(float)), [](const Property& p) { return getStringPair<float>(p, "float"); } },
@@ -92,9 +90,11 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
{ type_index(typeid(vector<unsigned char>)), [](const Property& p) { return getStringPair<vector<unsigned char>>(p, "vector<unsigned char>"); } },
{ type_index(typeid(vector<string>)), [](const Property& p) { return getStringPair<vector<string>>(p, "vector<string>"); } },
{ type_index(typeid(vector<int>)), [](const Property& p) { return getStringPair<vector<int>>(p, "vector<int>"); } },
{ type_index(typeid(vector<short>)), [](const Property& p) { return getStringPair<vector<short>>(p, "vector<short>"); } },
{ type_index(typeid(vector<long>)), [](const Property& p) { return getStringPair<vector<long>>(p, "vector<long>"); } },
{ type_index(typeid(vector<long long>)), [](const Property& p) { return getStringPair<vector<long long>>(p, "vector<long long>"); } },
{ type_index(typeid(vector<unsigned>)), [](const Property& p) { return getStringPair<vector<unsigned>>(p, "vector<unsigned>"); } },
{ type_index(typeid(vector<unsigned short>)), [](const Property& p) { return getStringPair<vector<unsigned short>>(p, "vector<unsigned short>"); } },
{ type_index(typeid(vector<unsigned long>)), [](const Property& p) { return getStringPair<vector<unsigned long>>(p, "vector<unsigned long>"); } },
{ type_index(typeid(vector<unsigned long long>)), [](const Property& p) { return getStringPair<vector<unsigned long long>>(p, "vector<unsigned long long>"); } },
{ type_index(typeid(vector<float>)), [](const Property& p) { return getStringPair<vector<float>>(p, "vector<float>"); } },
@@ -110,9 +110,11 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
{ type_index(typeid(const char*)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, string>(k, string(any_cast<const char*>(p))); } },
{ type_index(typeid(string)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, string>(k, any_cast<string>(p)); } },
{ type_index(typeid(int)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, int>(k, any_cast<int>(p)); } },
{ type_index(typeid(short)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, short>(k, any_cast<short>(p)); } },
{ type_index(typeid(long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long>(k, any_cast<long>(p)); } },
{ type_index(typeid(long long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long long>(k, any_cast<long long>(p)); } },
{ type_index(typeid(unsigned)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned>(k, any_cast<unsigned>(p)); } },
{ type_index(typeid(unsigned short)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned short>(k, any_cast<unsigned short>(p)); } },
{ type_index(typeid(unsigned long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned long>(k, any_cast<unsigned long>(p)); } },
{ type_index(typeid(unsigned long long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned long long>(k, any_cast<unsigned long long>(p)); } },
{ type_index(typeid(float)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, float>(k, any_cast<float>(p)); } },
@@ -126,9 +128,11 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
{ type_index(typeid(vector<unsigned char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned char>>(k, any_cast<vector<unsigned char>>(p)); } },
{ type_index(typeid(vector<string>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<string>>(k, any_cast<vector<string>>(p)); } },
{ type_index(typeid(vector<int>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<int>>(k, any_cast<vector<int>>(p)); } },
{ type_index(typeid(vector<short>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<short>>(k, any_cast<vector<short>>(p)); } },
{ type_index(typeid(vector<long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long>>(k, any_cast<vector<long>>(p)); } },
{ type_index(typeid(vector<long long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long long>>(k, any_cast<vector<long long>>(p)); } },
{ type_index(typeid(vector<unsigned>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned>>(k, any_cast<vector<unsigned>>(p)); } },
{ type_index(typeid(vector<unsigned short>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned short>>(k, any_cast<vector<unsigned short>>(p)); } },
{ type_index(typeid(vector<unsigned long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned long>>(k, any_cast<vector<unsigned long>>(p)); } },
{ type_index(typeid(vector<unsigned long long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned long long>>(k, any_cast<vector<unsigned long long>>(p)); } },
{ type_index(typeid(vector<float>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<float>>(k, any_cast<vector<float>>(p)); } },
@@ -137,5 +141,4 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
{ type_index(typeid(vector<boost::filesystem::path>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<boost::filesystem::path>>(k, any_cast<vector<boost::filesystem::path>>(p)); } },
};
} // namespace mq
} // namespace fair
} // namespace fair::mq

View File

@@ -16,14 +16,13 @@
#include <functional>
#include <map>
#include <unordered_map>
#include <stdexcept>
#include <string>
#include <typeindex>
#include <typeinfo>
#include <utility> // pair
namespace fair
{
namespace mq
namespace fair::mq
{
using Property = boost::any;
@@ -71,7 +70,6 @@ class PropertyHelper
static std::unordered_map<std::type_index, std::function<std::pair<std::string, std::string>(const Property&)>> fTypeInfos;
};
}
}
#endif /* FAIR_MQ_PROPERTIES_H */

View File

@@ -7,7 +7,8 @@
********************************************************************************/
#include <fairmq/StateMachine.h>
#include <fairmq/Tools.h>
#include <fairlogger/Logger.h>
// Increase maximum number of boost::msm states (default is 10)
// This #define has to be before any msm header includes
@@ -34,9 +35,7 @@ using namespace boost::msm::front;
using namespace boost::msm::back;
namespace bmpl = boost::mpl;
namespace fair
{
namespace mq
namespace fair::mq
{
namespace fsm
{
@@ -238,8 +237,7 @@ struct Machine_ : public state_machine_def<Machine_>
using FairMQFSM = state_machine<Machine_>;
} // namespace fsm
} // namespace mq
} // namespace fair
} // namespace fair::mq
using namespace fair::mq::fsm;
using namespace fair::mq;

View File

@@ -11,16 +11,12 @@
#include <fairmq/States.h>
#include <fairlogger/Logger.h>
#include <string>
#include <memory>
#include <functional>
#include <stdexcept>
namespace fair
{
namespace mq
namespace fair::mq
{
class StateMachine
@@ -58,7 +54,6 @@ class StateMachine
std::shared_ptr<void> fFsm;
};
} // namespace mq
} // namespace fair
} // namespace fair::mq
#endif /* FAIRMQSTATEMACHINE_H_ */

View File

@@ -17,9 +17,7 @@
#include <utility> // pair
#include <condition_variable>
namespace fair
{
namespace mq
namespace fair::mq
{
class StateQueue
@@ -88,7 +86,6 @@ class StateQueue
std::condition_variable fCV;
};
} // namespace mq
} // namespace fair
} // namespace fair::mq
#endif /* FAIRMQSTATEQUEUE_H_ */
#endif /* FAIRMQSTATEQUEUE_H_ */

View File

@@ -13,14 +13,13 @@
using namespace std;
namespace fair
{
namespace mq
namespace fair::mq
{
array<string, 15> stateNames =
array<string, 16> stateNames =
{
{
"UNDEFINED",
"OK",
"ERROR",
"IDLE",
@@ -41,6 +40,7 @@ array<string, 15> stateNames =
unordered_map<string, State> states =
{
{ "UNDEFINED", State::Undefined },
{ "OK", State::Ok },
{ "ERROR", State::Error },
{ "IDLE", State::Idle },
@@ -112,5 +112,4 @@ Transition GetTransition(const string& transition)
return transitions.at(transition);
}
} // namespace mq
} // namespace fair
} // namespace fair::mq

View File

@@ -13,13 +13,12 @@
#include <ostream>
#include <stdexcept>
namespace fair
{
namespace mq
namespace fair::mq
{
enum class State : int
{
Undefined = 0,
Ok,
Error,
Idle,
@@ -39,7 +38,7 @@ enum class State : int
enum class Transition : int
{
Auto,
Auto = 0,
InitDevice,
CompleteInit,
Bind,
@@ -63,7 +62,6 @@ struct DeviceErrorState : std::runtime_error { using std::runtime_error::runtime
inline std::ostream& operator<<(std::ostream& os, const State& state) { return os << GetStateName(state); }
inline std::ostream& operator<<(std::ostream& os, const Transition& transition) { return os << GetTransitionName(transition); }
} // namespace mq
} // namespace fair
} // namespace fair::mq
#endif /* FAIRMQSTATES_H_ */

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public License (LGPL) version 3, *
@@ -12,17 +12,19 @@
/// @brief Parser implementation for key-value subopt format
#include <fairmq/SuboptParser.h>
#include <fairmq/JSONParser.h>
#include <fairlogger/Logger.h>
#include <boost/property_tree/ptree.hpp>
#include <string_view>
#include <utility> // make_pair
#include <cstring>
#include <utility> // make_pair
using boost::property_tree::ptree;
using namespace std;
namespace fair
{
namespace mq
namespace fair::mq
{
enum channelOptionKeyIds
@@ -82,7 +84,16 @@ Properties SuboptParser(const vector<string>& channelConfig, const string& devic
string argString(token);
char* subopts = &argString[0];
char* value = nullptr;
// Find either a : or a =. If we find the former first, we consider what is before it
// the channel name
char* firstSep = strpbrk(subopts, ":=");
if (firstSep && *firstSep == ':') {
channelName = std::string_view(subopts, firstSep - subopts);
channelProperties.put("name", channelName);
subopts = firstSep + 1;
}
while (subopts && *subopts != 0 && *subopts != ' ') {
char* cur = subopts;
int subopt = getsubopt(&subopts, (char**)channelOptionKeys, &value);
if (subopt == NAME) {
channelName = value;
@@ -93,6 +104,8 @@ Properties SuboptParser(const vector<string>& channelConfig, const string& devic
socketsArray.push_back(make_pair("", socketProperties));
} else if (subopt >= 0 && value != nullptr) {
channelProperties.put(channelOptionKeys[subopt], value);
} else if (subopt == -1) {
LOG(warn) << "Ignoring unknown argument in --channel-config: " << cur;
}
}
@@ -117,4 +130,3 @@ Properties SuboptParser(const vector<string>& channelConfig, const string& devic
}
}
}

View File

@@ -14,14 +14,12 @@
#ifndef FAIR_MQ_SUBOPTPARSER_H
#define FAIR_MQ_SUBOPTPARSER_H
#include <fairmq/JSONParser.h>
#include <fairmq/Properties.h>
#include <vector>
#include <string>
namespace fair
{
namespace mq
namespace fair::mq
{
/**
@@ -43,7 +41,6 @@ namespace mq
Properties SuboptParser(const std::vector<std::string>& channelConfig, const std::string& deviceId);
}
}
#endif /* FAIR_MQ_SUBOPTPARSER_H */

View File

@@ -9,46 +9,35 @@
#ifndef FAIR_MQ_TRANSPORTS_H
#define FAIR_MQ_TRANSPORTS_H
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Strings.h>
#include <memory>
#include <ostream>
#include <stdexcept>
#include <string>
#include <unordered_map>
namespace fair
{
namespace mq
namespace fair::mq
{
enum class Transport
{
DEFAULT,
ZMQ,
NN,
SHM,
OFI
};
} /* namespace mq */
} /* namespace fair */
struct TransportError : std::runtime_error { using std::runtime_error::runtime_error; };
namespace std
{
} // namespace fair::mq
template<>
struct hash<fair::mq::Transport> : fair::mq::tools::HashEnum<fair::mq::Transport> {};
} /* namespace std */
namespace fair
{
namespace mq
namespace fair::mq
{
static std::unordered_map<std::string, Transport> TransportTypes {
{ "default", Transport::DEFAULT },
{ "zeromq", Transport::ZMQ },
{ "nanomsg", Transport::NN },
{ "shmem", Transport::SHM },
{ "ofi", Transport::OFI }
};
@@ -56,12 +45,27 @@ static std::unordered_map<std::string, Transport> TransportTypes {
static std::unordered_map<Transport, std::string> TransportNames {
{ Transport::DEFAULT, "default" },
{ Transport::ZMQ, "zeromq" },
{ Transport::NN, "nanomsg" },
{ Transport::SHM, "shmem" },
{ Transport::OFI, "ofi" }
};
} /* namespace mq */
} /* namespace fair */
inline std::string TransportName(Transport transport)
{
return TransportNames[transport];
}
inline Transport TransportType(const std::string& transport)
try {
return TransportTypes.at(transport);
} catch (std::out_of_range&) {
throw TransportError(tools::ToString("Unknown transport provided: ", transport));
}
inline std::ostream& operator<<(std::ostream& os, const Transport& transport)
{
return os << TransportName(transport);
}
} // namespace fair::mq
#endif /* FAIR_MQ_TRANSPORTS_H */

View File

@@ -21,7 +21,7 @@
#define FAIRMQ_GIT_DATE "@PROJECT_GIT_DATE@"
#define FAIRMQ_REPO_URL "https://github.com/FairRootGroup/FairMQ"
#define FAIRMQ_LICENSE "LGPL-3.0"
#define FAIRMQ_COPYRIGHT "2012-2020 GSI"
#define FAIRMQ_COPYRIGHT "2012-2021 GSI"
#define FAIRMQ_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#endif // FAIR_MQ_VERSION_H

View File

@@ -0,0 +1,125 @@
/********************************************************************************
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_BENCHMARKSAMPLER_H
#define FAIR_MQ_BENCHMARKSAMPLER_H
#include <fairmq/Device.h>
#include <fairmq/tools/RateLimit.h>
#include <chrono>
#include <cstddef> // size_t
#include <cstdint> // uint64_t
#include <cstring> // memset
#include <fairlogger/Logger.h>
#include <string>
namespace fair::mq
{
/**
* Sampler to generate traffic for benchmarking.
*/
class BenchmarkSampler : public Device
{
public:
BenchmarkSampler()
: fMultipart(false)
, fMemSet(false)
, fNumParts(1)
, fMsgSize(10000)
, fMsgAlignment(0)
, fMsgRate(0)
, fNumIterations(0)
, fMaxIterations(0)
, fOutChannelName()
{}
void InitTask() override
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fMemSet = fConfig->GetProperty<bool>("memset");
fNumParts = fConfig->GetProperty<size_t>("num-parts");
fMsgSize = fConfig->GetProperty<size_t>("msg-size");
fMsgAlignment = fConfig->GetProperty<size_t>("msg-alignment");
fMsgRate = fConfig->GetProperty<float>("msg-rate");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fOutChannelName = fConfig->GetProperty<std::string>("out-channel");
}
void Run() override
{
// store the channel reference to avoid traversing the map on every loop iteration
FairMQChannel& dataOutChannel = fChannels.at(fOutChannelName).at(0);
LOG(info) << "Starting the benchmark with message size of " << fMsgSize << " and " << fMaxIterations << " iterations.";
auto tStart = std::chrono::high_resolution_clock::now();
fair::mq::tools::RateLimiter rateLimiter(fMsgRate);
while (!NewStatePending()) {
if (fMultipart) {
FairMQParts parts;
for (size_t i = 0; i < fNumParts; ++i) {
parts.AddPart(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment}));
if (fMemSet) {
std::memset(parts.At(i)->GetData(), 0, parts.At(i)->GetSize());
}
}
if (dataOutChannel.Send(parts) >= 0) {
if (fMaxIterations > 0) {
if (fNumIterations >= fMaxIterations) {
break;
}
}
++fNumIterations;
}
} else {
FairMQMessagePtr msg(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment}));
if (fMemSet) {
std::memset(msg->GetData(), 0, msg->GetSize());
}
if (dataOutChannel.Send(msg) >= 0) {
if (fMaxIterations > 0) {
if (fNumIterations >= fMaxIterations) {
break;
}
}
++fNumIterations;
}
}
if (fMsgRate > 0) {
rateLimiter.maybe_sleep();
}
}
auto tEnd = std::chrono::high_resolution_clock::now();
LOG(info) << "Done " << fNumIterations << " iterations in " << std::chrono::duration<double, std::milli>(tEnd - tStart).count() << "ms.";
}
protected:
bool fMultipart;
bool fMemSet;
size_t fNumParts;
size_t fMsgSize;
size_t fMsgAlignment;
float fMsgRate;
uint64_t fNumIterations;
uint64_t fMaxIterations;
std::string fOutChannelName;
};
} // namespace fair::mq
#endif /* FAIR_MQ_BENCHMARKSAMPLER_H */

View File

@@ -1,100 +0,0 @@
/********************************************************************************
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "FairMQBenchmarkSampler.h"
#include "tools/RateLimit.h"
#include "../FairMQLogger.h"
#include <chrono>
using namespace std;
FairMQBenchmarkSampler::FairMQBenchmarkSampler()
: fMultipart(false)
, fNumParts(1)
, fMsgSize(10000)
, fMsgRate(0)
, fNumIterations(0)
, fMaxIterations(0)
, fOutChannelName()
{
}
void FairMQBenchmarkSampler::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fNumParts = fConfig->GetProperty<size_t>("num-parts");
fMsgSize = fConfig->GetProperty<size_t>("msg-size");
fMsgRate = fConfig->GetProperty<float>("msg-rate");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fOutChannelName = fConfig->GetProperty<string>("out-channel");
}
void FairMQBenchmarkSampler::Run()
{
// store the channel reference to avoid traversing the map on every loop iteration
FairMQChannel& dataOutChannel = fChannels.at(fOutChannelName).at(0);
FairMQMessagePtr baseMsg(dataOutChannel.NewMessage(fMsgSize));
LOG(info) << "Starting the benchmark with message size of " << fMsgSize << " and " << fMaxIterations << " iterations.";
auto tStart = chrono::high_resolution_clock::now();
fair::mq::tools::RateLimiter rateLimiter(fMsgRate);
while (!NewStatePending())
{
if (fMultipart)
{
FairMQParts parts;
for (size_t i = 0; i < fNumParts; ++i)
{
parts.AddPart(dataOutChannel.NewMessage(fMsgSize));
}
if (dataOutChannel.Send(parts) >= 0)
{
if (fMaxIterations > 0)
{
if (fNumIterations >= fMaxIterations)
{
break;
}
}
++fNumIterations;
}
}
else
{
FairMQMessagePtr msg(dataOutChannel.NewMessage(fMsgSize));
if (dataOutChannel.Send(msg) >= 0)
{
if (fMaxIterations > 0)
{
if (fNumIterations >= fMaxIterations)
{
break;
}
}
++fNumIterations;
}
}
if (fMsgRate > 0)
{
rateLimiter.maybe_sleep();
}
}
auto tEnd = chrono::high_resolution_clock::now();
LOG(info) << "Done " << fNumIterations << " iterations in " << chrono::duration<double, milli>(tEnd - tStart).count() << "ms.";
}

View File

@@ -1,44 +0,0 @@
/********************************************************************************
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIRMQBENCHMARKSAMPLER_H_
#define FAIRMQBENCHMARKSAMPLER_H_
#include <string>
#include <atomic>
#include <cstddef> // size_t
#include <cstdint> // uint64_t
#include "FairMQDevice.h"
/**
* Sampler to generate traffic for benchmarking.
*/
class FairMQBenchmarkSampler : public FairMQDevice
{
public:
FairMQBenchmarkSampler();
virtual ~FairMQBenchmarkSampler() {}
protected:
bool fMultipart;
size_t fNumParts;
size_t fMsgSize;
std::atomic<int> fMsgCounter;
float fMsgRate;
uint64_t fNumIterations;
uint64_t fMaxIterations;
std::string fOutChannelName;
virtual void InitTask() override;
virtual void Run() override;
};
#endif /* FAIRMQBENCHMARKSAMPLER_H_ */

View File

@@ -1,122 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQMerger.cxx
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#include "FairMQMerger.h"
#include "../FairMQLogger.h"
#include "../FairMQPoller.h"
using namespace std;
FairMQMerger::FairMQMerger()
: fMultipart(true)
, fInChannelName("data-in")
, fOutChannelName("data-out")
{
}
void FairMQMerger::RegisterChannelEndpoints()
{
RegisterChannelEndpoint(fInChannelName, 1, 10000);
RegisterChannelEndpoint(fOutChannelName, 1, 1);
PrintRegisteredChannels();
}
FairMQMerger::~FairMQMerger()
{
}
void FairMQMerger::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<string>("in-channel");
fOutChannelName = fConfig->GetProperty<string>("out-channel");
}
void FairMQMerger::Run()
{
int numInputs = fChannels.at(fInChannelName).size();
vector<FairMQChannel*> chans;
for (auto& chan : fChannels.at(fInChannelName))
{
chans.push_back(&chan);
}
FairMQPollerPtr poller(NewPoller(chans));
if (fMultipart)
{
while (!NewStatePending())
{
poller->Poll(100);
// Loop over the data input channels.
for (int i = 0; i < numInputs; ++i)
{
// Check if the channel has data ready to be received.
if (poller->CheckInput(i))
{
FairMQParts payload;
if (Receive(payload, fInChannelName, i) >= 0)
{
if (Send(payload, fOutChannelName) < 0)
{
LOG(debug) << "Transfer interrupted";
break;
}
}
else
{
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}
}
else
{
while (!NewStatePending())
{
poller->Poll(100);
// Loop over the data input channels.
for (int i = 0; i < numInputs; ++i)
{
// Check if the channel has data ready to be received.
if (poller->CheckInput(i))
{
FairMQMessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName, i) >= 0)
{
if (Send(payload, fOutChannelName) < 0)
{
LOG(debug) << "Transfer interrupted";
break;
}
}
else
{
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}
}
}

View File

@@ -1,38 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQMerger.h
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#ifndef FAIRMQMERGER_H_
#define FAIRMQMERGER_H_
#include "FairMQDevice.h"
#include <string>
class FairMQMerger : public FairMQDevice
{
public:
FairMQMerger();
virtual ~FairMQMerger();
protected:
bool fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
virtual void RegisterChannelEndpoints() override;
virtual void Run() override;
virtual void InitTask() override;
};
#endif /* FAIRMQMERGER_H_ */

View File

@@ -1,110 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "FairMQMultiplier.h"
#include "../FairMQLogger.h"
using namespace std;
FairMQMultiplier::FairMQMultiplier()
: fMultipart(true)
, fNumOutputs(0)
, fInChannelName()
, fOutChannelNames()
{
}
FairMQMultiplier::~FairMQMultiplier()
{
}
void FairMQMultiplier::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<string>("in-channel");
fOutChannelNames = fConfig->GetProperty<vector<string>>("out-channel");
fNumOutputs = fChannels.at(fOutChannelNames.at(0)).size();
if (fMultipart)
{
OnData(fInChannelName, &FairMQMultiplier::HandleMultipartData);
}
else
{
OnData(fInChannelName, &FairMQMultiplier::HandleSingleData);
}
}
bool FairMQMultiplier::HandleSingleData(std::unique_ptr<FairMQMessage>& payload, int /*index*/)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) // all except last channel
{
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) // all subChannels in a channel
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) // iterate over all except last subChannels of the last channel
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}
bool FairMQMultiplier::HandleMultipartData(FairMQParts& payload, int /*index*/)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) // all except last channel
{
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) // all subChannels in a channel
{
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k)
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy));
}
Send(parts, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) // iterate over all except last subChannels of the last channel
{
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k)
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy));
}
Send(parts, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}

View File

@@ -1,34 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIRMQMULTIPLIER_H_
#define FAIRMQMULTIPLIER_H_
#include "FairMQDevice.h"
#include <string>
class FairMQMultiplier : public FairMQDevice
{
public:
FairMQMultiplier();
virtual ~FairMQMultiplier();
protected:
bool fMultipart;
int fNumOutputs;
std::string fInChannelName;
std::vector<std::string> fOutChannelNames;
virtual void InitTask();
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
bool HandleMultipartData(FairMQParts&, int);
};
#endif /* FAIRMQMULTIPLIER_H_ */

View File

@@ -1,81 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQProxy.cxx
*
* @since 2013-10-02
* @author A. Rybalchenko
*/
#include "FairMQProxy.h"
#include "../FairMQLogger.h"
using namespace std;
FairMQProxy::FairMQProxy()
: fMultipart(true)
, fInChannelName()
, fOutChannelName()
{
}
FairMQProxy::~FairMQProxy()
{
}
void FairMQProxy::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<string>("in-channel");
fOutChannelName = fConfig->GetProperty<string>("out-channel");
}
void FairMQProxy::Run()
{
if (fMultipart)
{
while (!NewStatePending())
{
FairMQParts payload;
if (Receive(payload, fInChannelName) >= 0)
{
if (Send(payload, fOutChannelName) < 0)
{
LOG(debug) << "Transfer interrupted";
break;
}
}
else
{
LOG(debug) << "Transfer interrupted";
break;
}
}
}
else
{
while (!NewStatePending())
{
unique_ptr<FairMQMessage> payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName) >= 0)
{
if (Send(payload, fOutChannelName) < 0)
{
LOG(debug) << "Transfer interrupted";
break;
}
}
else
{
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}

View File

@@ -1,37 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQProxy.h
*
* @since 2013-10-02
* @author A. Rybalchenko
*/
#ifndef FAIRMQPROXY_H_
#define FAIRMQPROXY_H_
#include "FairMQDevice.h"
#include <string>
class FairMQProxy : public FairMQDevice
{
public:
FairMQProxy();
virtual ~FairMQProxy();
protected:
bool fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
virtual void Run();
virtual void InitTask();
};
#endif /* FAIRMQPROXY_H_ */

View File

@@ -1,103 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQSink.h
*
* @since 2013-01-09
* @author D. Klein, A. Rybalchenko
*/
#ifndef FAIRMQSINK_H_
#define FAIRMQSINK_H_
#include <string>
#include <chrono>
#include "../FairMQDevice.h"
#include "../FairMQLogger.h"
// template<typename OutputPolicy>
class FairMQSink : public FairMQDevice//, public OutputPolicy
{
public:
FairMQSink()
: fMultipart(false)
, fMaxIterations(0)
, fNumIterations(0)
, fInChannelName()
{}
virtual ~FairMQSink()
{}
protected:
bool fMultipart;
uint64_t fMaxIterations;
uint64_t fNumIterations;
std::string fInChannelName;
virtual void InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fInChannelName = fConfig->GetProperty<std::string>("in-channel");
}
virtual void Run()
{
// store the channel reference to avoid traversing the map on every loop iteration
FairMQChannel& dataInChannel = fChannels.at(fInChannelName).at(0);
LOG(info) << "Starting the benchmark and expecting to receive " << fMaxIterations << " messages.";
auto tStart = std::chrono::high_resolution_clock::now();
while (!NewStatePending())
{
if (fMultipart)
{
FairMQParts parts;
if (dataInChannel.Receive(parts) >= 0)
{
if (fMaxIterations > 0)
{
if (fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached.";
break;
}
}
fNumIterations++;
}
}
else
{
FairMQMessagePtr msg(dataInChannel.NewMessage());
if (dataInChannel.Receive(msg) >= 0)
{
if (fMaxIterations > 0)
{
if (fNumIterations >= fMaxIterations)
{
LOG(info) << "Configured maximum number of iterations reached.";
break;
}
}
fNumIterations++;
}
}
}
auto tEnd = std::chrono::high_resolution_clock::now();
LOG(info) << "Leaving RUNNING state. Received " << fNumIterations << " messages in " << std::chrono::duration<double, std::milli>(tEnd - tStart).count() << "ms.";
}
};
#endif /* FAIRMQSINK_H_ */

View File

@@ -1,74 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQSplitter.cxx
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#include "FairMQSplitter.h"
#include "../FairMQLogger.h"
using namespace std;
FairMQSplitter::FairMQSplitter()
: fMultipart(true)
, fNumOutputs(0)
, fDirection(0)
, fInChannelName()
, fOutChannelName()
{
}
FairMQSplitter::~FairMQSplitter()
{
}
void FairMQSplitter::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<string>("in-channel");
fOutChannelName = fConfig->GetProperty<string>("out-channel");
fNumOutputs = fChannels.at(fOutChannelName).size();
fDirection = 0;
if (fMultipart)
{
OnData(fInChannelName, &FairMQSplitter::HandleMultipartData);
}
else
{
OnData(fInChannelName, &FairMQSplitter::HandleSingleData);
}
}
bool FairMQSplitter::HandleSingleData(FairMQMessagePtr& payload, int /*index*/)
{
Send(payload, fOutChannelName, fDirection);
if (++fDirection >= fNumOutputs)
{
fDirection = 0;
}
return true;
}
bool FairMQSplitter::HandleMultipartData(FairMQParts& payload, int /*index*/)
{
Send(payload, fOutChannelName, fDirection);
if (++fDirection >= fNumOutputs)
{
fDirection = 0;
}
return true;
}

View File

@@ -1,41 +0,0 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/**
* FairMQSplitter.h
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#ifndef FAIRMQSPLITTER_H_
#define FAIRMQSPLITTER_H_
#include "FairMQDevice.h"
#include <string>
class FairMQSplitter : public FairMQDevice
{
public:
FairMQSplitter();
virtual ~FairMQSplitter();
protected:
bool fMultipart;
int fNumOutputs;
int fDirection;
std::string fInChannelName;
std::string fOutChannelName;
virtual void InitTask();
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
bool HandleMultipartData(FairMQParts&, int);
};
#endif /* FAIRMQSPLITTER_H_ */

113
fairmq/devices/Merger.h Normal file
View File

@@ -0,0 +1,113 @@
/********************************************************************************
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_MERGER_H
#define FAIR_MQ_MERGER_H
#include <FairMQPoller.h>
#include <fairmq/Device.h>
#include <fairlogger/Logger.h>
#include <string>
#include <vector>
namespace fair::mq
{
class Merger : public Device
{
public:
Merger()
: fMultipart(true)
, fInChannelName("data-in")
, fOutChannelName("data-out")
{}
protected:
bool fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
void InitTask() override
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<std::string>("in-channel");
fOutChannelName = fConfig->GetProperty<std::string>("out-channel");
}
void RegisterChannelEndpoints() override
{
RegisterChannelEndpoint(fInChannelName, 1, 10000);
RegisterChannelEndpoint(fOutChannelName, 1, 1);
PrintRegisteredChannels();
}
void Run() override
{
int numInputs = fChannels.at(fInChannelName).size();
std::vector<FairMQChannel*> chans;
for (auto& chan : fChannels.at(fInChannelName)) {
chans.push_back(&chan);
}
FairMQPollerPtr poller(NewPoller(chans));
if (fMultipart) {
while (!NewStatePending()) {
poller->Poll(100);
// Loop over the data input channels.
for (int i = 0; i < numInputs; ++i) {
// Check if the channel has data ready to be received.
if (poller->CheckInput(i)) {
FairMQParts payload;
if (Receive(payload, fInChannelName, i) >= 0) {
if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted";
break;
}
} else {
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}
} else {
while (!NewStatePending()) {
poller->Poll(100);
// Loop over the data input channels.
for (int i = 0; i < numInputs; ++i) {
// Check if the channel has data ready to be received.
if (poller->CheckInput(i)) {
FairMQMessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName, i) >= 0) {
if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted";
break;
}
} else {
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}
}
}
};
} // namespace fair::mq
#endif /* FAIR_MQ_MERGER_H */

114
fairmq/devices/Multiplier.h Normal file
View File

@@ -0,0 +1,114 @@
/********************************************************************************
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_MULTIPLIER_H
#define FAIR_MQ_MULTIPLIER_H
#include <fairmq/Device.h>
#include <string>
#include <vector>
namespace fair::mq
{
class Multiplier : public Device
{
public:
Multiplier()
: fMultipart(true)
, fNumOutputs(0)
, fInChannelName()
, fOutChannelNames()
{}
protected:
bool fMultipart;
int fNumOutputs;
std::string fInChannelName;
std::vector<std::string> fOutChannelNames;
void InitTask() override
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<std::string>("in-channel");
fOutChannelNames = fConfig->GetProperty<std::vector<std::string>>("out-channel");
fNumOutputs = fChannels.at(fOutChannelNames.at(0)).size();
if (fMultipart) {
OnData(fInChannelName, &Multiplier::HandleMultipartData);
} else {
OnData(fInChannelName, &Multiplier::HandleSingleData);
}
}
bool HandleSingleData(std::unique_ptr<FairMQMessage>& payload, int)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) { // all subChannels in a channel
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}
bool HandleMultipartData(FairMQParts& payload, int)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) { // all subChannels in a channel
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k) {
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy));
}
Send(parts, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k) {
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy));
}
Send(parts, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}
};
} // namespace fair::mq
#endif /* FAIR_MQ_MULTIPLIER_H */

74
fairmq/devices/Proxy.h Normal file
View File

@@ -0,0 +1,74 @@
/********************************************************************************
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_PROXY_H
#define FAIR_MQ_PROXY_H
#include <fairmq/Device.h>
#include <string>
namespace fair::mq
{
class Proxy : public Device
{
public:
Proxy()
: fMultipart(true)
, fInChannelName()
, fOutChannelName()
{}
protected:
bool fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
void InitTask() override
{
fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<std::string>("in-channel");
fOutChannelName = fConfig->GetProperty<std::string>("out-channel");
}
void Run() override
{
if (fMultipart) {
while (!NewStatePending()) {
FairMQParts payload;
if (Receive(payload, fInChannelName) >= 0) {
if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted";
break;
}
} else {
LOG(debug) << "Transfer interrupted";
break;
}
}
} else {
while (!NewStatePending()) {
FairMQMessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName) >= 0) {
if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted";
break;
}
} else {
LOG(debug) << "Transfer interrupted";
break;
}
}
}
}
};
} // namespace fair::mq
#endif /* FAIR_MQ_PROXY_H */

View File

@@ -2,9 +2,9 @@
With FairMQ several generic devices are provided:
- **FairMQBenchmarkSampler**: generates random data of configurable size and at configurable rate and sends it out on an output channel.
- **FairMQSink**: receives messages on the input channel and simply discards them.
- **FairMQMerger**: receives data from multiple input channels and forwards it to a single output channel.
- **FairMQSplitter**: receives messages on a single input channels and round-robins them among multiple output channels (which can have different socket types).
- **FairMQMultiplier**: receives data from a single input channel and multiplies (copies) it to two or more output channels.
- **FairMQProxy**: connects input channel to output channel, where both can have different socket types and multiple peers.
- **BenchmarkSampler**: generates random data of configurable size and at configurable rate and sends it out on an output channel.
- **Sink**: receives messages on the input channel and simply discards them.
- **Merger**: receives data from multiple input channels and forwards it to a single output channel.
- **Splitter**: receives messages on a single input channels and round-robins them among multiple output channels (which can have different socket types).
- **Multiplier**: receives data from a single input channel and multiplies (copies) it to two or more output channels.
- **Proxy**: connects input channel to output channel, where both can have different socket types and multiple peers.

Some files were not shown because too many files have changed in this diff Show More