Compare commits

...

173 Commits

Author SHA1 Message Date
Alexey Rybalchenko
8cfc04721e Add unit tests for regions 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
e9318dd234 Add FairMQTransportFactory::GetId() 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
c8fc5ad33f Add bool FairMQTransportFactory::SubscribedToRegionEvents() 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
59e32437a2 shmem region subscriptions: fix race condition 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
a3afadb824 Call region event callback with local_only event for zmq 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
9992811822 Implement region events for zmq 2020-05-11 12:02:19 +02:00
Alexey Rybalchenko
4218c185a4 Shmem: Send acks also for local regions 2020-05-04 10:01:29 +02:00
Alexey Rybalchenko
5a49c5b9b1 Truncate the file used for the region mapping 2020-05-04 10:01:29 +02:00
Alexey Rybalchenko
960b612d80 Update docs 2020-04-28 14:47:26 +02:00
Alexey Rybalchenko
e1a113aabe Add region events subscriptions 2020-04-28 14:09:04 +02:00
Alexey Rybalchenko
5721ea9510 SDK: send heartbeats when subscribed to state changes 2020-04-10 18:40:14 +02:00
Alexey Rybalchenko
330687772f Add SubscriptionHeartbeat command 2020-04-10 18:40:14 +02:00
Alexey Rybalchenko
7cbd154344 PMIx plugin: Fix Commands API usage 2020-04-07 14:44:51 +02:00
Alexey Rybalchenko
036561ab38 SDK: track state change (un-)subscriptions 2020-04-07 14:44:51 +02:00
Alexey Rybalchenko
274ba5ec00 Commands: Add task id to subscription status cmds 2020-04-07 14:44:51 +02:00
Alexey Rybalchenko
c5efd3e4a6 SDK: minor refactoring of the command handling 2020-04-07 14:44:51 +02:00
Alexey Rybalchenko
0a5820c07f Fix Typo 2020-04-06 18:42:34 +02:00
Dennis Klein
5788daa410 Plugin manager: extent lifetime of DLLs 2020-04-06 18:42:34 +02:00
Alexey Rybalchenko
46014118f0 QC ex: rename qc devices, granular state control 2020-03-30 13:14:12 +02:00
Alexey Rybalchenko
adc4688f9b DDSCommandUI: include path argument in ChangeState 2020-03-30 13:14:12 +02:00
Alexey Rybalchenko
c3127f22e5 SDK: refactor subscription to allow reuse 2020-03-30 13:14:12 +02:00
Alexey Rybalchenko
926ee743ed DDS plugin: refactor for better readability 2020-03-25 09:53:22 +01:00
Alexey Rybalchenko
c7b1304a2c DDS plugin: Update property instead of set to avoid errors 2020-03-25 09:53:22 +01:00
Alexey Rybalchenko
32764e1b12 DDS plugin: refactor for better readability 2020-03-25 09:53:22 +01:00
Alexey Rybalchenko
96348b8462 DDS plugin: improve error message on unexpected update 2020-03-25 09:53:22 +01:00
Alexey Rybalchenko
cd83efadea DDS plugin: refactor to load DDS task id only once 2020-03-25 09:53:22 +01:00
Alexey Rybalchenko
38eb9d22e4 Shmem: more detailed errors on meta data mismatch 2020-03-24 04:07:58 +01:00
Alexey Rybalchenko
a20ac7af08 SDK: Refactor StateChangeOp and add path parameter 2020-03-24 04:07:58 +01:00
Alexey Rybalchenko
24aabdb854 Add example and test of a n-to-m topology, incuding sub-channel use 2020-03-11 14:51:19 +01:00
Alexey Rybalchenko
539b088ade DDS Plugin: Simplify subchannel bookkeeping 2020-03-11 14:51:19 +01:00
Alexey Rybalchenko
b05782af16 CMake: Reformat 2020-03-11 14:51:19 +01:00
Alexey Rybalchenko
3a8f34efaa Example.QC: Add README 2020-03-11 14:51:19 +01:00
Dennis Klein
8160edfd04 Silence -Wunused-parameter 2020-03-10 14:30:23 +01:00
Dennis Klein
3d4cd02812 Allow undefining LOG macro with FairLogger v1.6.2+
Resolves #244
2020-03-10 14:30:23 +01:00
Alexey Rybalchenko
0ae53fd7d9 Throw an error if shmem receives invalid meta data 2020-03-09 14:09:29 +01:00
Alexey Rybalchenko
a545bee3b1 Do not report interruption by system call as error 2020-03-02 13:42:37 +01:00
Alexey Rybalchenko
f00519b99b PMIx plugin: adapt to updated commands format 2020-02-24 14:41:47 +01:00
Alexey Rybalchenko
41fc27d504 SDK: Update docs 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
811d1b8973 Update examples readme 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
ced67d8952 DDS Command UI: remove direct DDS dependency 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
8123a6ecab QC example: add setting of the property, test if its successful 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
beff0af51b DDS plugin: fix exiting timeout 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
21835cc104 Revert the session renaming 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
334d81a1ab SDK: Unsubscribe in the Topology destructor 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
c1719eb285 SDK Commands: remove heartbeat commands 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
fcd1022997 Add session id to DDS commands in dds/qc examples 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
e221242f9a Use SDK in dds-command-ui 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
e853d121bf SDK: Add garbage collection for completed ops 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
14d6d717a3 Add qc example 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
119cbe37f1 SDK: Add WaitForState() 2020-02-21 18:37:33 +01:00
Alexey Rybalchenko
0e72a9bf54 SDK::DDSSession: remove channel id to task id association 2020-02-21 18:37:33 +01:00
Dennis Klein
3785fd9ff9 SDK: Support DYLD_LIBRARY_PATH from parent env in sdk::DDSEnv
Fixes #235
2020-02-17 19:18:00 +01:00
Dennis Klein
278cd62049 Fix ODR violations for unity builds 2020-02-08 18:58:23 +01:00
Dennis Klein
6c63b01cfe Commands: Add [so]version to and rename installed lib 2020-02-06 15:51:22 +01:00
Andrey Lebedev
66acde2a69 Example.DDS: Fix env script for macOS
- For macOS append Boost_LIBRARY_DIRS to DYLD_LIBRARY_PATH and export DYLD_LIBRARY_PATH in the fairmq-ex-dds-env.sh
- Update CONTRIBUTORS list
2020-01-31 20:45:02 +01:00
Dennis Klein
19ab8bba3b SDK: One more test 2020-01-27 20:50:11 +01:00
Dennis Klein
be524d838a SDK: Add inline docs 2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
92af823135 SDK: Allow passing path to Set/GetProperties 2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
50dacbcdde SDK: update DDSTopology::GetTasks() 2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
264a178424 SDK: Add Topology::AsyncGetProperties
Co-Author: Dennis Klein <d.klein@gsi.de>
2020-01-27 20:50:11 +01:00
Dennis Klein
1c8ad03f3c SDK: Add Topology::AsyncSetProperties
Co-Author: Alexey Rybalchenko <alexryba@gmail.com>
2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
25658370fa SDK: Add DDSTopology::GetTasksMatchingPath 2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
f42945b3a3 SDK: Allow passing path to DDSSession::SendCommand 2020-01-27 20:50:11 +01:00
Dennis Klein
9544de0647 SDK: Do not require r-value refs
I mistakenly thought they were forwarding refs.
2020-01-27 20:50:11 +01:00
Dennis Klein
d608abf31c Fix -Wpedantic 2020-01-27 20:50:11 +01:00
Alexey Rybalchenko
15de80cfd3 Detect network interface of the default route without use of ip 2020-01-17 16:48:31 +01:00
Dennis Klein
f2da29a650 Update copyright 2020-01-16 20:26:53 +01:00
Dennis Klein
c180300303 Increase severity
From user feedback we learned that it is preferred to have this
condition rather fail fast than just warn.
2020-01-16 19:11:36 +01:00
Alexey Rybalchenko
9f8a3553ba Avoid deadlock in FairMQChannel operator=, handle self-assignment 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
692ec4e997 Fix CIDs 350447, 321250 (uncaught exception) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
b6d9c949ae Fix CID 350448 (uncaught exception) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
b6791856f9 Fix CID 350451 (uncaught exception) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
a1e0814a92 Fix CIDs 350452, 323467 (missing_lock) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
38bb14e556 Fix CID 350453 (uninit_member) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
7187953604 Fix CID 350455 (uncaught exception) 2020-01-16 17:17:52 +01:00
Alexey Rybalchenko
c290c16896 PMIx: Add commands to plugin and command ui 2020-01-06 20:20:18 +01:00
Dennis Klein
fd2bac3e22 Modernize ctor
https://clang.llvm.org/extra/clang-tidy/checks/modernize-pass-by-value.html#pass-by-value-in-constructors
2020-01-06 20:20:18 +01:00
Alexey Rybalchenko
8e3f25851c Pass by const ref 2020-01-06 20:20:18 +01:00
Alexey Rybalchenko
ce937ca03e Bump linger time for multipart test 2019-12-20 14:04:58 +01:00
Alexey Rybalchenko
684e711b8b Shmem: track number of message objects, throw if non-zero at reset 2019-12-20 14:04:58 +01:00
Alexey Rybalchenko
5b5fecc994 Extend multipart tests to include single part, transfer across >1 channel 2019-12-20 14:04:58 +01:00
Alexey Rybalchenko
462a93b58b Add multipart arguments to the benchmark script 2019-12-20 14:04:58 +01:00
Alexey Rybalchenko
a2cff5b7bb Shmem: simplify message/socket and refactor to use namespaces 2019-12-20 14:04:58 +01:00
Alexey Rybalchenko
b2e027478e shmem: properly initialize received multipart messages 2019-12-16 21:17:06 +01:00
Dennis Klein
e6dede492e Disable codecov.io checks 2019-12-13 14:52:36 +01:00
Dennis Klein
f195eeac66 Silence warning: unused variable 'a' [-Wunused-variable] 2019-12-13 14:52:36 +01:00
Dennis Klein
4d1e7b9cdb Fix AppleClang 10.0.1 support with Boost.Asio <= 1.68 2019-12-13 14:52:36 +01:00
Dennis Klein
50be386191 Support and require DDS 3.0 2019-12-13 14:52:36 +01:00
Alexey Rybalchenko
f31be6d7a1 Update to new DDS API, bump required version 2019-12-04 15:30:45 +01:00
Alexey Rybalchenko
5607d47664 DDSCommandUI: add support for more commands 2019-12-03 15:44:25 +01:00
Alexey Rybalchenko
0f4595b8c1 Remove TransitionTo from plugin APIs 2019-12-03 15:44:25 +01:00
Alexey Rybalchenko
b0b271d1f4 DDS plugin: remove static mode 2019-12-03 15:44:25 +01:00
Alexey Rybalchenko
073f5e5c0e Fix regression in the DDS plugin shutdown handling 2019-11-20 14:07:44 +01:00
Dennis Klein
f6e3183f45 SDK commands: Link shared flatbuffers if no static avail 2019-11-17 11:16:31 +01:00
Dennis Klein
71325828f6 CMake: Add option ENABLE_CCACHE 2019-11-15 14:44:56 +01:00
Alexey Rybalchenko
9d30ff25c2 Remove deprecated methods 2019-11-15 14:36:27 +01:00
Alexey Rybalchenko
2ac8f98178 Shm monitor: fix startup race and enable view-only mode 2019-11-13 16:16:16 +01:00
Alexey Rybalchenko
2c6f436858 Fix shmmonitor daemonization 2019-10-29 20:06:31 +01:00
Alexey Rybalchenko
dd191551ca Include empty parts in multipart example/test 2019-10-29 20:06:31 +01:00
Alexey Rybalchenko
88dbcbe4fd Formatting, some refactoring 2019-10-29 20:06:31 +01:00
Alexey Rybalchenko
85a3a254d4 Shmem: Fix handling of empty message parts 2019-10-29 20:06:31 +01:00
Alexey Rybalchenko
c34d1f0946 Cleanup includes 2019-10-29 20:06:31 +01:00
Alexey Rybalchenko
160ee9d064 Add safety check in shmem region location 2019-10-29 20:06:31 +01:00
Dennis Klein
040931fba7 CMake: Pass multi-value argument atomically 2019-10-28 18:01:56 +01:00
Dennis Klein
0d46ffe010 Docs: Add section on the Controller SDK 2019-10-21 15:52:47 +02:00
Alexey Rybalchenko
72a8e9b33c Commands: support JSON in addition to binary 2019-10-10 10:55:20 +02:00
Dennis Klein
caeee626a3 PMIx plugin: Add barriers and fix lookup of multiple keys 2019-10-07 14:07:27 +02:00
Dennis Klein
e1134321dd PMIx: Support integer values 2019-10-07 14:07:27 +02:00
Dennis Klein
5fc1c47e2a Relax required ZeroMQ version to support the CentOS 7 system package 2019-10-07 14:07:27 +02:00
Alexey Rybalchenko
2f69526c04 Enable commands in tests 2019-09-30 12:18:49 +02:00
Alexey Rybalchenko
7502f4b424 Add unit tests for commands 2019-09-30 12:18:49 +02:00
Alexey Rybalchenko
1c1509af3e Use new commands format in dds command UI 2019-09-30 12:18:49 +02:00
Alexey Rybalchenko
a53e95b5f6 Add flatbuffers-based command format to SDK/plugin 2019-09-30 12:18:49 +02:00
Alexey Rybalchenko
ea9ad64664 CMake: Support multiple values for REQUIRES in fairmq_build_option 2019-09-30 12:18:49 +02:00
Alexey Rybalchenko
b9720e5269 Update Topology.h 2019-09-19 15:45:28 +02:00
Dennis Klein
343605899f CI: Record DDS logs in error cases for analysis 2019-09-18 18:06:46 +02:00
Alexey Rybalchenko
d64169a163 SDK: optimize container access 2019-09-18 18:06:46 +02:00
Alexey Rybalchenko
37c8041997 Add missing include 2019-09-18 18:06:46 +02:00
Alexey Rybalchenko
d8d293302d Remove unused includes 2019-09-18 18:06:46 +02:00
Alexey Rybalchenko
9544d9665b DDS plugin: Prefix channel properties 2019-09-18 18:06:46 +02:00
Dennis Klein
47d9e282d4 SDK: Replace for loop with count_if 2019-09-17 11:34:46 +02:00
Alexey Rybalchenko
23423a86d9 Reduce codecov verbosity 2019-09-16 16:02:47 +02:00
Alexey Rybalchenko
dc72262af1 DDS Plugin: reset channel containers before filling 2019-09-16 16:02:47 +02:00
Alexey Rybalchenko
44bfbe02ed SDK: optimize TryChangeStateCompletion 2019-09-16 16:02:47 +02:00
Dennis Klein
924320a0ac DDS plugin: Move Boost dependency to intended target 2019-09-13 15:00:14 +02:00
Dennis Klein
e3890a4033 DDS plugin: Do not block the DDS KeyValue callback 2019-09-13 14:53:42 +02:00
Dennis Klein
fa394194e8 CMake: Fix working directory for submodule update command 2019-09-11 15:41:43 +02:00
Dennis Klein
79bcb40c04 CI: Preserve full paths in coverage reports 2019-09-05 21:59:37 +02:00
Dennis Klein
54719da645 CI: Enable SDK build and tests 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
4b78c472b1 Add sdk:GroupByTaskId(TopologyState) 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
92112c812f Handle InitializingDevice in the ShutdownSequence 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
870d0deae1 Add test for sdk::GroupByCollectionId(TopologyState) 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
acbf57d6f3 Add sdk::GroupByCollectionId(TopologyState) 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
2973ce0352 Add collections to test topology 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
e1b6b804bd sdk: Add DDSTopology::GetCollections() and extend DDSTask 2019-09-05 21:59:37 +02:00
Alexey Rybalchenko
456b65871a sdk: Add DDSCollection class 2019-09-05 21:59:37 +02:00
Dennis Klein
3f5374820a CMake: Add config for --graphviz 2019-09-04 21:17:35 +02:00
Dennis Klein
8a2c7fb601 DDS plugin: Wait for IDLE->EXITING state-change to be acknowledged
Sometimes devices shut down too fast when entering the EXITING state so
that the publication of that state-change will never be sent. The plugin
now waits for an acknowledgement by the external controller with a
configurable timeout.
2019-09-04 21:17:35 +02:00
Dennis Klein
c1a17c97b8 SDK: Add getter for agent path 2019-09-04 21:17:35 +02:00
Dennis Klein
ac8825c8de SDK: Update convenience header 2019-09-04 21:17:35 +02:00
Dennis Klein
1c49dde668 SDK: Fix data races on the local semaphores 2019-09-04 21:17:35 +02:00
Dennis Klein
5d6184cd1a Tools: Add a copyable SharedSemaphore 2019-09-04 21:17:35 +02:00
Dennis Klein
0e5f648d2b SDK: Require DDS 2.5.46
This DDS version fixed a critical deadlock
2019-09-04 21:17:35 +02:00
Dennis Klein
8057b8ae33 Tests.SDK: Fix formatting 2019-09-04 21:17:35 +02:00
Dennis Klein
da28b85497 Tests.SDK: Add optional DDS Tools API stability tests 2019-09-04 21:17:35 +02:00
Dennis Klein
33b5a2a342 SDK: Require DDS 2.5.42 and adapt to most recent API change 2019-09-04 21:17:35 +02:00
Dennis Klein
5b47df3014 SDK: Fix race condition which lead to frequent segfaults on destruction 2019-09-04 21:17:35 +02:00
Dennis Klein
fd77f2b729 SDK: Add usage examples (and tests) 2019-09-04 21:17:35 +02:00
Dennis Klein
6275f4d267 fairmq: Remove obsolete functions 2019-09-04 21:17:35 +02:00
Dennis Klein
d09be4ab79 Docs: Fix link 2019-09-04 21:17:35 +02:00
Dennis Klein
246e99a577 SDK: Fix exception specification 2019-09-04 21:17:35 +02:00
Dennis Klein
0d182dc18f fairmq: Fix -Wdefaulted-function-deleted 2019-09-04 21:17:35 +02:00
Dennis Klein
46e0796e77 CMake: Make the SDK depend on DDS_PLUGIN 2019-09-04 21:17:35 +02:00
Dennis Klein
1055f035ff CMake: Issue a warning if build option requirements are not met 2019-09-04 21:17:35 +02:00
Dennis Klein
7a0d348bd4 SDK: Implement Topology with asio-compliant async interface 2019-09-04 21:17:35 +02:00
Dennis Klein
3cd6d8cfca SDK: Refactor out DDSTask 2019-09-04 21:17:35 +02:00
Dennis Klein
0f50abf3d9 SDK: Fix completion signature and catch completion exceptions 2019-09-04 21:17:35 +02:00
Dennis Klein
75a3a80ac1 CMake: Fix submodule update command 2019-09-04 21:17:35 +02:00
Dennis Klein
25539e99f2 SDK: Introduce fairmq error category 2019-09-04 21:17:35 +02:00
Dennis Klein
f73a6d71ed CMake: Do not use git version in install tree 2019-09-04 21:17:35 +02:00
Dennis Klein
73af0ed78b SDK: Implement asio-compliant asynchronous operation helpers 2019-09-04 21:17:35 +02:00
Dennis Klein
1dec059104 SDK: Require C++14, CMake 3.11 and bundle asio 1.13.0
Decouple from Boost distro to be able to use
newest releases and rely on std::error_code only.
2019-09-04 21:17:35 +02:00
Dennis Klein
88ff5d8fc0 CMake: Bundle GTest 2019-09-04 21:17:35 +02:00
Dennis Klein
d6d9312e53 CMake: Add find module for asio 2019-09-04 21:17:35 +02:00
Dennis Klein
2208fe91e8 README: Update instructions 2019-09-04 21:17:35 +02:00
Dennis Klein
8d12b908b6 SDK: Implement helper to find most recent running DDS session 2019-09-04 21:17:35 +02:00
Alexey Rybalchenko
02b20c320c Add support for fairlogger dependencies 2019-08-22 15:52:45 +02:00
Alexey Rybalchenko
be06a5629e Print install prefix in cmake summary 2019-08-14 15:03:12 +02:00
Alexey Rybalchenko
eaa8f5cbdd SDK: Require DDS 2.5.36 and support new Tools API 2019-08-13 20:04:05 +02:00
Alexey Rybalchenko
7f0237d97d Example.DDS: Support DDS 2.5.25+ CLI 2019-08-13 20:04:05 +02:00
Alexey Rybalchenko
2fc93994d1 Execute test for DDS example only if DDS was found 2019-08-12 16:22:39 +02:00
Alexey Rybalchenko
8feffe70ba Topology: Use DDSTask type, remove unused member 2019-08-12 16:22:39 +02:00
Dennis Klein
31edf948de FairMQ: Require Boost 1.66 2019-08-07 18:37:36 +02:00
184 changed files with 9375 additions and 3096 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'
HeaderFilterRegex: '/(fairmq/|FairMQ)'
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'
HeaderFilterRegex: '/(fairmq/)'

View File

@@ -1,2 +1,3 @@
comment:
layout: "diff, files"
behavior: once

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "extern/googletest"]
path = extern/googletest
url = https://github.com/google/googletest
[submodule "extern/asio"]
path = extern/asio
url = https://github.com/chriskohlhoff/asio

View File

@@ -0,0 +1,14 @@
set(GRAPHVIZ_GRAPH_TYPE digraph)
set(GRAPHVIZ_GRAPH_NAME FairMQ)
set(GRAPHVIZ_EXECUTABLES ON)
set(GRAPHVIZ_STATIC_LIBS OFF)
set(GRAPHVIZ_SHARED_LIBS ON)
set(GRAPHVIZ_MODULE_LIBS OFF)
set(GRAPHVIZ_GENERATE_PER_TARGET OFF)
set(GRAPHVIZ_GENERATE_DEPENDERS OFF)
set(GRAPHVIZ_IGNORE_TARGETS
"fairmq-ex.*"
"testsuite_.*"
"testhelper_.*"
"FairMQPlugin_test_dummy"
)

View File

@@ -6,8 +6,8 @@
# copied verbatim in the file "LICENSE" #
################################################################################
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
cmake_policy(VERSION 3.10...3.14)
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
cmake_policy(VERSION 3.12...3.15)
# Project ######################################################################
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
@@ -18,7 +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)
if(BUILD_OFI_TRANSPORT OR BUILD_SDK OR BUILD_PMIX_PLUGIN)
set(PROJECT_MIN_CXX_STANDARD 14)
else()
set(PROJECT_MIN_CXX_STANDARD 11)
@@ -31,17 +31,28 @@ include(CTest)
# Build options ################################################################
include(CMakeDependentOption)
option(BUILD_FAIRMQ "Build FairMQ library and devices." ON)
cmake_dependent_option(BUILD_TESTING "Build tests." OFF "BUILD_FAIRMQ" OFF)
cmake_dependent_option(BUILD_NANOMSG_TRANSPORT "Build nanomsg transport." OFF "BUILD_FAIRMQ" OFF)
cmake_dependent_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport." OFF "BUILD_FAIRMQ" OFF)
cmake_dependent_option(BUILD_DDS_PLUGIN "Build DDS plugin." OFF "BUILD_FAIRMQ" OFF)
cmake_dependent_option(BUILD_PMIX_PLUGIN "Build PMIx plugin." OFF "BUILD_FAIRMQ" OFF)
cmake_dependent_option(BUILD_EXAMPLES "Build FairMQ examples." ON "BUILD_FAIRMQ" OFF)
option(BUILD_SDK "Build the FairMQ controller SDK." OFF)
option(BUILD_DOCS "Build FairMQ documentation." OFF)
option(FAST_BUILD "Fast production build. Not recommended for development." 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_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)
################################################################################
@@ -74,16 +85,15 @@ if(BUILD_NANOMSG_TRANSPORT)
)
endif()
if(BUILD_SDK)
set(required_dds_version 2.5.22)
else()
set(required_dds_version 2.4)
if(BUILD_SDK_COMMANDS)
find_package2(PRIVATE Flatbuffers REQUIRED)
endif()
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
find_package2(PRIVATE DDS REQUIRED
VERSION ${required_dds_version}
VERSION 3.0
)
set(DDS_Boost_COMPONENTS system log log_setup)
set(DDS_Boost_COMPONENTS system log log_setup regex filesystem thread)
set(DDS_Boost_VERSION 1.67)
endif()
@@ -98,6 +108,13 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
VERSION 1.2.0
)
foreach(dep IN LISTS FairLogger_PACKAGE_DEPENDENCIES)
if(NOT dep STREQUAL "Boost")
find_package2(PUBLIC ${dep} REQUIRED VERSION ${FairLogger_${dep}_VERSION})
set(PROJECT_${dep}_VERSION ${FairLogger_${dep}_VERSION})
endif()
endforeach()
if(NOT DEFINED Boost_NO_BOOST_CMAKE AND CMAKE_VERSION VERSION_LESS 3.15)
# Since Boost 1.70 a CMake package is shipped by default. Unfortunately, it has a number
# of problems that are only fixed in Boost 1.71 or CMake 3.15. By default we skip the
@@ -105,7 +122,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
set(Boost_NO_BOOST_CMAKE ON)
endif()
find_package2(PUBLIC Boost REQUIRED
VERSION 1.64
VERSION 1.66
COMPONENTS
container
@@ -119,18 +136,35 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
DDS
FairLogger
)
# Normalize Boost version
if(CMAKE_VERSION VERSION_LESS 3.15)
set(Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
endif()
endif()
if(BUILD_SDK)
find_package2(BUNDLED asio
VERSION 1.13.0
)
if(NOT asio_FOUND)
build_bundled(asio extern/asio)
find_package2(PRIVATE asio REQUIRED)
endif()
endif()
if(BUILD_FAIRMQ)
find_package2(PRIVATE ZeroMQ REQUIRED
VERSION 4.1.5
VERSION 4.1.4
)
endif()
if(BUILD_TESTING)
find_package2(PRIVATE GTest REQUIRED
VERSION 1.7.0
)
find_package2(PRIVATE GTest VERSION 1.7.0)
if(NOT GTest_FOUND)
build_bundled(GTest extern/googletest)
find_package2(PRIVATE GTest REQUIRED)
endif()
endif()
if(BUILD_DOCS)
@@ -196,6 +230,9 @@ endif()
if(BUILD_SDK)
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk)
endif()
if(BUILD_SDK_COMMANDS)
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
endif()
################################################################################
@@ -210,6 +247,22 @@ if(BUILD_DOCS)
DESTINATION ${PROJECT_INSTALL_DATADIR}/docs
)
endif()
if(BUILD_SDK)
install(FILES cmake/Findasio.cmake
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
)
if(asio_BUNDLED)
install(TARGETS bundled_asio_headers EXPORT ${PROJECT_EXPORT_SET})
install(DIRECTORY "${asio_BUILD_INCLUDE_DIR}/asio"
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
PATTERN "Makefile.am" EXCLUDE
PATTERN ".gitignore" EXCLUDE
)
install(FILES "${asio_BUILD_INCLUDE_DIR}/asio.hpp"
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
)
endif()
endif()
install_cmake_package()
################################################################################
@@ -245,16 +298,8 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
message(STATUS " ")
message(STATUS " ${Cyan}DEPENDENCY FOUND VERSION PREFIX${CR}")
foreach(dep IN LISTS PROJECT_PACKAGE_DEPENDENCIES)
if(${dep}_VERSION)
if(${dep} STREQUAL Boost)
if(Boost_VERSION_MAJOR)
set(version_str "${BGreen}${${dep}_VERSION_MAJOR}.${${dep}_VERSION_MINOR}${CR}")
else()
set(version_str "${BGreen}${${dep}_MAJOR_VERSION}.${${dep}_MINOR_VERSION}${CR}")
endif()
else()
set(version_str "${BGreen}${${dep}_VERSION}${CR}")
endif()
if(${dep}_VERSION AND NOT ${dep}_VERSION STREQUAL "..")
set(version_str "${BGreen}${${dep}_VERSION}${CR}")
else()
set(version_str "${BYellow}unknown${CR}")
endif()
@@ -298,10 +343,22 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
get_target_property(doxygen_bin Doxygen::doxygen INTERFACE_LOCATION)
get_filename_component(prefix ${doxygen_bin} DIRECTORY)
get_filename_component(prefix ${prefix}/.. ABSOLUTE)
elseif(${dep} STREQUAL fmt)
get_target_property(fmt_include fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
get_filename_component(prefix ${fmt_include}/.. ABSOLUTE)
elseif(${dep} STREQUAL Flatbuffers)
if(TARGET flatbuffers::flatbuffers)
get_target_property(flatbuffers_include flatbuffers::flatbuffers INTERFACE_INCLUDE_DIRECTORIES)
else()
get_target_property(flatbuffers_include flatbuffers::flatbuffers_shared INTERFACE_INCLUDE_DIRECTORIES)
endif()
get_filename_component(prefix ${flatbuffers_include}/.. ABSOLUTE)
else()
get_filename_component(prefix ${${dep}_INCLUDE_DIR}/.. ABSOLUTE)
endif()
message(STATUS " ${BWhite}${dep_padded}${CR}${version_padded}${prefix}")
if(NOT ${dep}_BUNDLED)
message(STATUS " ${BWhite}${dep_padded}${CR}${version_padded}${prefix}")
endif()
unset(version_str)
unset(version_padded)
unset(version_req_str)
@@ -340,9 +397,9 @@ else()
endif()
message(STATUS " ${BWhite}dds_plugin${CR} ${dds_summary}")
if(BUILD_PMIX_PLUGIN)
set(pmix_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
set(pmix_summary "${BGreen}YES${CR} EXPERIMENTAL (requires C++14) (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
else()
set(pmix_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
set(pmix_summary "${BRed} NO${CR} EXPERIMENTAL (requires C++14) (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
endif()
message(STATUS " ${BWhite}pmix_plugin${CR} ${pmix_summary}")
if(BUILD_EXAMPLES)
@@ -358,11 +415,17 @@ else()
endif()
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
if(BUILD_SDK)
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (required C++14) (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
else()
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (required C++14) (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
endif()
message(STATUS " ${BWhite}sdk${CR} ${sdk_summary}")
if(BUILD_SDK_COMMANDS)
set(sdk_commands_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_SDK_COMMANDS=OFF${CR})")
else()
set(sdk_commands_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_SDK_COMMANDS=ON${CR})")
endif()
message(STATUS " ${BWhite}sdk_commands${CR} ${sdk_commands_summary}")
message(STATUS " ")
if(RUN_STATIC_ANALYSIS)
list(LENGTH PROJECT_STATIC_ANALYSERS size)
@@ -384,6 +447,8 @@ if(RUN_STATIC_ANALYSIS)
else()
set(static_ana_summary "${BRed}OFF${CR} (default, enable with ${BMagenta}-DRUN_STATIC_ANALYSIS=ON${CR})")
endif()
message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX}${CR} (change with ${BMagenta}-DCMAKE_INSTALL_PREFIX=...${CR})")
message(STATUS " ")
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
message(STATUS " ")
################################################################################

View File

@@ -4,6 +4,7 @@ Eulisse, Giulio
Karabowicz, Radoslaw
Kretz, Matthias <kretz@kde.org>
Krzewicki, Mikolaj
Lebedev, Andrey
Mrnjavac, Teo <teo.m@cern.ch>
Neskovic, Gvozden
Richter, Matthias

View File

@@ -15,6 +15,14 @@ Files: cmake/cotire.cmake
Copyright: 2012-2018 Sascha Kratky
License: COTIRE
Files: extern/googletest
Copyright: 2008, Google Inc.
License: GOOGLE
Files: extern/asio
Copyright: 2003-2019, Christopher M. Kohlhoff (chris at kohlhoff dot com)
License: BSL-1.0
License: LGPL-3.0-only
[see LICENSE file]
@@ -39,3 +47,58 @@ License: COTIRE
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.
License: GOOGLE
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: BSL-1.0
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
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.

View File

@@ -65,7 +65,7 @@ if [ "$1" == "alfa_ci" ]; then
export ctest_model=Experimental
elif [ "$1" == "codecov" ]; then
export ctest_model=Profile
export do_codecov_upload=1
export do_codecov_upload=0
else
export ctest_model=$1
fi

View File

@@ -29,13 +29,14 @@ 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=OFF")
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}")
Set(EXTRA_FLAGS $ENV{EXTRA_FLAGS})
If(EXTRA_FLAGS)
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
EndIf()
If($ENV{ctest_model} MATCHES Profile)
@@ -43,6 +44,7 @@ If($ENV{ctest_model} MATCHES Profile)
If(GCOV_COMMAND)
Message("Found GCOV: ${GCOV_COMMAND}")
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
EndIf(GCOV_COMMAND)
EndIf()
@@ -58,7 +60,7 @@ Ctest_Configure(BUILD "${CTEST_BINARY_DIRECTORY}"
Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
# PARALLEL_LEVEL $ENV{number_of_processors}
PARALLEL_LEVEL $ENV{number_of_processors}
RETURN_VALUE _ctest_test_ret_val
@@ -78,7 +80,7 @@ If("$ENV{do_codecov_upload}")
EndIf()
Ctest_Submit()
if (_ctest_test_ret_val)
Message(FATAL_ERROR "Some tests failed.")
endif()

16
Jenkinsfile vendored
View File

@@ -22,11 +22,11 @@ def jobMatrix(String prefix, List specs, Closure callback) {
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc8/) {
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/8" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /MacOS/) {
@@ -49,6 +49,10 @@ def jobMatrix(String prefix, List specs, Closure callback) {
deleteDir()
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
} catch (e) {
def tarball = "${prefix}_${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
archiveArtifacts tarball
deleteDir()
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
throw e
@@ -65,16 +69,16 @@ pipeline{
stage("Run CI Matrix") {
steps{
script {
def build_jobs = jobMatrix('alfa-ci/build', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
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 profile_jobs = jobMatrix('alfa-ci/codecov', [
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
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'

View File

@@ -21,11 +21,11 @@ def buildMatrix(List specs, Closure callback) {
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
"""
if (os =~ /Debian/ && compiler =~ /gcc8/) {
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/8" >> Dart.cfg
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
'''
}
if (os =~ /MacOS/) {
@@ -46,6 +46,10 @@ def buildMatrix(List specs, Closure callback) {
deleteDir()
} catch (e) {
def tarball = "${label}_dds_logs.tar.gz"
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
archiveArtifacts tarball
deleteDir()
throw e
}
@@ -63,7 +67,7 @@ pipeline{
steps{
script {
parallel(buildMatrix([
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
[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 ->

View File

@@ -33,25 +33,21 @@ configuration and control services.
FairMQ has been developed in the context of its mother project [FairRoot](https://github.com/FairRootGroup/FairRoot) -
a simulation, reconstruction and analysis framework.
## Dependencies
* PUBLIC: [**Boost**](https://www.boost.org/), [**FairLogger**](https://github.com/FairRootGroup/FairLogger)
* BUILD: [CMake](https://cmake.org/), [GTest](https://github.com/google/googletest), [Doxygen](http://www.doxygen.org/)
* PRIVATE: [ZeroMQ](http://zeromq.org/), [Msgpack](https://msgpack.org/index.html), [nanomsg](http://nanomsg.org/),
[asiofi](https://github.com/FairRootGroup/asiofi), [DDS](http://dds.gsi.de), [PMIx](https://pmix.org/)
Supported platforms: Linux and MacOS.
## Installation from Source
Recommended:
```bash
git clone https://github.com/FairRootGroup/FairMQ fairmq
mkdir fairmq_build && cd fairmq_build
cmake -DCMAKE_INSTALL_PREFIX=./fairmq_install ../fairmq
cmake --build . --target install
git clone https://github.com/FairRootGroup/FairMQ fairmq_source
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=fairmq_install
cmake --build fairmq_build
cd fairmq_build; ctest -j4; cd ..
cmake --build fairmq_build --target install
```
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`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
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).
## Usage
@@ -70,30 +66,50 @@ find_package(FairMQ)
`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ`.
In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies, too.
In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies:
```cmake
find_package(FairMQ)
if(FairMQ_FOUND)
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_Boost_COMPONENTS})
foreach(dep IN LISTS FairMQ_PACKAGE_DEPENDENCIES)
if(FairMQ_${dep}_COMPONENTS)
find_package(${dep} ${FairMQ_${dep}_VERSION} COMPONENTS ${FairMQ_${dep}_COMPONENTS})
else()
find_package(${dep} ${FairMQ_${dep}_VERSION})
endif()
endforeach()
endif()
```
Of course, feel free to customize the above commands to your needs.
If your project shares a dependency with FairMQ or if you want to omit a certain dependency, you may want to customize the above example code to your needs.
Optionally, you can require certain FairMQ package components and a minimum version:
```cmake
find_package(FairMQ 1.1.0 COMPONENTS nanomsg_transport dds_plugin)
if(FairMQ_FOUND)
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_Boost_COMPONENTS})
endif()
```
When building FairMQ, CMake will print a summary table of all available package components.
## Dependencies
* [asio](https://github.com/chriskohlhoff/asio) (optionally bundled)
* [asiofi](https://github.com/FairRootGroup/asiofi)
* [Boost](https://www.boost.org/)
* [CMake](https://cmake.org/)
* [DDS](http://dds.gsi.de)
* [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/)
Which dependencies are required depends on which components are built.
Supported platforms: Linux and MacOS.
## CMake options
On command line:
@@ -106,7 +122,7 @@ On command line:
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
* `-DBUILD_DOCS=ON` enables building of API docs.
* You can hint non-system installations for dependent packages, see the #Installation section above
* You can hint non-system installations for dependent packages, see the #installation-from-source section above
After the `find_package(FairMQ)` call the following CMake variables are defined:
@@ -165,4 +181,5 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
3. [Provided Plugins](docs/Plugins.md#73-provided-plugins)
1. [DDS](docs/Plugins.md#731-dds)
2. [PMIx](docs/Plugins.md#732-pmix)
8. [Controller SDK](docs/SDK.md)

View File

@@ -36,4 +36,6 @@ set(CMAKE_MODULE_PATH ${@PROJECT_NAME@_CMAKEMODDIR} ${CMAKE_MODULE_PATH})
### Import targets
include(@PACKAGE_CMAKE_INSTALL_PREFIX@/@PACKAGE_INSTALL_DESTINATION@/@PROJECT_EXPORT_SET@.cmake)
@BUNDLED_PACKAGES@
@PACKAGE_COMPONENTS@

View File

@@ -143,15 +143,17 @@ macro(set_fairmq_defaults)
set(PROJECT_EXPORT_SET ${PROJECT_NAME}Targets)
# Configure build types
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo" "Nightly" "Profile" "Experimental" "AdressSan" "ThreadSan")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wshadow -Wall -Wextra")
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_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -Wshadow -Wall -Wextra -DNDEBUG")
set(CMAKE_CXX_FLAGS_NIGHTLY "-O2 -g -Wshadow -Wall -Wextra")
set(CMAKE_CXX_FLAGS_PROFILE "-g3 -Wshadow -Wall -Wextra -fno-inline -ftest-coverage -fprofile-arcs")
set(CMAKE_CXX_FLAGS_EXPERIMENTAL "-O2 -g -Wshadow -Wall -Wextra -DNDEBUG")
set(CMAKE_CXX_FLAGS_ADRESSSAN "-O2 -g -Wshadow -Wall -Wextra -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_THREADSAN "-O2 -g -Wshadow -Wall -Wextra -fsanitize=thread")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${_warnings} -DNDEBUG")
set(CMAKE_CXX_FLAGS_NIGHTLY "-O2 -g ${_warnings}")
set(CMAKE_CXX_FLAGS_PROFILE "-g3 ${_warnings} -fno-inline -ftest-coverage -fprofile-arcs")
set(CMAKE_CXX_FLAGS_EXPERIMENTAL "-O2 -g ${_warnings} -DNDEBUG")
set(CMAKE_CXX_FLAGS_ADDRESSSAN "-O2 -g ${_warnings} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_THREADSAN "-O2 -g ${_warnings} -fsanitize=thread")
unset(_warnings)
if(CMAKE_GENERATOR STREQUAL "Ninja" AND
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
@@ -194,6 +196,13 @@ macro(set_fairmq_defaults)
endif()
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
endif()
if(CMAKE_GENERATOR STREQUAL Ninja AND ENABLE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
endif()
endif()
endmacro()
function(join VALUES GLUE OUTPUT)
@@ -266,13 +275,30 @@ check_required_components(${PROJECT_NAME})
set(PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} PARENT_SCOPE)
endfunction()
function(generate_bundled_packages)
if(asio_BUNDLED)
set(BUNDLED_PACKAGES "\
####### Expanded from @BUNDLED_PACKAGES@ by configure_package_config_file() #########
if(\"\${CMAKE_MAJOR_VERSION}.\${CMAKE_MINOR_VERSION}\" VERSION_LESS 3.11)
message(FATAL_ERROR \"CMake >= 3.11 required\")
endif()
set_target_properties(${PROJECT_NAME}::bundled_asio_headers PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(asio::headers ALIAS ${PROJECT_NAME}::bundled_asio_headers)
set(asio_VERSION ${asio_VERSION})
")
endif()
set(BUNDLED_PACKAGES ${BUNDLED_PACKAGES} PARENT_SCOPE)
endfunction()
# Configure/Install CMake package
macro(install_cmake_package)
list(SORT PROJECT_PACKAGE_DEPENDENCIES)
list(SORT PROJECT_INTERFACE_PACKAGE_DEPENDENCIES)
include(CMakePackageConfigHelpers)
set(PACKAGE_INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_GIT_VERSION}
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
)
if(BUILD_FAIRMQ)
install(EXPORT ${PROJECT_EXPORT_SET}
@@ -288,6 +314,7 @@ macro(install_cmake_package)
)
generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES}
generate_package_components() # fills ${PACKAGE_COMPONENTS}
generate_bundled_packages() # fills ${BUNDLED_PACKAGES}
string(TOUPPER ${CMAKE_BUILD_TYPE} PROJECT_BUILD_TYPE_UPPER)
set(PROJECT_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${PROJECT_BUILD_TYPE_UPPER}})
configure_package_config_file(
@@ -312,10 +339,11 @@ endmacro()
#
# Wrapper around CMake's native find_package command to add some features and bookkeeping.
#
# The qualifier (PRIVATE|PUBLIC|INTERFACE) to the package to populate
# The qualifier (PRIVATE|PUBLIC|INTERFACE|BUNDLED) to the package to populate
# the variables PROJECT_[INTERFACE]_<pkgname>_([VERSION]|[COMPONENTS]|PACKAGE_DEPENDENCIES)
# accordingly. This bookkeeping information is used to print our dependency found summary
# table and to generate a part of our CMake package.
# table and to generate a part of our CMake package. BUNDLED decays to PUBLIC if the variable
# <pkgname>_BUNDLED is false and to PRIVATE otherwise.
#
# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables
# <dep_pkgname>_<pkgname>_VERSION|COMPONENTS are looked up to and added to the native
@@ -372,28 +400,149 @@ macro(find_package2 qualifier pkgname)
find_package(${pkgname} ${__version__} QUIET ${ARGS_UNPARSED_ARGUMENTS})
endif()
if(${qualifier} STREQUAL BUNDLED)
if(${pkgname}_BUNDLED)
set(__qualifier__ PRIVATE)
else()
set(__qualifier__ PUBLIC)
endif()
else()
set(__qualifier__ ${qualifier})
endif()
if(${pkgname}_FOUND)
if(${qualifier} STREQUAL PRIVATE)
if(${__qualifier__} STREQUAL PRIVATE)
set(PROJECT_${pkgname}_VERSION ${__version__})
set(PROJECT_${pkgname}_COMPONENTS ${__components__})
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
elseif(${qualifier} STREQUAL PUBLIC)
elseif(${__qualifier__} STREQUAL PUBLIC)
set(PROJECT_${pkgname}_VERSION ${__version__})
set(PROJECT_${pkgname}_COMPONENTS ${__components__})
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__})
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
elseif(${qualifier} STREQUAL INTERFACE)
elseif(${__qualifier__} STREQUAL INTERFACE)
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__})
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
endif()
endif()
unset(__qualifier__)
unset(__version__)
unset(__components__)
unset(__required_versions__)
set(CMAKE_PREFIX_PATH ${__old_cpp__})
unset(__old_cpp__)
endmacro()
macro(exec cmd)
join("${ARGN}" " " args)
file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n")
execute_process(COMMAND ${cmd} ${ARGN}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
OUTPUT_VARIABLE log
ERROR_VARIABLE log
RESULT_VARIABLE res
)
file(APPEND ${${package}_BUILD_LOGFILE} ${log})
if(res)
message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"")
endif()
endmacro()
macro(exec_source cmd)
join("${ARGN}" " " args)
file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n")
execute_process(COMMAND ${cmd} ${ARGN}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE log
ERROR_VARIABLE log
RESULT_VARIABLE res
)
file(APPEND ${${package}_BUILD_LOGFILE} ${log})
if(res)
message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"")
endif()
endmacro()
function(build_bundled package bundle)
message(STATUS "Building bundled ${package}")
set(${package}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${bundle})
set(${package}_BINARY_DIR ${CMAKE_BINARY_DIR}/${bundle})
file(MAKE_DIRECTORY ${${package}_BINARY_DIR})
set(${package}_BUILD_LOGFILE ${${package}_BINARY_DIR}/build.log)
file(REMOVE ${${package}_BUILD_LOGFILE})
if(Git_FOUND)
exec_source(${GIT_EXECUTABLE} submodule update --init -- ${${package}_SOURCE_DIR})
endif()
if(${package} STREQUAL GTest)
set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install)
file(MAKE_DIRECTORY ${${package}_INSTALL_DIR})
set(${package}_ROOT ${${package}_INSTALL_DIR})
exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR}
-DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} -DBUILD_GMOCK=OFF
)
exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR})
exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install)
elseif(${package} STREQUAL asio)
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)
endif()
string(TOUPPER ${package} package_upper)
set(${package_upper}_ROOT "${${package}_ROOT}" CACHE PATH "Bundled ${package} install prefix search hint")
set(${package}_BUNDLED ON CACHE BOOL "Whether bundled ${package} was used")
message(STATUS "Building bundled ${package} - done")
endfunction()
macro(fairmq_build_option option description)
cmake_parse_arguments(ARGS "" "DEFAULT" "REQUIRES" ${ARGN})
if(ARGS_DEFAULT)
set(__default__ ON)
else()
set(__default__ OFF)
endif()
if(ARGS_REQUIRES)
include(CMakeDependentOption)
set(__requires__ ${ARGS_REQUIRES})
foreach(d ${__requires__})
string(REGEX REPLACE " +" ";" __requires_condition__ "${d}")
if(${__requires_condition__})
else()
if(${option})
message(FATAL_ERROR "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
endif()
endif()
endforeach()
else()
set(__requires__)
endif()
if(__requires__)
cmake_dependent_option(${option} ${description} ${__default__} "${__requires__}" OFF)
else()
option(${option} ${description} ${__default__})
endif()
set(__default__)
set(__requires__)
set(__requires_condition__)
set(ARGS_DEFAULT)
set(ARGS_REQUIRES)
set(option)
set(description)
endmacro()

53
cmake/Findasio.cmake Normal file
View File

@@ -0,0 +1,53 @@
################################################################################
# Copyright (C) 2019 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(asio_INCLUDE_DIR
NAMES asio.hpp
PATH_SUFFIXES include
)
if(asio_INCLUDE_DIR)
find_file(asio_VERSION_HEADER "asio/version.hpp"
${asio_INCLUDE_DIR}
NO_DEFAULT_PATH
)
endif()
if(asio_VERSION_HEADER)
file(READ "${asio_VERSION_HEADER}" _asio_VERSION_HEADER_CONTENT)
string(REGEX MATCH "#define ASIO_VERSION ([0-9]+)" _MATCH "${_asio_VERSION_HEADER_CONTENT}")
set(asio_VERSION_MACRO ${CMAKE_MATCH_1})
math(EXPR asio_VERSION_MAJOR "${asio_VERSION_MACRO} / 100000")
math(EXPR asio_VERSION_MINOR "${asio_VERSION_MACRO} / 100 % 1000")
math(EXPR asio_VERSION_PATCH "${asio_VERSION_MACRO} % 100")
set(asio_VERSION "${asio_VERSION_MAJOR}.${asio_VERSION_MINOR}.${asio_VERSION_PATCH}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(asio
REQUIRED_VARS asio_INCLUDE_DIR
VERSION_VAR asio_VERSION
HANDLE_COMPONENTS
)
if(asio_FOUND AND asio_BUNDLED)
add_library(bundled_asio_headers INTERFACE)
target_include_directories(bundled_asio_headers INTERFACE
$<BUILD_INTERFACE:${asio_BUILD_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${asio_INSTALL_INCLUDE_DIR}>
)
add_library(asio::headers ALIAS bundled_asio_headers)
endif()
if(asio_FOUND AND NOT TARGET asio::headers)
add_library(asio::headers INTERFACE IMPORTED)
set_target_properties(asio::headers PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${asio_INCLUDE_DIR}"
)
endif()

34
docs/SDK.md Normal file
View File

@@ -0,0 +1,34 @@
← [Back](../README.md)
# 8. Controller SDK
The FairMQ Controller Software Development Kit (`-DBUILD_SDK=ON`) contains a (as of today still experimental) set of C++ APIs that provide essential functionality to the implementer of a global controller.
The FairMQ core library only provides two local controllers - `static` (a fixed sequence of state transitions) and `interactive` (a read-eval-print-loop which reads keyboard commands from standard input). A local controller only knows how steer a single [FairMQ device](Device.md) - in fact, it runs in a thread within the device process.
A global controller has knowledge about the full topology of connected FairMQ devices. Its responsibility is to facilitate the lifecycle of a distributed FairMQ-based application (*executing a topology*), such as
* allocating/releasing compute resources from a resource management system,
* launching/setting up the run-time environment and the FairMQ devices,
* driving the device state machines in lock-step across the full topology,
* pushing the device configuration,
* monitoring (some aspects of the application's) operation,
* and handling/reporting (some) error cases.
The low-level hook to integrate FairMQ devices with such a global contoller is the [plugin mechanism](Plugins.md) in the FairMQ core library. The FairMQ Controller SDK provides C++ APIs that communicate to the endpoints exposed by such a FairMQ plugin.
At the moment, the Controller SDK only supports [DDS](https://dds.gsi.de) as resource manager and run-time environment. A second implementation based on [PMIx](https://pmix.org/) (targeting its implementation in [Slurm](https://slurm.schedmd.com/documentation.html) and [OpenRTE](https://www-lb.open-mpi.org/papers/euro-pvmmpi-2005-orte/)) is in development.
The following section give a short overview on the APIs provided.
## RMS and run-time environment
The classes [`fair::mq::sdk::DDSEnvironment`](../fairmq/sdk/DDSEnvironment.h), [`fair::mq::sdk::DDSSession`](../fairmq/sdk/DDSSession.h), and [`fair::mq::sdk::DDSTopology`](../fairmq/sdk/DDSTopology.h) are thin wrappers of most of the synchronous APIs exposed by DDS ([`dds::tools_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1tools__api.html) and [`dds::topology_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1topology__api.html)). E.g. they allow to [start a DDS session](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L26-L28), [allocate resources](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L34) and [launch a topology](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L39) from a C++ program.
## Driving the global state machine
The class [`fair::mq::sdk::Topology`](../fairmq/sdk/Topology.h) adds a FairMQ-specific view on an existing DDS session that is executing a topology of FairMQ devices. One can e.g. [initiate a state transition on all devices in the topology simultaneously](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L48-L49). This topology transition completes once a topology-wide barrier is passed (all devices completed the transition). This effectively exposes the device state machine as a topology state machine. The implementation is based on remote procedure calls over the [DDS intercom service](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1intercom__api.html) between the controller and the DDS plugin shipped with FairMQ (`-DBUILD_DDS_PLUGIN=ON`).
For future versions of the SDK new APIs are planned to inspect and modify the device configurations and also operate only on subsets of a given topology.
← [Back](../README.md)

View File

@@ -6,9 +6,6 @@
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include <thread> // this_thread::sleep_for
#include <chrono>
#include "Sampler.h"
using namespace std;

View File

@@ -16,6 +16,8 @@ add_subdirectory(multiple-channels)
if(BUILD_NANOMSG_TRANSPORT)
add_subdirectory(multiple-transports)
endif()
add_subdirectory(n-m)
add_subdirectory(qc)
add_subdirectory(readout)
add_subdirectory(region)
add_subdirectory(req-rep)

View File

@@ -6,41 +6,50 @@ Set of FairMQ examples. More examples that combine FairMQ with FairRoot can be f
A simple topology of two devices - **Sampler** and **Sink**. **Sampler** sends data to **Sink** with the **PUSH-PULL** pattern.
## 1-n-1
A simple topology of three device types - **Sampler**, **Processor** and **Sink**. **Sampler** sends data to one or more **Processor**s, who modify the data and send it to one **Sink**. Transport with the **PUSH-PULL** pattern. The example also shows the configuration via JSON files, as oposed to `--channel-config` that is used by other examples.
## Built-in devices
## DDS
This example demonstrates usage of the Dynamic Deployment System ([DDS](http://dds.gsi.de/)) to dynamically deploy and configure a topology of devices. The topology is similar to those of Example 2, but now it can be easily distributed on different computing nodes without the need for manual reconfiguration of the devices.
Usage of generic devies provided with FairMQ.
## Copy & Push
A topology consisting of one **Sampler** and two **Sink**s. The **Sampler** uses the `Copy` method to send the same data to both sinks with the **PUSH-PULL** pattern. In countrary to the **PUB-SUB** pattern, this ensures that all receivers are connected and no data is lost, but requires additional channels to be configured.
## DDS
## Request & Reply
This example demonstrates usage of the Dynamic Deployment System ([DDS](http://dds.gsi.de/)) to dynamically deploy and configure a topology of devices. The topology is similar to those of Example 2, but now it can be easily distributed on different computing nodes without the need for manual reconfiguration of the devices.
This topology contains two devices that communicate with each other via the **REQ-REP** pettern. Bidirectional communication via a single socket.
## Multipart
This example shows how to send a multipart message from one device to the other. (two parts message parts - header and body).
## Multiple Channels
This example demonstrates how to work with multiple channels and multiplex between them.
## Sending Multipart messages
This example shows how to send a multipart message from one device to the other. (two parts message parts - header and body).
## Multiple Transports example
## Multiple Transports
This examples shows how to combine different channel transports (zeromq/nanomsg/shmem) inside of one device and/or topology.
## Region example
## n-m
A topology consisting of three layers of devices: synchronizer -> n * senders -> m * receivers.
## QC
A topology consisting of 4 devices - Sampler, QCDispatcher, QCTask and Sink. The data flows from Sampler through QCDispatcher to Sink. On demand - by setting the corresponding configuration property - the QCDispatcher device will duplicate the data to the QCTask device. The property is set by the topology controller, in this example this is the `fairmq-dds-command-ui` utility.
## Readout
Two example topologies of setups to be distributed to two kinds of nodes - detector readout node and processing node. Detector readout node contains readout process, data builder and data sender (and optionally an additional processor), while processing node contains data receiver devices. communication within readout nodes is done via unmanaged region through shared memory transport.
## Region
This example demonstrates the use of a more advanced feature - UnmanagedRegion, that can be used to create a buffer through one of FairMQ transports. The contents of this buffer are managed by the user, who can also create messages out of sub-buffers of the created buffer. Such feature can be interesting in environments that have special requirements by the hardware that writes the data, to keep the transfer efficient (e.g. shared memory).
## Request & Reply
This topology contains two devices that communicate with each other via the **REQ-REP** pettern. Bidirectional communication via a single socket.

View File

@@ -7,12 +7,12 @@
################################################################################
add_library(ExampleDDSLib 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(ExampleDDSLib PUBLIC FairMQ)
@@ -28,6 +28,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(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)
@@ -37,23 +38,25 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh @ONLY)
# test
add_test(NAME Example.DDS.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh localhost)
set_tests_properties(Example.DDS.localhost PROPERTIES
TIMEOUT 15
RUN_SERIAL true
PASS_REGULAR_EXPRESSION "Example successful"
)
if(DDS_FOUND)
add_test(NAME Example.DDS.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh localhost)
set_tests_properties(Example.DDS.localhost PROPERTIES
TIMEOUT 15
RUN_SERIAL true
PASS_REGULAR_EXPRESSION "Example successful"
)
endif()
# install
install(
TARGETS
fairmq-ex-dds-sampler
fairmq-ex-dds-processor
fairmq-ex-dds-sink
TARGETS
fairmq-ex-dds-sampler
fairmq-ex-dds-processor
fairmq-ex-dds-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
@@ -65,30 +68,30 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install @ONLY)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-dds-topology.xml
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-dds-topology.xml
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-dds-topology-infinite.xml
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-dds-topology-infinite.xml
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg
DESTINATION ${PROJECT_INSTALL_DATADIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg
DESTINATION ${PROJECT_INSTALL_DATADIR}
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-ex-dds-env.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-ex-dds-env.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-dds.sh
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-dds.sh
)

View File

@@ -1,7 +1,7 @@
<topology name="ExampleDDS">
<property name="data1" />
<property name="data2" />
<property name="fmqchan_data1" />
<property name="fmqchan_data2" />
<declrequirement name="SamplerWorker" type="wnname" value="sampler"/>
<declrequirement name="ProcessorWorker" type="wnname" value="processor"/>
@@ -14,7 +14,7 @@
<name>SamplerWorker</name>
</requirements>
<properties>
<name access="write">data1</name>
<name access="write">fmqchan_data1</name>
</properties>
</decltask>
@@ -25,8 +25,8 @@
<name>ProcessorWorker</name>
</requirements>
<properties>
<name access="read">data1</name>
<name access="read">data2</name>
<name access="read">fmqchan_data1</name>
<name access="read">fmqchan_data2</name>
</properties>
</decltask>
@@ -37,7 +37,7 @@
<name>SinkWorker</name>
</requirements>
<properties>
<name access="write">data2</name>
<name access="write">fmqchan_data2</name>
</properties>
</decltask>

View File

@@ -1,7 +1,7 @@
<topology name="ExampleDDS">
<property name="data1" />
<property name="data2" />
<property name="fmqchan_data1" />
<property name="fmqchan_data2" />
<declrequirement name="SamplerWorker" type="wnname" value="sampler"/>
<declrequirement name="ProcessorWorker" type="wnname" value="processor"/>
@@ -14,7 +14,7 @@
<name>SamplerWorker</name>
</requirements>
<properties>
<name access="write">data1</name>
<name access="write">fmqchan_data1</name>
</properties>
</decltask>
@@ -25,8 +25,8 @@
<name>ProcessorWorker</name>
</requirements>
<properties>
<name access="read">data1</name>
<name access="read">data2</name>
<name access="read">fmqchan_data1</name>
<name access="read">fmqchan_data2</name>
</properties>
</decltask>
@@ -37,7 +37,7 @@
<name>SinkWorker</name>
</requirements>
<properties>
<name access="write">data2</name>
<name access="write">fmqchan_data2</name>
</properties>
</decltask>

View File

@@ -9,3 +9,8 @@
################################################################################
export PATH=@BIN_DIR@:$PATH
OS=$(uname -s 2>&1)
if [ "$OS" == "Darwin" ]; then
export DYLD_LIBRARY_PATH=@LIB_DIR@:$DYLD_LIBRARY_PATH
fi

View File

@@ -30,52 +30,49 @@ echo "SESSION ID: ${DDS_SESSION_ID}"
trap "cleanup ${DDS_SESSION_ID}" EXIT
requiredNofAgents=12
requiredNofSlots=12
if [[ "$plugin" == "ssh" ]]; then
dds-submit -r ${plugin} -c @DATA_DIR@/ex-dds-hosts.cfg
else
dds-submit -r ${plugin} -n ${requiredNofAgents}
dds-submit -r ${plugin} --slots ${requiredNofSlots}
fi
echo "...waiting for ${requiredNofAgents} idle agents..."
dds-info --wait-for-idle-agents ${requiredNofAgents}
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
topologyFile=@DATA_DIR@/ex-dds-topology.xml
echo "TOPOLOGY FILE: ${topologyFile}"
# TODO Uncomment once DDS 2.6 is released
# echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${topologyFile})"
export FAIRMQ_DDS_TOPO_FILE=@DATA_DIR@/ex-dds-topology.xml
echo "TOPOLOGY FILE: ${FAIRMQ_DDS_TOPO_FILE}"
echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${FAIRMQ_DDS_TOPO_FILE})"
# TODO Uncomment once DDS 2.6 is released
# dds-info --active-topology
dds-topology --activate ${topologyFile}
# dds-info --active-topology
# dds-info --wait-for-executing-agents ${requiredNofAgents}
sleep 1
dds-info --active-topology
dds-topology --activate ${FAIRMQ_DDS_TOPO_FILE}
dds-info --active-topology
echo "...waiting for ${requiredNofSlots} executing slots..."
dds-info --executing-count --wait ${requiredNofSlots}
echo "------------------------"
echo "...waiting for Topology to finish..."
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
fairmq-dds-command-ui -w "IDLE" -n ${requiredNofAgents}
fairmq-dds-command-ui -c i -w "INITIALIZING DEVICE" -n ${requiredNofAgents}
fairmq-dds-command-ui -c k -w "INITIALIZED" -n ${requiredNofAgents}
fairmq-dds-command-ui -c b -w "BOUND" -n ${requiredNofAgents}
fairmq-dds-command-ui -c x -w "DEVICE READY" -n ${requiredNofAgents}
fairmq-dds-command-ui -c j -w "READY" -n ${requiredNofAgents}
fairmq-dds-command-ui -w "IDLE"
fairmq-dds-command-ui -c i
fairmq-dds-command-ui -c k
fairmq-dds-command-ui -c b
fairmq-dds-command-ui -c x
fairmq-dds-command-ui -c j
fairmq-dds-command-ui -c r
sampler_and_sink="main/(Sampler|Sink)"
fairmq-dds-command-ui -p $sampler_and_sink -w "RUNNING->READY" -n 2
sampler_and_sink="main/(Sampler|Sink).*"
fairmq-dds-command-ui -w "RUNNING->READY" -p $sampler_and_sink
echo "...$sampler_and_sink are READY, sending shutdown..."
fairmq-dds-command-ui -c s -w "RUNNING->READY" -n ${requiredNofAgents}
fairmq-dds-command-ui -c t -w "DEVICE READY" -n ${requiredNofAgents}
fairmq-dds-command-ui -c d -w "IDLE" -n ${requiredNofAgents}
fairmq-dds-command-ui -c s
fairmq-dds-command-ui -c t
fairmq-dds-command-ui -c d
fairmq-dds-command-ui -c q
echo "...waiting for ${requiredNofAgents} idle agents..."
dds-info --wait-for-idle-agents ${requiredNofAgents}
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
echo "------------------------"
# TODO Uncomment once DDS 2.6 is released
# dds-info --active-topology
dds-info --active-topology
dds-topology --stop
# dds-info --active-topology
dds-info --active-topology
dds-agent-cmd getlog -a
logDir="${wrkDir}/logs"

View File

@@ -32,19 +32,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMA
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh)
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 5 parts")
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 5 parts")
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 5 parts")
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
if(BUILD_OFI_TRANSPORT)
add_test(NAME Example.Multipart.ofi COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh ofi)
set_tests_properties(Example.Multipart.ofi PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 5 parts")
set_tests_properties(Example.Multipart.ofi PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
endif()
# install

View File

@@ -40,8 +40,7 @@ bool Sampler::ConditionalRun()
header.stopFlag = 0;
// Set stopFlag to 1 for last message.
if (fMaxIterations > 0 && fNumIterations == fMaxIterations - 1)
{
if (fMaxIterations > 0 && fNumIterations == fMaxIterations - 1) {
header.stopFlag = 1;
}
LOG(info) << "Sending header with stopFlag: " << header.stopFlag;
@@ -60,13 +59,20 @@ bool Sampler::ConditionalRun()
assert(auxData.Size() == 0);
assert(parts.Size() == 5);
parts.AddPart(NewMessage());
assert(parts.Size() == 6);
parts.AddPart(NewMessage(100));
assert(parts.Size() == 7);
LOG(info) << "Sending body of size: " << parts.At(1)->GetSize();
Send(parts, "data");
// Go out of the sending loop if the stopFlag was sent.
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
{
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
return false;
}
@@ -77,8 +83,4 @@ bool Sampler::ConditionalRun()
return true;
}
Sampler::~Sampler()
{
}
} // namespace example_multipart

View File

@@ -24,7 +24,7 @@ class Sampler : public FairMQDevice
{
public:
Sampler();
virtual ~Sampler();
virtual ~Sampler() {}
protected:
virtual void InitTask();

View File

@@ -20,23 +20,28 @@ using namespace std;
namespace example_multipart
{
Sink::Sink()
{
OnData("data", &Sink::HandleData);
}
bool Sink::HandleData(FairMQParts& parts, int /*index*/)
{
LOG(info) << "Received message with " << parts.Size() << " parts";
Header header;
header.stopFlag = (static_cast<Header*>(parts.At(0)->GetData()))->stopFlag;
LOG(info) << "Received message with " << parts.Size() << " parts";
LOG(info) << "Received part 1 (header) with stopFlag: " << header.stopFlag;
LOG(info) << "Received part 2 of size: " << parts.At(1)->GetSize();
assert(parts.At(1)->GetSize() == 1000);
LOG(info) << "Received part 3 of size: " << parts.At(2)->GetSize();
assert(parts.At(2)->GetSize() == 500);
LOG(info) << "Received part 4 of size: " << parts.At(3)->GetSize();
assert(parts.At(3)->GetSize() == 600);
LOG(info) << "Received part 5 of size: " << parts.At(4)->GetSize();
assert(parts.At(4)->GetSize() == 700);
LOG(info) << "Received part 6 of size: " << parts.At(5)->GetSize();
assert(parts.At(5)->GetSize() == 0);
LOG(info) << "Received part 7 of size: " << parts.At(6)->GetSize();
assert(parts.At(6)->GetSize() == 100);
LOG(info) << "Received header with stopFlag: " << header.stopFlag;
LOG(info) << "Received body of size: " << parts.At(1)->GetSize();
if (header.stopFlag == 1)
{
if (header.stopFlag == 1) {
LOG(info) << "stopFlag is 1, going IDLE";
return false;
}
@@ -44,8 +49,4 @@ bool Sink::HandleData(FairMQParts& parts, int /*index*/)
return true;
}
Sink::~Sink()
{
}
}

View File

@@ -23,8 +23,8 @@ namespace example_multipart
class Sink : public FairMQDevice
{
public:
Sink();
virtual ~Sink();
Sink() { OnData("data", &Sink::HandleData); }
virtual ~Sink() {}
protected:
bool HandleData(FairMQParts&, int);

View File

@@ -2,12 +2,24 @@
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
transport="zeromq"
if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1
fi
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
SAMPLER="fairmq-ex-multipart-sampler"
SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --channel-config name=data,type=push,method=connect,rateLogging=0,address=tcp://127.0.0.1:5555"
xterm -geometry 80x23+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
SINK="fairmq-ex-multipart-sink"
SINK+=" --id sink1"
SINK+=" --transport $transport"
SINK+=" --session $SESSION"
SINK+=" --channel-config name=data,type=pull,method=bind,rateLogging=0,address=tcp://127.0.0.1:5555"
xterm -geometry 80x23+500+0 -hold -e @EX_BIN_DIR@/$SINK &

View File

@@ -20,7 +20,7 @@ SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --max-iterations 1"
SAMPLER+=" --control static --color false"
SAMPLER+=" --channel-config name=data,type=pair,method=connect,rateLogging=0,address=tcp://127.0.0.1:5555"
SAMPLER+=" --channel-config name=data,type=pair,method=connect,rateLogging=0,address=tcp://127.0.0.1:5555,linger=1000"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$!

View File

@@ -0,0 +1,99 @@
################################################################################
# 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" #
################################################################################
add_executable(fairmq-ex-n-m-synchronizer runSynchronizer.cxx)
target_link_libraries(fairmq-ex-n-m-synchronizer PRIVATE FairMQ)
add_executable(fairmq-ex-n-m-sender runSender.cxx)
target_link_libraries(fairmq-ex-n-m-sender PRIVATE FairMQ)
add_executable(fairmq-ex-n-m-receiver runReceiver.cxx)
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(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)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-n-m-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-n-m-env.sh @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m.sh @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-pair.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair.sh @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-dds.sh @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-pair-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair-dds.sh @ONLY)
# test
if(DDS_FOUND)
add_test(NAME Example.N-M.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-dds.sh localhost)
set_tests_properties(Example.N-M.localhost PROPERTIES TIMEOUT 15 RUN_SERIAL true PASS_REGULAR_EXPRESSION "Example successful")
add_test(NAME Example.N-M-pair.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair-dds.sh localhost)
set_tests_properties(Example.N-M-pair.localhost PROPERTIES TIMEOUT 15 RUN_SERIAL true PASS_REGULAR_EXPRESSION "Example successful")
endif()
# install
install(
TARGETS
fairmq-ex-n-m-synchronizer
fairmq-ex-n-m-sender
fairmq-ex-n-m-receiver
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(DATA_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-topology.xml_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-pair-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-pair-topology.xml_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-n-m-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-n-m-env.sh_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m.sh_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-pair.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair.sh_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-dds.sh_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-n-m-pair-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair-dds.sh_install @ONLY)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-topology.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-n-m-topology.xml
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-pair-topology.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-n-m-pair-topology.xml
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-n-m-env.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-ex-n-m-env.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-n-m.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-n-m-pair.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-dds.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-n-m-dds.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-n-m-pair-dds.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-n-m-pair-dds.sh
)

24
examples/n-m/Header.h Normal file
View File

@@ -0,0 +1,24 @@
/********************************************************************************
* 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 FAIR_MQ_EXAMPLE_N_M_HEADER_H
#define FAIR_MQ_EXAMPLE_N_M_HEADER_H
#include <cstdint>
namespace example_n_m
{
struct Header
{
std::uint16_t id;
int senderIndex;
};
} // namespace example_n_m
#endif /* FAIR_MQ_EXAMPLE_N_M_HEADER_H */

4
examples/n-m/README.md Normal file
View File

@@ -0,0 +1,4 @@
N-M
==========================
A topology consisting of three layers of devices: synchronizer -> sender(s) -> receiver(s). Senders distribute data to receivers based on the data id contained in the message from the synchronizer (same id goes to the same receiver from every sender). The senders send the data in a non-blocking fashion - if queue is full or receiver is down, data is discarded. Two configurations are provided - one using push/pull channels between senders/receivers, another using pair channels. In push/pull case there is only one receiving channel on the receiver device. In pair case there are as many receiver (sub-)channels as there are senders.

View File

@@ -0,0 +1,44 @@
<topology name="myTopology">
<var name="numSenders" value="3" />
<var name="numReceivers" value="4" />
<property name="fmqchan_sync" />
<property name="fmqchan_data" />
<decltask name="Synchronizer">
<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>
</properties>
</decltask>
<decltask name="Sender">
<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>
</properties>
</decltask>
<decltask name="Receiver">
<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>
</properties>
</decltask>
<main name="main">
<task>Synchronizer</task>
<group name="Senders" n="${numSenders}">
<task>Sender</task>
</group>
<group name="Receivers" n="${numReceivers}">
<task>Receiver</task>
</group>
</main>
</topology>

View File

@@ -0,0 +1,44 @@
<topology name="myTopology">
<var name="numSenders" value="3" />
<var name="numReceivers" value="4" />
<property name="fmqchan_sync" />
<property name="fmqchan_data" />
<decltask name="Synchronizer">
<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>
</properties>
</decltask>
<decltask name="Sender">
<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>
</properties>
</decltask>
<decltask name="Receiver">
<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>
</properties>
</decltask>
<main name="main">
<task>Synchronizer</task>
<group name="Senders" n="${numSenders}">
<task>Sender</task>
</group>
<group name="Receivers" n="${numReceivers}">
<task>Receiver</task>
</group>
</main>
</topology>

View File

@@ -0,0 +1,16 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019 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" #
################################################################################
export PATH=@BIN_DIR@:$PATH
OS=$(uname -s 2>&1)
if [ "$OS" == "Darwin" ]; then
export DYLD_LIBRARY_PATH=@LIB_DIR@:$DYLD_LIBRARY_PATH
fi

View File

@@ -0,0 +1,76 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019 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 -e
cleanup() {
dds-session stop $1
echo "CLEANUP PERFORMED"
}
source @DDS_INSTALL_PREFIX@/DDS_env.sh
export PATH=@BIN_DIR@:$PATH
exec 5>&1
output=$(dds-session start | tee >(cat - >&5))
export DDS_SESSION_ID=$(echo ${output} | grep "DDS session ID: " | cut -d' ' -f4)
echo "SESSION ID: ${DDS_SESSION_ID}"
trap "cleanup ${DDS_SESSION_ID}" EXIT
requiredNofSlots=8
dds-submit -r localhost --slots ${requiredNofSlots}
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
export FAIRMQ_DDS_TOPO_FILE=@DATA_DIR@/ex-n-m-topology.xml
echo "TOPOLOGY FILE: ${FAIRMQ_DDS_TOPO_FILE}"
echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${FAIRMQ_DDS_TOPO_FILE})"
dds-info --active-topology
dds-topology --activate ${FAIRMQ_DDS_TOPO_FILE}
dds-info --active-topology
echo "...waiting for ${requiredNofSlots} executing slots..."
dds-info --executing-count --wait ${requiredNofSlots}
echo "------------------------"
echo "...waiting for Topology to finish..."
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
fairmq-dds-command-ui -w "IDLE"
fairmq-dds-command-ui -c i
fairmq-dds-command-ui -c k
fairmq-dds-command-ui -c b
fairmq-dds-command-ui -c x
fairmq-dds-command-ui -c j
fairmq-dds-command-ui -c r
receivers="main/Receivers.*"
fairmq-dds-command-ui -w "RUNNING->READY" -p $receivers
echo "All receivers transitioned from RUNNING to READY"
fairmq-dds-command-ui -c s
fairmq-dds-command-ui -c t
fairmq-dds-command-ui -c d
fairmq-dds-command-ui -c q
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
echo "------------------------"
dds-info --active-topology
dds-topology --stop
dds-info --active-topology
dds-agent-cmd getlog -a
logDir="${wrkDir}/logs"
for file in $(find "${logDir}" -name "*.tar.gz"); do tar -xf ${file} -C "${logDir}" ; done
echo "AGENT LOG FILES IN: ${logDir}"
# This string is used by ctest to detect success
echo "Example successful :)"
# Cleanup function is called by EXIT trap

View File

@@ -0,0 +1,76 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019 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 -e
cleanup() {
dds-session stop $1
echo "CLEANUP PERFORMED"
}
source @DDS_INSTALL_PREFIX@/DDS_env.sh
export PATH=@BIN_DIR@:$PATH
exec 5>&1
output=$(dds-session start | tee >(cat - >&5))
export DDS_SESSION_ID=$(echo ${output} | grep "DDS session ID: " | cut -d' ' -f4)
echo "SESSION ID: ${DDS_SESSION_ID}"
trap "cleanup ${DDS_SESSION_ID}" EXIT
requiredNofSlots=8
dds-submit -r localhost --slots ${requiredNofSlots}
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
export FAIRMQ_DDS_TOPO_FILE=@DATA_DIR@/ex-n-m-pair-topology.xml
echo "TOPOLOGY FILE: ${FAIRMQ_DDS_TOPO_FILE}"
echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${FAIRMQ_DDS_TOPO_FILE})"
dds-info --active-topology
dds-topology --activate ${FAIRMQ_DDS_TOPO_FILE}
dds-info --active-topology
echo "...waiting for ${requiredNofSlots} executing slots..."
dds-info --executing-count --wait ${requiredNofSlots}
echo "------------------------"
echo "...waiting for Topology to finish..."
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
fairmq-dds-command-ui -w "IDLE"
fairmq-dds-command-ui -c i
fairmq-dds-command-ui -c k
fairmq-dds-command-ui -c b
fairmq-dds-command-ui -c x
fairmq-dds-command-ui -c j
fairmq-dds-command-ui -c r
receivers="main/Receivers.*"
fairmq-dds-command-ui -w "RUNNING->READY" -p $receivers
echo "All receivers transitioned from RUNNING to READY"
fairmq-dds-command-ui -c s
fairmq-dds-command-ui -c t
fairmq-dds-command-ui -c d
fairmq-dds-command-ui -c q
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
echo "------------------------"
dds-info --active-topology
dds-topology --stop
dds-info --active-topology
dds-agent-cmd getlog -a
logDir="${wrkDir}/logs"
for file in $(find "${logDir}" -name "*.tar.gz"); do tar -xf ${file} -C "${logDir}" ; done
echo "AGENT LOG FILES IN: ${logDir}"
# This string is used by ctest to detect success
echo "Example successful :)"
# Cleanup function is called by EXIT trap

View File

@@ -0,0 +1,60 @@
#!/bin/bash
export PATH=@BIN_DIR@:$PATH
SYNC="fairmq-ex-n-m-synchronizer"
SYNC+=" --id Sync"
SYNC+=" --channel-config name=sync,type=pub,method=bind,address=tcp://localhost:8010"
SYNC+=" --rate 100"
xterm -geometry 80x25+0+0 -hold -e $SYNC &
SENDER0="fairmq-ex-n-m-sender"
SENDER0+=" --id Sender1"
SENDER0+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER0+=" name=data,type=pair,method=connect,address=tcp://localhost:8021,address=tcp://localhost:8022,address=tcp://localhost:8023,address=tcp://localhost:8024"
SENDER0+=" --sender-index 0"
SENDER0+=" --subtimeframe-size 1000000"
SENDER0+=" --num-receivers 4"
xterm -geometry 80x25+500+0 -hold -e $SENDER0 &
SENDER1="fairmq-ex-n-m-sender"
SENDER1+=" --id Sender2"
SENDER1+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER1+=" name=data,type=pair,method=connect,address=tcp://localhost:8031,address=tcp://localhost:8032,address=tcp://localhost:8033,address=tcp://localhost:8034"
SENDER1+=" --sender-index 1"
SENDER1+=" --subtimeframe-size 1000000"
SENDER1+=" --num-receivers 4"
xterm -geometry 80x25+500+350 -hold -e $SENDER1 &
SENDER2="fairmq-ex-n-m-sender"
SENDER2+=" --id Sender3"
SENDER2+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER2+=" name=data,type=pair,method=connect,address=tcp://localhost:8041,address=tcp://localhost:8042,address=tcp://localhost:8043,address=tcp://localhost:8044"
SENDER2+=" --sender-index 2"
SENDER2+=" --subtimeframe-size 1000000"
SENDER2+=" --num-receivers 4"
xterm -geometry 80x25+500+700 -hold -e $SENDER2 &
RECEIVER0="fairmq-ex-n-m-receiver"
RECEIVER0+=" --id Receiver1"
RECEIVER0+=" --channel-config name=data,type=pair,method=bind,address=tcp://localhost:8021,address=tcp://localhost:8031,address=tcp://localhost:8041"
RECEIVER0+=" --num-senders 3"
xterm -geometry 80x25+1000+0 -hold -e $RECEIVER0 &
RECEIVER1="fairmq-ex-n-m-receiver"
RECEIVER1+=" --id Receiver2"
RECEIVER1+=" --channel-config name=data,type=pair,method=bind,address=tcp://localhost:8022,address=tcp://localhost:8032,address=tcp://localhost:8042"
RECEIVER1+=" --num-senders 3"
xterm -geometry 80x25+1000+350 -hold -e $RECEIVER1 &
RECEIVER2="fairmq-ex-n-m-receiver"
RECEIVER2+=" --id Receiver3"
RECEIVER2+=" --channel-config name=data,type=pair,method=bind,address=tcp://localhost:8023,address=tcp://localhost:8033,address=tcp://localhost:8043"
RECEIVER2+=" --num-senders 3"
xterm -geometry 80x25+1000+700 -hold -e $RECEIVER2 &
RECEIVER3="fairmq-ex-n-m-receiver"
RECEIVER3+=" --id Receiver4"
RECEIVER3+=" --channel-config name=data,type=pair,method=bind,address=tcp://localhost:8024,address=tcp://localhost:8034,address=tcp://localhost:8044"
RECEIVER3+=" --num-senders 3"
xterm -geometry 80x25+1000+1050 -hold -e $RECEIVER3 &

View File

@@ -0,0 +1,60 @@
#!/bin/bash
export PATH=@BIN_DIR@:$PATH
SYNC="fairmq-ex-n-m-synchronizer"
SYNC+=" --id Sync"
SYNC+=" --channel-config name=sync,type=pub,method=bind,address=tcp://localhost:8010"
SYNC+=" --rate 100"
xterm -geometry 80x25+0+0 -hold -e $SYNC &
SENDER0="fairmq-ex-n-m-sender"
SENDER0+=" --id Sender1"
SENDER0+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER0+=" name=data,type=push,method=connect,address=tcp://localhost:8021,address=tcp://localhost:8022,address=tcp://localhost:8023,address=tcp://localhost:8024"
SENDER0+=" --sender-index 0"
SENDER0+=" --subtimeframe-size 1000000"
SENDER0+=" --num-receivers 4"
xterm -geometry 80x25+500+0 -hold -e $SENDER0 &
SENDER1="fairmq-ex-n-m-sender"
SENDER1+=" --id Sender2"
SENDER1+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER1+=" name=data,type=push,method=connect,address=tcp://localhost:8021,address=tcp://localhost:8022,address=tcp://localhost:8023,address=tcp://localhost:8024"
SENDER1+=" --sender-index 1"
SENDER1+=" --subtimeframe-size 1000000"
SENDER1+=" --num-receivers 4"
xterm -geometry 80x25+500+350 -hold -e $SENDER1 &
SENDER2="fairmq-ex-n-m-sender"
SENDER2+=" --id Sender3"
SENDER2+=" --channel-config name=sync,type=sub,method=connect,address=tcp://localhost:8010"
SENDER2+=" name=data,type=push,method=connect,address=tcp://localhost:8021,address=tcp://localhost:8022,address=tcp://localhost:8023,address=tcp://localhost:8024"
SENDER2+=" --sender-index 2"
SENDER2+=" --subtimeframe-size 1000000"
SENDER2+=" --num-receivers 4"
xterm -geometry 80x25+500+700 -hold -e $SENDER2 &
RECEIVER0="fairmq-ex-n-m-receiver"
RECEIVER0+=" --id Receiver1"
RECEIVER0+=" --channel-config name=data,type=pull,method=bind,address=tcp://localhost:8021"
RECEIVER0+=" --num-senders 3"
xterm -geometry 80x25+1000+0 -hold -e $RECEIVER0 &
RECEIVER1="fairmq-ex-n-m-receiver"
RECEIVER1+=" --id Receiver2"
RECEIVER1+=" --channel-config name=data,type=pull,method=bind,address=tcp://localhost:8022"
RECEIVER1+=" --num-senders 3"
xterm -geometry 80x25+1000+350 -hold -e $RECEIVER1 &
RECEIVER2="fairmq-ex-n-m-receiver"
RECEIVER2+=" --id Receiver3"
RECEIVER2+=" --channel-config name=data,type=pull,method=bind,address=tcp://localhost:8023"
RECEIVER2+=" --num-senders 3"
xterm -geometry 80x25+1000+700 -hold -e $RECEIVER2 &
RECEIVER3="fairmq-ex-n-m-receiver"
RECEIVER3+=" --id Receiver4"
RECEIVER3+=" --channel-config name=data,type=pull,method=bind,address=tcp://localhost:8024"
RECEIVER3+=" --num-senders 3"
xterm -geometry 80x25+1000+1050 -hold -e $RECEIVER3 &

View File

@@ -0,0 +1,119 @@
/********************************************************************************
* 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" *
********************************************************************************/
#include "Header.h"
#include <FairMQDevice.h>
#include <runFairMQDevice.h>
#include <string>
#include <iomanip>
#include <chrono>
#include <string>
#include <unordered_map>
#include <unordered_set>
using namespace std;
using namespace example_n_m;
namespace bpo = boost::program_options;
struct TFBuffer
{
FairMQParts parts;
chrono::steady_clock::time_point start;
chrono::steady_clock::time_point end;
};
class Receiver : public FairMQDevice
{
public:
Receiver()
: fBuffer()
, fDiscardedSet()
, fNumSenders(0)
, fBufferTimeoutInMs(5000)
, fMaxTimeframes(0)
, fTimeframeCounter(0)
{
OnData("data", &Receiver::HandleData);
}
~Receiver() = default;
void InitTask() override
{
fNumSenders = GetConfig()->GetValue<int>("num-senders");
fBufferTimeoutInMs = GetConfig()->GetValue<int>("buffer-timeout");
fMaxTimeframes = GetConfig()->GetValue<int>("max-timeframes");
}
protected:
bool HandleData(FairMQParts& parts, int /* index */)
{
Header& h = *(static_cast<Header*>(parts.At(0)->GetData()));
// LOG(info) << "Received sub-time frame #" << h.id << " from Sender" << h.senderIndex;
if (fDiscardedSet.find(h.id) == fDiscardedSet.end()) {
if (fBuffer.find(h.id) == fBuffer.end()) {
// if this is the first part with this ID, save the receive time.
fBuffer[h.id].start = chrono::steady_clock::now();
}
// if the received ID has not previously been discarded, store the data part in the buffer
fBuffer[h.id].parts.AddPart(move(parts.At(1)));
} else {
// if received ID has been previously discarded.
LOG(debug) << "Received part from an already discarded timeframe with id " << h.id;
}
if (fBuffer[h.id].parts.Size() == fNumSenders) {
LOG(info) << "Successfully completed timeframe #" << h.id;
fBuffer.erase(h.id);
if (fMaxTimeframes > 0 && ++fTimeframeCounter >= fMaxTimeframes) {
LOG(info) << "Reached configured maximum number of timeframes (" << fMaxTimeframes << "). Exiting RUNNING state.";
return false;
}
}
return true;
}
void DiscardIncompleteTimeframes()
{
auto it = fBuffer.begin();
while (it != fBuffer.end()) {
if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - (it->second).start).count() > fBufferTimeoutInMs) {
LOG(debug) << "Timeframe #" << it->first << " incomplete after " << fBufferTimeoutInMs << " milliseconds, discarding";
fDiscardedSet.insert(it->first);
fBuffer.erase(it++);
LOG(debug) << "Number of discarded timeframes: " << fDiscardedSet.size();
} else {
// LOG(info) << "Timeframe #" << it->first << " within timeout, buffering...";
++it;
}
}
}
unordered_map<uint16_t, TFBuffer> fBuffer;
unordered_set<uint16_t> fDiscardedSet;
int fNumSenders;
int fBufferTimeoutInMs;
int fMaxTimeframes;
int fTimeframeCounter;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("buffer-timeout", bpo::value<int>()->default_value(1000), "Buffer timeout in milliseconds")
("num-senders", bpo::value<int>()->required(), "Number of senders")
("max-timeframes", bpo::value<int>()->default_value(0), "Maximum number of timeframes to receive (0 - unlimited)");
}
FairMQDevice* getDevice(const FairMQProgOptions& /* config */) { return new Receiver(); }

View File

@@ -0,0 +1,79 @@
/********************************************************************************
* 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" *
********************************************************************************/
#include "Header.h"
#include <FairMQDevice.h>
#include <runFairMQDevice.h>
#include <string>
using namespace std;
using namespace example_n_m;
namespace bpo = boost::program_options;
class Sender : public FairMQDevice
{
public:
Sender()
: fNumReceivers(0)
, fIndex(0)
, fSubtimeframeSize(10000)
{}
~Sender() = default;
protected:
void InitTask() override
{
fIndex = GetConfig()->GetProperty<int>("sender-index");
fSubtimeframeSize = GetConfig()->GetProperty<int>("subtimeframe-size");
fNumReceivers = GetConfig()->GetProperty<int>("num-receivers");
}
void Run() override
{
FairMQChannel& dataInChannel = fChannels.at("sync").at(0);
while (!NewStatePending()) {
Header h;
FairMQMessagePtr id(NewMessage());
if (dataInChannel.Receive(id) > 0) {
h.id = *(static_cast<uint16_t*>(id->GetData()));
h.senderIndex = fIndex;
} else {
continue;
}
FairMQParts parts;
parts.AddPart(NewSimpleMessage(h));
parts.AddPart(NewMessage(fSubtimeframeSize));
uint64_t currentDataId = h.id;
int direction = currentDataId % fNumReceivers;
if (Send(parts, "data", direction, 0) < 0) {
LOG(debug) << "Failed to queue Subtimeframe #" << currentDataId << " to Receiver[" << direction << "]";
}
}
}
private:
int fNumReceivers;
unsigned int fIndex;
int fSubtimeframeSize;
};
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("sender-index", bpo::value<int>()->default_value(0), "Sender Index")
("subtimeframe-size", bpo::value<int>()->default_value(1000), "Subtimeframe size in bytes")
("num-receivers", bpo::value<int>()->required(), "Number of EPNs");
}
FairMQDevice* getDevice(const FairMQProgOptions& /* config */) { return new Sender(); }

View File

@@ -0,0 +1,46 @@
/********************************************************************************
* 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" *
********************************************************************************/
#include <FairMQDevice.h>
#include <runFairMQDevice.h>
#include <string>
#include <cstdint>
using namespace std;
namespace bpo = boost::program_options;
class Synchronizer : public FairMQDevice
{
public:
Synchronizer()
: fTimeframeId(0)
{}
~Synchronizer() = default;
protected:
bool ConditionalRun() override
{
FairMQMessagePtr msg(NewSimpleMessage(fTimeframeId));
if (Send(msg, "sync") > 0) {
if (++fTimeframeId == UINT16_MAX - 1) {
fTimeframeId = 0;
}
} else {
return false;
}
return true;
}
uint16_t fTimeframeId;
};
void addCustomOptions(bpo::options_description& /* options */) {}
FairMQDevice* getDevice(const FairMQProgOptions& /* config */) { return new Synchronizer(); }

View File

@@ -0,0 +1,71 @@
################################################################################
# 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" #
################################################################################
add_executable(fairmq-ex-qc-sampler runSampler.cxx)
target_link_libraries(fairmq-ex-qc-sampler PRIVATE FairMQ)
add_executable(fairmq-ex-qc-dispatcher runQCDispatcher.cxx)
target_link_libraries(fairmq-ex-qc-dispatcher PRIVATE FairMQ)
add_executable(fairmq-ex-qc-task runQCTask.cxx)
target_link_libraries(fairmq-ex-qc-task PRIVATE FairMQ)
add_executable(fairmq-ex-qc-sink runSink.cxx)
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(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)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-qc.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-qc.sh @ONLY)
# test
if(DDS_FOUND)
add_test(NAME Example.QC.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-qc.sh localhost)
set_tests_properties(Example.QC.localhost PROPERTIES TIMEOUT 15 RUN_SERIAL true PASS_REGULAR_EXPRESSION "Example successful")
endif()
# install
install(
TARGETS
fairmq-ex-qc-sampler
fairmq-ex-qc-dispatcher
fairmq-ex-qc-task
fairmq-ex-qc-sink
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
)
# configure run script with different executable paths for build and for install directories
set(BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
set(DATA_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-qc-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-qc-topology.xml_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-qc-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-qc-env.sh_install @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-qc.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-qc.sh_install @ONLY)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-qc-topology.xml_install
DESTINATION ${PROJECT_INSTALL_DATADIR}
RENAME ex-qc-topology.xml
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-qc-env.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-ex-qc-env.sh
)
install(
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-qc.sh_install
DESTINATION ${PROJECT_INSTALL_BINDIR}
RENAME fairmq-start-ex-qc.sh
)

4
examples/qc/README.md Normal file
View File

@@ -0,0 +1,4 @@
QC
==
A topology consisting of 4 devices - Sampler, QCDispatcher, QCTask and Sink. The data flows from Sampler through QCDispatcher to Sink. On demand - by setting the corresponding configuration property - the QCDispatcher device will duplicate the data to the QCTask device. The property is set by the topology controller, in this example this is the `fairmq-dds-command-ui` utility.

View File

@@ -0,0 +1,48 @@
<topology name="ExampleQC">
<property name="fmqchan_data1" />
<property name="fmqchan_data2" />
<property name="fmqchan_qc" />
<decltask name="Sampler">
<exe>fairmq-ex-qc-sampler --color false --channel-config name=data1,type=push,method=bind -P dds --max-iterations 1000</exe>
<env reachable="false">fairmq-ex-qc-env.sh</env>
<properties>
<name access="write">fmqchan_data1</name>
</properties>
</decltask>
<decltask name="QCDispatcher">
<exe>fairmq-ex-qc-dispatcher --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect name=qc,type=push,method=connect -P dds</exe>
<env reachable="false">fairmq-ex-qc-env.sh</env>
<properties>
<name access="read">fmqchan_data1</name>
<name access="read">fmqchan_data2</name>
<name access="read">fmqchan_qc</name>
</properties>
</decltask>
<decltask name="QCTask">
<exe>fairmq-ex-qc-task --color false --channel-config name=qc,type=pull,method=bind -P dds</exe>
<env reachable="false">fairmq-ex-qc-env.sh</env>
<properties>
<name access="write">fmqchan_qc</name>
</properties>
</decltask>
<decltask name="Sink">
<exe>fairmq-ex-qc-sink --color false --channel-config name=data2,type=pull,method=bind -P dds --max-iterations 1000</exe>
<env reachable="false">fairmq-ex-qc-env.sh</env>
<properties>
<name access="write">fmqchan_data2</name>
</properties>
</decltask>
<main name="main">
<task>Sampler</task>
<task>QCDispatcher</task>
<task>QCTask</task>
<task>Sink</task>
</main>
</topology>

16
examples/qc/fairmq-ex-qc-env.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019 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" #
################################################################################
export PATH=@BIN_DIR@:$PATH
OS=$(uname -s 2>&1)
if [ "$OS" == "Darwin" ]; then
export DYLD_LIBRARY_PATH=@LIB_DIR@:$DYLD_LIBRARY_PATH
fi

View File

@@ -0,0 +1,82 @@
#!/bin/bash
################################################################################
# Copyright (C) 2019 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" #
################################################################################
# fairmq-start-ex-qc.sh -> submit agents with localhost plugin
set -e
cleanup() {
dds-session stop $1
echo "CLEANUP PERFORMED"
}
source @DDS_INSTALL_PREFIX@/DDS_env.sh
export PATH=@BIN_DIR@:$PATH
exec 5>&1
output=$(dds-session start | tee >(cat - >&5))
export DDS_SESSION_ID=$(echo ${output} | grep "DDS session ID: " | cut -d' ' -f4)
echo "SESSION ID: ${DDS_SESSION_ID}"
trap "cleanup ${DDS_SESSION_ID}" EXIT
requiredNofSlots=4
dds-submit -r localhost --slots ${requiredNofSlots}
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
export FAIRMQ_DDS_TOPO_FILE=@DATA_DIR@/ex-qc-topology.xml
echo "TOPOLOGY FILE: ${FAIRMQ_DDS_TOPO_FILE}"
echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${FAIRMQ_DDS_TOPO_FILE})"
dds-info --active-topology
dds-topology --activate ${FAIRMQ_DDS_TOPO_FILE}
dds-info --active-topology
echo "...waiting for ${requiredNofSlots} executing slots..."
dds-info --executing-count --wait ${requiredNofSlots}
echo "------------------------"
echo "...waiting for Topology to finish..."
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
fairmq-dds-command-ui -w "IDLE"
fairmq-dds-command-ui -c i
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)"
fairmq-dds-command-ui -c r -p $allexceptqctasks
qctask="main/QCTask.*"
qcdispatcher="main/QCDispatcher.*"
fairmq-dds-command-ui -c p --property-key qc --property-value active -p $qcdispatcher
fairmq-dds-command-ui -c r -p $qctask
fairmq-dds-command-ui -w "RUNNING->READY" -p $qctask
echo "...$qctask received data and transitioned to READY, sending shutdown..."
fairmq-dds-command-ui -c s
fairmq-dds-command-ui -c t
fairmq-dds-command-ui -c d
fairmq-dds-command-ui -c q
echo "...waiting for ${requiredNofSlots} idle slots..."
dds-info --idle-count --wait ${requiredNofSlots}
echo "------------------------"
dds-info --active-topology
dds-topology --stop
dds-info --active-topology
dds-agent-cmd getlog -a
logDir="${wrkDir}/logs"
for file in $(find "${logDir}" -name "*.tar.gz"); do tar -xf ${file} -C "${logDir}" ; done
echo "AGENT LOG FILES IN: ${logDir}"
# This string is used by ctest to detect success
echo "Example successful :)"
# Cleanup function is called by EXIT trap

View File

@@ -0,0 +1,59 @@
/********************************************************************************
* 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 "runFairMQDevice.h"
#include "FairMQDevice.h"
class QCDispatcher : public FairMQDevice
{
public:
QCDispatcher()
: fDoQC(false)
{
OnData("data1", &QCDispatcher::HandleData);
}
void InitTask() override
{
GetConfig()->Subscribe<std::string>("qcdevice", [&](const std::string& key, std::string value) {
if (key == "qc") {
if (value == "active") {
fDoQC.store(true);
} else if (value == "inactive") {
fDoQC.store(false);
}
}
});
}
protected:
bool HandleData(FairMQMessagePtr& msg, int)
{
if (fDoQC.load() == true) {
FairMQMessagePtr msgCopy(NewMessage());
msgCopy->Copy(*msg);
if (Send(msg, "qc") < 0) {
return false;
}
}
if (Send(msg, "data2") < 0) {
return false;
}
return true;
}
void ResetTask() override { GetConfig()->Unsubscribe<std::string>("qcdevice"); }
private:
std::atomic<bool> fDoQC;
};
void addCustomOptions(boost::program_options::options_description& /*options*/) {}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new QCDispatcher(); }

26
examples/qc/runQCTask.cxx Normal file
View File

@@ -0,0 +1,26 @@
/********************************************************************************
* 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 "runFairMQDevice.h"
#include "FairMQDevice.h"
class QCTask : public FairMQDevice
{
public:
QCTask()
{
OnData("qc", [](FairMQMessagePtr& /*msg*/, int) {
LOG(info) << "received data";
return false;
});
}
};
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& /*options*/) {}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new QCTask(); }

View File

@@ -0,0 +1,36 @@
/********************************************************************************
* 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 "runFairMQDevice.h"
#include "FairMQDevice.h"
#include <thread> // this_thread::sleep_for
#include <chrono>
class Sampler : public FairMQDevice
{
public:
Sampler() {}
protected:
virtual bool ConditionalRun()
{
FairMQMessagePtr msg(NewMessage(1000));
if (Send(msg, "data1") < 0) {
return false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
return true;
}
};
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description&) {}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new Sampler(); }

25
examples/qc/runSink.cxx Normal file
View File

@@ -0,0 +1,25 @@
/********************************************************************************
* 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 "runFairMQDevice.h"
#include "FairMQDevice.h"
#include <string>
class Sink : public FairMQDevice
{
public:
Sink() { OnData("data2", &Sink::HandleData); }
protected:
bool HandleData(FairMQMessagePtr& /*msg*/, int /*index*/) { return true; }
};
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description&) {}
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new Sink(); }

View File

@@ -31,10 +31,12 @@ SENDER="fairmq-ex-readout-sender"
SENDER+=" --id sender1"
SENDER+=" --input-name ps"
SENDER+=" --channel-config name=ps,type=pair,method=bind,address=tcp://localhost:7779,transport=shmem"
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=ofi"
#SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=ofi"
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=zeromq"
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
RECEIVER="fairmq-ex-readout-receiver"
RECEIVER+=" --id receiver1"
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=ofi"
#RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=ofi"
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=zeromq"
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &

View File

@@ -25,10 +25,12 @@ SENDER="fairmq-ex-readout-sender"
SENDER+=" --id sender1"
SENDER+=" --input-name bs"
SENDER+=" --channel-config name=bs,type=pair,method=bind,address=tcp://localhost:7778,transport=shmem"
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=ofi"
# SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=ofi"
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=zeromq"
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
RECEIVER="fairmq-ex-readout-receiver"
RECEIVER+=" --id receiver1"
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=ofi"
# RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=ofi"
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=zeromq"
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &

View File

@@ -35,6 +35,14 @@ void Sampler::InitTask()
fMsgSize = fConfig->GetProperty<int>("msg-size");
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;
});
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data",
0,
10000000,
@@ -82,6 +90,7 @@ void Sampler::ResetTask()
LOG(debug) << "done, still unacked: " << fNumUnackedMsgs;
}
fRegion.reset();
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents();
}
Sampler::~Sampler()

View File

@@ -29,6 +29,13 @@ 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;
});
}
void Sink::Run()
@@ -50,6 +57,11 @@ void Sink::Run()
}
}
void Sink::ResetTask()
{
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents();
}
Sink::~Sink()
{
}

View File

@@ -31,6 +31,7 @@ class Sink : public FairMQDevice
protected:
virtual void Run();
virtual void InitTask();
virtual void ResetTask();
private:
uint64_t fMaxIterations;

View File

@@ -19,6 +19,7 @@ SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport"
SAMPLER+=" --severity debug"
SAMPLER+=" --session $SESSION"
SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1"
SAMPLER+=" --msg-size $msgSize"

1
extern/asio vendored Submodule

Submodule extern/asio added at 90f32660cd

17
extern/bundled_asio.cmake vendored Normal file
View File

@@ -0,0 +1,17 @@
################################################################################
# Copyright (C) 2019 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" #
################################################################################
if(NOT TARGET asio::headers)
if(Git_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive --depth 1 -- extern/asio
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
endif()

1
extern/googletest vendored Submodule

Submodule extern/googletest added at 90a443f9c2

View File

@@ -6,16 +6,6 @@
# copied verbatim in the file "LICENSE" #
################################################################################
####################
# external plugins #
####################
if(BUILD_DDS_PLUGIN)
add_subdirectory(plugins/DDS)
endif()
if(BUILD_PMIX_PLUGIN)
add_subdirectory(plugins/PMIx)
endif()
if(BUILD_FAIRMQ OR BUILD_SDK)
###########
# Version #
@@ -58,6 +48,12 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
${TOOLS_PUBLIC_HEADER_FILES}
)
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
# workaround https://github.com/boostorg/asio/commit/43874d5497414c67655d901e48c939ef01337edb
if( Boost_VERSION VERSION_LESS 1.69
AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0.1)
target_compile_definitions(${target} PUBLIC BOOST_ASIO_HAS_STD_STRING_VIEW)
endif()
target_include_directories(${target}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
@@ -70,7 +66,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
Boost::boost
)
set_target_properties(${target} PROPERTIES
VERSION ${PROJECT_GIT_VERSION}
VERSION ${PROJECT_VERSION}
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
OUTPUT_NAME FairMQ${target}
)
@@ -124,7 +120,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
Tools
)
set_target_properties(${target} PROPERTIES
VERSION ${PROJECT_GIT_VERSION}
VERSION ${PROJECT_VERSION}
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
OUTPUT_NAME FairMQ${target}
)
@@ -186,11 +182,11 @@ if(BUILD_FAIRMQ)
plugins/Builtin.h
plugins/config/Config.h
plugins/Control.h
shmem/FairMQMessageSHM.h
shmem/FairMQPollerSHM.h
shmem/FairMQUnmanagedRegionSHM.h
shmem/FairMQSocketSHM.h
shmem/FairMQTransportFactorySHM.h
shmem/Message.h
shmem/Poller.h
shmem/UnmanagedRegion.h
shmem/Socket.h
shmem/TransportFactory.h
shmem/Common.h
shmem/Manager.h
shmem/Region.h
@@ -247,11 +243,10 @@ if(BUILD_FAIRMQ)
SuboptParser.cxx
plugins/config/Config.cxx
plugins/Control.cxx
shmem/FairMQMessageSHM.cxx
shmem/FairMQPollerSHM.cxx
shmem/FairMQUnmanagedRegionSHM.cxx
shmem/FairMQSocketSHM.cxx
shmem/FairMQTransportFactorySHM.cxx
shmem/Message.cxx
shmem/Poller.cxx
shmem/Socket.cxx
shmem/TransportFactory.cxx
shmem/Manager.cxx
shmem/Region.cxx
zeromq/FairMQMessageZMQ.cxx
@@ -371,7 +366,7 @@ if(BUILD_FAIRMQ)
${OFI_DEPS}
)
set_target_properties(${_target} PROPERTIES
VERSION ${PROJECT_GIT_VERSION}
VERSION ${PROJECT_VERSION}
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
)
@@ -460,6 +455,20 @@ if(BUILD_FAIRMQ)
endforeach()
endif()
if(BUILD_SDK_COMMANDS)
add_subdirectory(sdk/commands)
endif()
if(BUILD_SDK)
add_subdirectory(sdk)
endif()
####################
# external plugins #
####################
if(BUILD_DDS_PLUGIN)
add_subdirectory(plugins/DDS)
endif()
if(BUILD_PMIX_PLUGIN)
add_subdirectory(plugins/PMIx)
endif()

View File

@@ -75,7 +75,7 @@ void DeviceRunner::SubscribeForConfigChange()
fair::Logger::SetConsoleColor(val);
}
});
fConfig.Subscribe<string>("device-runner", [&](const std::string& key, const std::string val) {
fConfig.Subscribe<string>("device-runner", [&](const std::string& key, const std::string& val) {
if (key == "severity") {
fair::Logger::SetConsoleSeverity(val);
} else if (key == "file-severity") {

View File

@@ -12,12 +12,10 @@
#include <memory>
#include <mutex>
#include <string>
#include <tuple>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <utility>
#include <vector>
#include <functional>
#include <boost/any.hpp>
#include <boost/functional/hash.hpp>

View File

@@ -7,7 +7,8 @@
********************************************************************************/
#include "FairMQChannel.h"
#include <fairmq/Tools.h>
#include <fairmq/tools/Strings.h>
#include <fairmq/Properties.h>
#include <boost/algorithm/string.hpp> // join/split
@@ -19,7 +20,7 @@ using namespace std;
using namespace fair::mq;
template<typename T>
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound) noexcept
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound)
{
if (m.count(k)) {
return boost::any_cast<T>(m.at(k));
@@ -132,26 +133,37 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan, const string& newName)
FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
{
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;
if (this == &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;
}
return *this;
}

View File

@@ -10,6 +10,7 @@
#define FAIRMQCHANNEL_H_
#include <FairMQTransportFactory.h>
#include <FairMQUnmanagedRegion.h>
#include <FairMQSocket.h>
#include <fairmq/Transports.h>
#include <FairMQLogger.h>
@@ -17,15 +18,14 @@
#include <fairmq/Properties.h>
#include <FairMQMessage.h>
#include <boost/any.hpp>
#include <string>
#include <memory> // unique_ptr, shared_ptr
#include <vector>
#include <atomic>
#include <mutex>
#include <stdexcept>
#include <utility> // std::move
#include <cstddef> // size_t
#include <cstdint> // int64_t
class FairMQChannel
{
@@ -68,13 +68,13 @@ class FairMQChannel
FairMQChannel(const FairMQChannel&, const std::string& name);
/// Move constructor
FairMQChannel(FairMQChannel&&) = default;
FairMQChannel(FairMQChannel&&) = delete;
/// Assignment operator
FairMQChannel& operator=(const FairMQChannel&);
/// Move assignment operator
FairMQChannel& operator=(FairMQChannel&&) = default;
FairMQChannel& operator=(FairMQChannel&&) = delete;
/// Destructor
virtual ~FairMQChannel()
@@ -340,6 +340,11 @@ class FairMQChannel
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);
}
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::DEFAULT;
static constexpr const char* DefaultTransportName = "default";
static constexpr const char* DefaultName = "";

View File

@@ -8,19 +8,15 @@
#include <FairMQDevice.h>
#include <fairmq/tools/RateLimit.h>
#include <fairmq/tools/Network.h>
#include <boost/algorithm/string.hpp> // join/split
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <list>
#include <cstdlib>
#include <chrono>
#include <mutex>
#include <thread>
#include <functional>
#include <sstream>
#include <iomanip>
#include <future>
#include <algorithm> // std::max
@@ -303,10 +299,15 @@ void FairMQDevice::InitWrapper()
// if binding address is not specified, try getting it from the configured network interface
if (subChannel.fAddress == "unspecified" || subChannel.fAddress == "") {
// if the configured network interface is default, get its name from the default route
if (networkInterface == "default") {
networkInterface = tools::getDefaultRouteNetworkInterface();
try {
if (networkInterface == "default") {
networkInterface = tools::getDefaultRouteNetworkInterface();
}
subChannel.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
} catch(const tools::DefaultRouteDetectionError& e) {
LOG(debug) << "binding on tcp://*:1";
subChannel.fAddress = "tcp://*:1";
}
subChannel.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
}
// fill the uninitialized list
fUninitializedBindingChannels.push_back(&subChannel);
@@ -482,32 +483,6 @@ void FairMQDevice::InitTaskWrapper()
ChangeState(Transition::Auto);
}
bool FairMQDevice::SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs)
{
return lhs.fAddress < rhs.fAddress;
}
void FairMQDevice::SortChannel(const string& name, const bool reindex)
{
if (fChannels.find(name) != fChannels.end())
{
sort(fChannels.at(name).begin(), fChannels.at(name).end(), SortSocketsByAddress);
if (reindex)
{
for (auto vi = fChannels.at(name).begin(); vi != fChannels.at(name).end(); ++vi)
{
// set channel name: name + vector index
vi->fName = tools::ToString(name, "[", vi - fChannels.at(name).begin(), "]");
}
}
}
else
{
LOG(error) << "Sorting failed: no channel with the name \"" << name << "\".";
}
}
void FairMQDevice::RunWrapper()
{
LOG(info) << "DEVICE: Running...";

View File

@@ -14,7 +14,6 @@
#include <fairmq/Transports.h>
#include <fairmq/StateQueue.h>
#include <FairMQSocket.h>
#include <FairMQChannel.h>
#include <FairMQMessage.h>
#include <FairMQParts.h>
@@ -24,21 +23,19 @@
#include <vector>
#include <memory> // unique_ptr
#include <algorithm> // std::sort()
#include <algorithm> // find
#include <string>
#include <chrono>
#include <iostream>
#include <unordered_map>
#include <functional>
#include <assert.h> // static_assert
#include <type_traits> // is_trivially_copyable
#include <stdexcept>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <cstddef>
#include <utility> // pair
#include <fairmq/Tools.h>
#include <fairmq/tools/Version.h>
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
@@ -115,11 +112,6 @@ class FairMQDevice
/// Outputs the socket transfer rates
virtual void LogSocketRates();
/// Sorts a channel by address, with optional reindexing of the sorted values
/// @param name Channel name
/// @param reindex Should reindexing be done
void SortChannel(const std::string& name, const bool reindex = true);
template<typename Serializer, typename DataType, typename... Args>
void Serialize(FairMQMessage& msg, DataType&& data, Args&&... args) const
{
@@ -154,15 +146,6 @@ class FairMQDevice
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
}
int SendAsync(FairMQMessagePtr& msg, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(msg, \"channelA\", subchannelIndex, timeout);")))
{
return GetChannel(channel, index).Send(msg, 0);
}
int ReceiveAsync(FairMQMessagePtr& msg, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(msg, \"channelA\", subchannelIndex, timeout);")))
{
return GetChannel(channel, index).Receive(msg, 0);
}
/// Shorthand method to send FairMQParts on `chan` at index `i`
/// @param parts parts reference
/// @param chan channel name
@@ -185,15 +168,6 @@ class FairMQDevice
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
}
int64_t SendAsync(FairMQParts& parts, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(parts, \"channelA\", subchannelIndex, timeout);")))
{
return GetChannel(channel, index).Send(parts.fParts, 0);
}
int64_t ReceiveAsync(FairMQParts& parts, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(parts, \"channelA\", subchannelIndex, timeout);")))
{
return GetChannel(channel, index).Receive(parts.fParts, 0);
}
/// @brief Getter for default transport factory
auto Transport() const -> FairMQTransportFactory*
{
@@ -243,17 +217,47 @@ class FairMQDevice
}
// creates unamanaged region with the default device transport
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr)
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
{
return Transport()->CreateUnmanagedRegion(size, callback);
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);
}
// 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)
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel,
int index,
const size_t size,
FairMQRegionCallback callback = nullptr,
const std::string& path = "",
int flags = 0)
{
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);
}
template<typename ...Ts>
FairMQPollerPtr NewPoller(const Ts&... inputs)
{
@@ -297,9 +301,6 @@ class FairMQDevice
return channels.at(0)->Transport()->CreatePoller(channels);
}
/// Waits for the first initialization run to finish
void WaitForInitialValidation() __attribute__((deprecated("This method will have no effect in future versions and will be removed. Instead subscribe for state changes and inspect configuration values."))) {}
/// Adds a transport to the device if it doesn't exist
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
@@ -312,11 +313,6 @@ class FairMQDevice
return fConfig;
}
/// Implements the sort algorithm used in SortChannel()
/// @param lhs Right hand side value for comparison
/// @param rhs Left hand side value for comparison
static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs);
// overload to easily bind member functions
template<typename T>
void OnData(const std::string& channelName, bool (T::* memberFunction)(FairMQMessagePtr& msg, int index))

View File

@@ -33,7 +33,7 @@ class FairMQParts
FairMQParts& operator=(const FairMQParts&) = delete;
/// Constructor from argument pack of std::unique_ptr<FairMQMessage> rvalues
template <typename... Ts>
FairMQParts(Ts&&... messages) : fParts() {AddPart(std::forward<Ts>(messages)...);}
FairMQParts(Ts&&... messages) : fParts() { AddPart(std::forward<Ts>(messages)...); }
/// Default destructor
~FairMQParts() {};
@@ -63,10 +63,10 @@ class FairMQParts
/// Add content of another object by move
void AddPart(FairMQParts&& other)
{
container parts = std::move(other.fParts);
for (auto& part : parts) {
fParts.push_back(std::move(part));
}
container parts = std::move(other.fParts);
for (auto& part : parts) {
fParts.push_back(std::move(part));
}
}
/// Get reference to part in the container at index (without bounds check)

View File

@@ -31,8 +31,8 @@ namespace fair
namespace mq
{
using PollerPtr = std::unique_ptr<FairMQPoller>;
using Poller = FairMQPoller;
using PollerPtr = FairMQPollerPtr;
struct PollerError : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */

View File

@@ -22,7 +22,7 @@ class FairMQSocket
FairMQSocket() {}
FairMQSocket(FairMQTransportFactory* fac): fTransport(fac) {}
virtual std::string GetId() = 0;
virtual std::string GetId() const = 0;
virtual bool Bind(const std::string& address) = 0;
virtual bool Connect(const std::string& address) = 0;

View File

@@ -7,8 +7,8 @@
********************************************************************************/
#include <FairMQTransportFactory.h>
#include <fairmq/shmem/TransportFactory.h>
#include <zeromq/FairMQTransportFactoryZMQ.h>
#include <shmem/FairMQTransportFactorySHM.h>
#ifdef BUILD_NANOMSG_TRANSPORT
#include <nanomsg/FairMQTransportFactoryNN.h>
#endif /* BUILD_NANOMSG_TRANSPORT */
@@ -16,52 +16,47 @@
#include <fairmq/ofi/TransportFactory.h>
#endif
#include <FairMQLogger.h>
#include <fairmq/Tools.h>
#include <fairmq/tools/Unique.h>
#include <memory>
#include <string>
#include <sstream>
FairMQTransportFactory::FairMQTransportFactory(const std::string& id)
using namespace std;
FairMQTransportFactory::FairMQTransportFactory(const string& id)
: fkId(id)
{
}
{}
auto FairMQTransportFactory::CreateTransportFactory(const std::string& type, const std::string& id, const fair::mq::ProgOptions* config) -> std::shared_ptr<FairMQTransportFactory>
auto FairMQTransportFactory::CreateTransportFactory(const string& type,
const string& id,
const fair::mq::ProgOptions* config)
-> shared_ptr<FairMQTransportFactory>
{
using namespace std;
auto finalId = id;
// Generate uuid if empty
if (finalId == "")
{
if (finalId == "") {
finalId = fair::mq::tools::Uuid();
}
if (type == "zeromq")
{
if (type == "zeromq") {
return make_shared<FairMQTransportFactoryZMQ>(finalId, config);
}
else if (type == "shmem")
{
return make_shared<FairMQTransportFactorySHM>(finalId, config);
} else if (type == "shmem") {
return make_shared<fair::mq::shmem::TransportFactory>(finalId, config);
}
#ifdef BUILD_NANOMSG_TRANSPORT
else if (type == "nanomsg")
{
else if (type == "nanomsg") {
return make_shared<FairMQTransportFactoryNN>(finalId, config);
}
#endif /* BUILD_NANOMSG_TRANSPORT */
#ifdef BUILD_OFI_TRANSPORT
else if (type == "ofi")
{
else if (type == "ofi") {
return make_shared<fair::mq::ofi::TransportFactory>(finalId, config);
}
#endif /* BUILD_OFI_TRANSPORT */
else
{
LOG(error) << "Unavailable transport requested: " << "\"" << type << "\"" << ". Available are: "
else {
LOG(error) << "Unavailable transport requested: "
<< "\"" << type << "\""
<< ". Available are: "
<< "\"zeromq\""
<< "\"shmem\""
#ifdef BUILD_NANOMSG_TRANSPORT

View File

@@ -12,7 +12,6 @@
#include <FairMQLogger.h>
#include <FairMQMessage.h>
#include <FairMQPoller.h>
#include <fairmq/ProgOptionsFwd.h>
#include <FairMQSocket.h>
#include <FairMQUnmanagedRegion.h>
#include <fairmq/MemoryResources.h>
@@ -22,8 +21,11 @@
#include <memory>
#include <vector>
#include <unordered_map>
#include <stdexcept>
#include <cstddef> // size_t
class FairMQChannel;
namespace fair { namespace mq { class ProgOptions; } }
class FairMQTransportFactory
{
@@ -59,20 +61,49 @@ class FairMQTransportFactory
/// @param obj optional helper pointer that can be used in the callback
/// @return pointer to FairMQMessage
virtual FairMQMessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
/// @brief create a message with the buffer located within the corresponding unmanaged region
/// @param unmanagedRegion the unmanaged region that this message buffer belongs to
/// @param data message buffer (must be within the region - checked at runtime by the transport)
/// @param size size of the message
/// @param hint optional parameter, returned to the user in the FairMQRegionCallback
virtual FairMQMessagePtr CreateMessage(FairMQUnmanagedRegionPtr& unmanagedRegion, void* data, const size_t size, void* hint = 0) = 0;
/// Create a socket
/// @brief Create a socket
virtual FairMQSocketPtr CreateSocket(const std::string& type, const std::string& name) = 0;
/// Create a poller for a single channel (all subchannels)
/// @brief Create a poller for a single channel (all subchannels)
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel>& channels) const = 0;
/// Create a poller for specific channels
/// @brief Create a poller for specific channels
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel*>& channels) const = 0;
/// Create a poller for specific channels (all subchannels)
/// @brief Create a poller for specific channels (all subchannels)
virtual FairMQPollerPtr CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const = 0;
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) const = 0;
/// @brief Create new UnmanagedRegion
/// @param size size of the region
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
/// @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;
/// @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
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
/// @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;
/// @brief Subscribe to region events (creation, destruction, ...)
/// @param callback the callback that is called when a region event occurs
virtual void SubscribeToRegionEvents(FairMQRegionEventCallback callback) = 0;
/// @brief Check if there is an active subscription to region events
/// @return true/false
virtual bool SubscribedToRegionEvents() = 0;
/// @brief Unsubscribe from region events
virtual void UnsubscribeFromRegionEvents() = 0;
virtual std::vector<FairMQRegionInfo> GetRegionInfo() = 0;
/// Get transport type
virtual fair::mq::Transport GetType() const = 0;
@@ -135,6 +166,7 @@ namespace fair
namespace mq
{
using TransportFactory = FairMQTransportFactory;
struct TransportFactoryError : std::runtime_error { using std::runtime_error::runtime_error; };
} /* namespace mq */

View File

@@ -12,26 +12,91 @@
#include <cstddef> // size_t
#include <memory> // std::unique_ptr
#include <functional> // std::function
#include <ostream> // std::ostream
class FairMQTransportFactory;
enum class FairMQRegionEvent : int
{
created,
destroyed,
local_only
};
struct FairMQRegionInfo
{
FairMQRegionInfo()
: 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)
, ptr(_ptr)
, size(_size)
, flags(_flags)
, event (_event)
{}
uint64_t id; // id of the region
void* ptr; // pointer to the start of the region
size_t size; // region size
int64_t flags; // custom flags set by the creator
FairMQRegionEvent event;
};
using FairMQRegionCallback = std::function<void(void*, size_t, void*)>;
using FairMQRegionEventCallback = std::function<void(FairMQRegionInfo)>;
class FairMQUnmanagedRegion
{
public:
FairMQUnmanagedRegion() {}
FairMQUnmanagedRegion(FairMQTransportFactory* factory): fTransport(factory) {}
virtual void* GetData() const = 0;
virtual size_t GetSize() const = 0;
virtual uint64_t GetId() const = 0;
FairMQTransportFactory* GetTransport() { return fTransport; }
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
virtual ~FairMQUnmanagedRegion() {};
private:
FairMQTransportFactory* fTransport{nullptr};
};
using FairMQUnmanagedRegionPtr = std::unique_ptr<FairMQUnmanagedRegion>;
inline std::ostream& operator<<(std::ostream& os, const FairMQRegionEvent& event)
{
switch (event) {
case FairMQRegionEvent::created:
return os << "created";
case FairMQRegionEvent::destroyed:
return os << "destroyed";
case FairMQRegionEvent::local_only:
return os << "local_only";
default:
return os << "unrecognized event";
}
}
namespace fair
{
namespace mq
{
using UnmanagedRegionPtr = std::unique_ptr<FairMQUnmanagedRegion>;
using RegionCallback = FairMQRegionCallback;
using RegionEventCallback = FairMQRegionEventCallback;
using RegionEvent = FairMQRegionEvent;
using RegionInfo = FairMQRegionInfo;
using UnmanagedRegion = FairMQUnmanagedRegion;
using UnmanagedRegionPtr = FairMQUnmanagedRegionPtr;
} /* namespace mq */
} /* namespace fair */

View File

@@ -60,7 +60,7 @@ FairMQMessagePtr getMessage(ContainerT &&container_, FairMQMemoryResource *targe
container.data(),
containerSizeBytes);
return message;
};
}
} /* namespace mq */
} /* namespace fair */

View File

@@ -18,5 +18,5 @@
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t /*alignment*/)
{
return setMessage(factory->CreateMessage(bytes));
};
}

View File

@@ -23,11 +23,7 @@ class FairMQTransportFactory;
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
#include <cstring>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
namespace fair {
namespace mq {

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2017-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -8,15 +8,20 @@
#include <fairmq/Plugin.h>
#include <FairMQLogger.h>
#include <utility>
using namespace std;
fair::mq::Plugin::Plugin(const string name, const Version version, const string maintainer, const string homepage, PluginServices* pluginServices)
: fkName{name}
fair::mq::Plugin::Plugin(string name,
Version version,
string maintainer,
string homepage,
PluginServices* pluginServices)
: fkName(std::move(name))
, fkVersion(version)
, fkMaintainer{maintainer}
, fkHomepage{homepage}
, fPluginServices{pluginServices}
, fkMaintainer(std::move(maintainer))
, fkHomepage(std::move(homepage))
, fPluginServices(pluginServices)
{
LOG(debug) << "Loaded plugin: " << *this;
}

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2017-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -9,7 +9,8 @@
#ifndef FAIR_MQ_PLUGIN_H
#define FAIR_MQ_PLUGIN_H
#include <fairmq/Tools.h>
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Version.h>
#include <fairmq/PluginServices.h>
#include <boost/dll/alias.hpp>
@@ -43,7 +44,11 @@ class Plugin
using Version = tools::Version;
Plugin() = delete;
Plugin(const std::string name, const Version version, const std::string maintainer, const std::string homepage, PluginServices* pluginServices);
Plugin(std::string name,
Version version,
std::string maintainer,
std::string homepage,
PluginServices* pluginServices);
Plugin(const Plugin&) = delete;
Plugin operator=(const Plugin&) = delete;
@@ -59,10 +64,10 @@ class Plugin
friend auto operator!=(const Plugin& lhs, const Plugin& rhs) -> bool { return !(lhs == rhs); }
friend auto operator<<(std::ostream& os, const Plugin& p) -> std::ostream&
{
return os << "'" << p.GetName() << "', "
<< "version '" << p.GetVersion() << "', "
return os << "'" << p.GetName() << "', "
<< "version '" << p.GetVersion() << "', "
<< "maintainer '" << p.GetMaintainer() << "', "
<< "homepage '" << p.GetHomepage() << "'";
<< "homepage '" << p.GetHomepage() << "'";
}
static auto NoProgramOptions() -> ProgOptions { return boost::none; }
@@ -79,7 +84,6 @@ class Plugin
auto StealDeviceControl() -> void { fPluginServices->StealDeviceControl(fkName); };
auto ReleaseDeviceControl() -> void { fPluginServices->ReleaseDeviceControl(fkName); };
auto ChangeDeviceState(const DeviceStateTransition next) -> bool { return fPluginServices->ChangeDeviceState(fkName, next); }
void TransitionDeviceStateTo(const DeviceState state) { return fPluginServices->TransitionDeviceStateTo(fkName, state); }
auto SubscribeToDeviceStateChange(std::function<void(DeviceState)> callback) -> void { fPluginServices->SubscribeToDeviceStateChange(fkName, callback); }
auto UnsubscribeFromDeviceStateChange() -> void { fPluginServices->UnsubscribeFromDeviceStateChange(fkName); }

View File

@@ -8,7 +8,7 @@
#include <fairmq/plugins/Builtin.h>
#include <fairmq/PluginManager.h>
#include <fairmq/Tools.h>
#include <fairmq/tools/Strings.h>
#include <boost/program_options.hpp>
#include <algorithm>
#include <iterator>
@@ -28,6 +28,8 @@ using boost::optional;
const std::string fair::mq::PluginManager::fgkLibPrefix = "FairMQPlugin_";
std::vector<boost::dll::shared_library> fair::mq::PluginManager::fgDLLKeepAlive = std::vector<boost::dll::shared_library>();
fair::mq::PluginManager::PluginManager()
: fSearchPaths{}
, fPluginFactories()

View File

@@ -11,8 +11,9 @@
#include <fairmq/Plugin.h>
#include <fairmq/PluginServices.h>
#include <fairmq/Tools.h>
#include <FairMQDevice.h>
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Strings.h>
#define BOOST_FILESYSTEM_VERSION 3
#define BOOST_FILESYSTEM_NO_DEPRECATED
#include <boost/filesystem.hpp>
@@ -21,13 +22,14 @@
#include <boost/dll/import.hpp>
#include <boost/dll/shared_library.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include <functional>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
#include <utility> // forward
namespace fair
{
@@ -78,7 +80,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 = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); }
auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
@@ -95,6 +97,7 @@ class PluginManager
using fair::mq::tools::ToString;
auto lib = shared_library{std::forward<Args>(args)...};
fgDLLKeepAlive.push_back(lib);
fPluginFactories[pluginName] = import_alias<PluginFactory>(
shared_library{lib},
@@ -115,6 +118,7 @@ class PluginManager
static const std::string fgkLibPrefix;
std::vector<boost::filesystem::path> fSearchPaths;
static std::vector<boost::dll::shared_library> fgDLLKeepAlive;
std::map<std::string, std::function<PluginFactory>> fPluginFactories;
std::unique_ptr<PluginServices> fPluginServices;
std::map<std::string, std::unique_ptr<Plugin>> fPlugins;

View File

@@ -7,6 +7,7 @@
********************************************************************************/
#include <fairmq/PluginServices.h>
#include <fairmq/tools/Strings.h>
using namespace fair::mq;
using namespace std;
@@ -27,22 +28,6 @@ auto PluginServices::ChangeDeviceState(const string& controller, const DeviceSta
}
}
void PluginServices::TransitionDeviceStateTo(const std::string& controller, DeviceState state)
{
lock_guard<mutex> lock{fDeviceControllerMutex};
if (!fDeviceController) fDeviceController = controller;
if (fDeviceController == controller) {
fDevice.TransitionTo(state);
} else {
throw DeviceControlError{tools::ToString(
"Plugin '", controller, "' is not allowed to change device states. ",
"Currently, plugin '", *fDeviceController, "' has taken control."
)};
}
}
auto PluginServices::TakeDeviceControl(const string& controller) -> void
{
lock_guard<mutex> lock{fDeviceControllerMutex};

View File

@@ -9,7 +9,6 @@
#ifndef FAIR_MQ_PLUGINSERVICES_H
#define FAIR_MQ_PLUGINSERVICES_H
#include <fairmq/Tools.h>
#include <fairmq/States.h>
#include <FairMQDevice.h>
#include <fairmq/ProgOptions.h>
@@ -125,8 +124,6 @@ class PluginServices
/// If the device control role has not been taken yet, calling this function will take over control implicitely.
auto ChangeDeviceState(const std::string& controller, const DeviceStateTransition next) -> bool;
void TransitionDeviceStateTo(const std::string& controller, DeviceState state);
/// @brief Subscribe with a callback to device state changes
/// @param subscriber id
/// @param callback

View File

@@ -15,7 +15,7 @@
#include "FairMQLogger.h"
#include <fairmq/ProgOptions.h>
#include "tools/Unique.h"
#include <fairmq/tools/Strings.h>
#include <boost/any.hpp>
#include <boost/regex.hpp>
@@ -62,7 +62,7 @@ ValInfo ConvertVarValToValInfo(const po::variable_value& v)
} catch (out_of_range& oor) {
return {string("[unidentified_type]"), string("[unidentified_type]"), origin};
}
};
}
string ConvertVarValToString(const po::variable_value& v)
{
@@ -443,4 +443,4 @@ void ProgOptions::PrintOptionsRaw() const
} // namespace mq
} // namespace fair
} // namespace fair

View File

@@ -14,7 +14,7 @@
#include <fairmq/EventManager.h>
#include <fairmq/ProgOptionsFwd.h>
#include <fairmq/Properties.h>
#include <fairmq/Tools.h>
#include <fairmq/tools/Strings.h>
#include <boost/program_options.hpp>

View File

@@ -10,11 +10,17 @@
#define FAIR_MQ_SDK_H
// IWYU pragma: begin_exports
#include <fairmq/sdk/DDSInfo.h>
#include <fairmq/sdk/AsioAsyncOp.h>
#include <fairmq/sdk/AsioBase.h>
#include <fairmq/sdk/DDSAgent.h>
#include <fairmq/sdk/DDSEnvironment.h>
#include <fairmq/sdk/DDSInfo.h>
#include <fairmq/sdk/DDSSession.h>
#include <fairmq/sdk/DDSTask.h>
#include <fairmq/sdk/DDSTopology.h>
#include <fairmq/sdk/Error.h>
#include <fairmq/sdk/Topology.h>
#include <fairmq/sdk/Traits.h>
// IWYU pragma: end_exports
#endif // FAIR_MQ_SDK_H

View File

@@ -79,7 +79,9 @@ struct Machine_ : public state_machine_def<Machine_>
{
public:
Machine_()
: fLastTransitionResult(true)
: fState(State::Ok)
, fNewState(State::Ok)
, fLastTransitionResult(true)
, fNewStatePending(false)
{}

View File

@@ -9,7 +9,7 @@
#ifndef FAIR_MQ_TRANSPORTS_H
#define FAIR_MQ_TRANSPORTS_H
#include <fairmq/Tools.h>
#include <fairmq/tools/CppSTL.h>
#include <memory>
#include <string>

View File

@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2018-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
@@ -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-2019 GSI"
#define FAIRMQ_COPYRIGHT "2012-2020 GSI"
#define FAIRMQ_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#endif // FAIR_MQ_VERSION_H

View File

@@ -8,10 +8,9 @@
#include "FairMQBenchmarkSampler.h"
#include <fairmq/Tools.h>
#include "tools/RateLimit.h"
#include "../FairMQLogger.h"
#include <vector>
#include <chrono>
using namespace std;
@@ -27,10 +26,6 @@ FairMQBenchmarkSampler::FairMQBenchmarkSampler()
{
}
FairMQBenchmarkSampler::~FairMQBenchmarkSampler()
{
}
void FairMQBenchmarkSampler::InitTask()
{
fMultipart = fConfig->GetProperty<bool>("multipart");

View File

@@ -10,8 +10,10 @@
#define FAIRMQBENCHMARKSAMPLER_H_
#include <string>
#include <thread>
#include <atomic>
#include <cstddef> // size_t
#include <cstdint> // uint64_t
#include "FairMQDevice.h"
@@ -23,7 +25,7 @@ class FairMQBenchmarkSampler : public FairMQDevice
{
public:
FairMQBenchmarkSampler();
virtual ~FairMQBenchmarkSampler();
virtual ~FairMQBenchmarkSampler() {}
protected:
bool fMultipart;

View File

@@ -17,7 +17,6 @@
#include <vector>
#include <unordered_map>
#include <initializer_list>
#include "FairMQPoller.h"
#include "FairMQChannel.h"

View File

@@ -91,11 +91,6 @@ FairMQSocketNN::FairMQSocketNN(const string& type, const string& name, const str
LOG(debug) << "Created socket " << GetId();
}
string FairMQSocketNN::GetId()
{
return fId;
}
bool FairMQSocketNN::Bind(const string& address)
{
// LOG(info) << "bind socket " << fId << " on " << address;

View File

@@ -23,7 +23,7 @@ class FairMQSocketNN final : public FairMQSocket
FairMQSocketNN(const FairMQSocketNN&) = delete;
FairMQSocketNN operator=(const FairMQSocketNN&) = delete;
std::string GetId() override;
std::string GetId() const override { return fId; }
bool Bind(const std::string& address) override;
bool Connect(const std::string& address) override;

View File

@@ -19,6 +19,7 @@ fair::mq::Transport FairMQTransportFactoryNN::fTransportType = fair::mq::Transpo
FairMQTransportFactoryNN::FairMQTransportFactoryNN(const string& id, const fair::mq::ProgOptions* /*config*/)
: FairMQTransportFactory(id)
, fRegionCounter(0)
{
LOG(debug) << "Transport: Using nanomsg library";
}
@@ -65,9 +66,14 @@ FairMQPollerPtr FairMQTransportFactoryNN::CreatePoller(const unordered_map<strin
return unique_ptr<FairMQPoller>(new FairMQPollerNN(channelsMap, channelList));
}
FairMQUnmanagedRegionPtr FairMQTransportFactoryNN::CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback, const std::string& path /* = "" */, int flags /* = 0 */) const
FairMQUnmanagedRegionPtr FairMQTransportFactoryNN::CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback, const std::string& path /* = "" */, int flags /* = 0 */)
{
return unique_ptr<FairMQUnmanagedRegion>(new FairMQUnmanagedRegionNN(size, callback, path, flags));
return unique_ptr<FairMQUnmanagedRegion>(new FairMQUnmanagedRegionNN(++fRegionCounter, size, callback, path, flags, this));
}
FairMQUnmanagedRegionPtr FairMQTransportFactoryNN::CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback, const std::string& path /* = "" */, int flags /* = 0 */)
{
return unique_ptr<FairMQUnmanagedRegion>(new FairMQUnmanagedRegionNN(size, userFlags, callback, path, flags, this));
}
fair::mq::Transport FairMQTransportFactoryNN::GetType() const

View File

@@ -36,7 +36,13 @@ class FairMQTransportFactoryNN final : public FairMQTransportFactory
FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel*>& channels) const override;
FairMQPollerPtr CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const override;
FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback, const std::string& path = "", int flags = 0) const override;
FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback, const std::string& path = "", int flags = 0) override;
FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) override;
void SubscribeToRegionEvents(FairMQRegionEventCallback /* callback */) override { LOG(error) << "SubscribeToRegionEvents not yet implemented for nanomsg"; }
bool SubscribedToRegionEvents() override { LOG(error) << "Region event subscriptions not yet implemented for nanomsg"; return false; }
void UnsubscribeFromRegionEvents() override { LOG(error) << "UnsubscribeFromRegionEvents not yet implemented for nanomsg"; }
std::vector<FairMQRegionInfo> GetRegionInfo() override { LOG(error) << "GetRegionInfo not yet implemented for nanomsg, returning empty vector"; return std::vector<FairMQRegionInfo>(); }
fair::mq::Transport GetType() const override;
@@ -46,6 +52,7 @@ class FairMQTransportFactoryNN final : public FairMQTransportFactory
private:
static fair::mq::Transport fTransportType;
uint64_t fRegionCounter;
mutable std::vector<FairMQSocket*> fSockets;
};

View File

@@ -11,8 +11,19 @@
using namespace std;
FairMQUnmanagedRegionNN::FairMQUnmanagedRegionNN(const size_t size, FairMQRegionCallback callback, const std::string& /*path = "" */, int /*flags = 0 */)
: fBuffer(malloc(size))
FairMQUnmanagedRegionNN::FairMQUnmanagedRegionNN(uint64_t id, const size_t size, FairMQRegionCallback callback, const std::string& /*path = "" */, int /*flags = 0 */, FairMQTransportFactory* factory /* = nullptr */)
: FairMQUnmanagedRegion(factory)
, fId(id)
, fBuffer(malloc(size))
, fSize(size)
, fCallback(callback)
{
}
FairMQUnmanagedRegionNN::FairMQUnmanagedRegionNN(uint64_t id, const size_t size, const int64_t /*userFlags*/, FairMQRegionCallback callback, const std::string& /*path = "" */, int /*flags = 0 */, FairMQTransportFactory* factory /* = nullptr */)
: FairMQUnmanagedRegion(factory)
, fId(id)
, fBuffer(malloc(size))
, fSize(size)
, fCallback(callback)
{
@@ -28,6 +39,12 @@ size_t FairMQUnmanagedRegionNN::GetSize() const
return fSize;
}
uint64_t FairMQUnmanagedRegionNN::GetId() const
{
return fId;
}
FairMQUnmanagedRegionNN::~FairMQUnmanagedRegionNN()
{
LOG(debug) << "destroying region";

View File

@@ -19,19 +19,23 @@ class FairMQUnmanagedRegionNN final : public FairMQUnmanagedRegion
friend class FairMQSocketNN;
public:
FairMQUnmanagedRegionNN(const size_t size, FairMQRegionCallback callback, const std::string& path = "", int flags = 0);
FairMQUnmanagedRegionNN(uint64_t id, const size_t size, FairMQRegionCallback callback, const std::string& path = "", int flags = 0, FairMQTransportFactory* factory = nullptr);
FairMQUnmanagedRegionNN(uint64_t id, const size_t size, const int64_t userFlags, FairMQRegionCallback callback, const std::string& path = "", int flags = 0, FairMQTransportFactory* factory = nullptr);
FairMQUnmanagedRegionNN(const FairMQUnmanagedRegionNN&) = delete;
FairMQUnmanagedRegionNN operator=(const FairMQUnmanagedRegionNN&) = delete;
virtual void* GetData() const override;
virtual size_t GetSize() const override;
void* GetData() const override;
size_t GetSize() const override;
uint64_t GetId() const override;
virtual ~FairMQUnmanagedRegionNN();
private:
uint64_t fId;
void* fBuffer;
size_t fSize;
FairMQRegionCallback fCallback;
};
#endif /* FAIRMQUNMANAGEDREGIONNN_H_ */
#endif /* FAIRMQUNMANAGEDREGIONNN_H_ */

View File

@@ -43,7 +43,7 @@ class Socket final : public fair::mq::Socket
Socket(const Socket&) = delete;
Socket operator=(const Socket&) = delete;
auto GetId() -> std::string { return fId; }
auto GetId() const -> std::string override { return fId; }
auto Bind(const std::string& address) -> bool override;
auto Connect(const std::string& address) -> bool override;

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