mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-15 09:31:45 +00:00
Compare commits
302 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
53a4d17f8b | ||
|
20544e1f18 | ||
|
b32e04db60 | ||
|
0d03c76a75 | ||
|
2916a491b9 | ||
|
b56e32eb11 | ||
|
4b516de81a | ||
|
361fb0cba5 | ||
|
df574c6466 | ||
|
dbdabd23a4 | ||
|
ccbf0be572 | ||
|
7a67719a3c | ||
|
f4a54ff550 | ||
|
d22023bcb5 | ||
|
a15d59c725 | ||
|
8cfc04721e | ||
|
e9318dd234 | ||
|
c8fc5ad33f | ||
|
59e32437a2 | ||
|
a3afadb824 | ||
|
9992811822 | ||
|
4218c185a4 | ||
|
5a49c5b9b1 | ||
|
960b612d80 | ||
|
e1a113aabe | ||
|
5721ea9510 | ||
|
330687772f | ||
|
7cbd154344 | ||
|
036561ab38 | ||
|
274ba5ec00 | ||
|
c5efd3e4a6 | ||
|
0a5820c07f | ||
|
5788daa410 | ||
|
46014118f0 | ||
|
adc4688f9b | ||
|
c3127f22e5 | ||
|
926ee743ed | ||
|
c7b1304a2c | ||
|
32764e1b12 | ||
|
96348b8462 | ||
|
cd83efadea | ||
|
38eb9d22e4 | ||
|
a20ac7af08 | ||
|
24aabdb854 | ||
|
539b088ade | ||
|
b05782af16 | ||
|
3a8f34efaa | ||
|
8160edfd04 | ||
|
3d4cd02812 | ||
|
0ae53fd7d9 | ||
|
a545bee3b1 | ||
|
f00519b99b | ||
|
41fc27d504 | ||
|
811d1b8973 | ||
|
ced67d8952 | ||
|
8123a6ecab | ||
|
beff0af51b | ||
|
21835cc104 | ||
|
334d81a1ab | ||
|
c1719eb285 | ||
|
fcd1022997 | ||
|
e221242f9a | ||
|
e853d121bf | ||
|
14d6d717a3 | ||
|
119cbe37f1 | ||
|
0e72a9bf54 | ||
|
3785fd9ff9 | ||
|
278cd62049 | ||
|
6c63b01cfe | ||
|
66acde2a69 | ||
|
19ab8bba3b | ||
|
be524d838a | ||
|
92af823135 | ||
|
50dacbcdde | ||
|
264a178424 | ||
|
1c8ad03f3c | ||
|
25658370fa | ||
|
f42945b3a3 | ||
|
9544de0647 | ||
|
d608abf31c | ||
|
15de80cfd3 | ||
|
f2da29a650 | ||
|
c180300303 | ||
|
9f8a3553ba | ||
|
692ec4e997 | ||
|
b6d9c949ae | ||
|
b6791856f9 | ||
|
a1e0814a92 | ||
|
38bb14e556 | ||
|
7187953604 | ||
|
c290c16896 | ||
|
fd2bac3e22 | ||
|
8e3f25851c | ||
|
ce937ca03e | ||
|
684e711b8b | ||
|
5b5fecc994 | ||
|
462a93b58b | ||
|
a2cff5b7bb | ||
|
b2e027478e | ||
|
e6dede492e | ||
|
f195eeac66 | ||
|
4d1e7b9cdb | ||
|
50be386191 | ||
|
f31be6d7a1 | ||
|
5607d47664 | ||
|
0f4595b8c1 | ||
|
b0b271d1f4 | ||
|
073f5e5c0e | ||
|
f6e3183f45 | ||
|
71325828f6 | ||
|
9d30ff25c2 | ||
|
2ac8f98178 | ||
|
2c6f436858 | ||
|
dd191551ca | ||
|
88dbcbe4fd | ||
|
85a3a254d4 | ||
|
c34d1f0946 | ||
|
160ee9d064 | ||
|
040931fba7 | ||
|
0d46ffe010 | ||
|
72a8e9b33c | ||
|
caeee626a3 | ||
|
e1134321dd | ||
|
5fc1c47e2a | ||
|
2f69526c04 | ||
|
7502f4b424 | ||
|
1c1509af3e | ||
|
a53e95b5f6 | ||
|
ea9ad64664 | ||
|
b9720e5269 | ||
|
343605899f | ||
|
d64169a163 | ||
|
37c8041997 | ||
|
d8d293302d | ||
|
9544d9665b | ||
|
47d9e282d4 | ||
|
23423a86d9 | ||
|
dc72262af1 | ||
|
44bfbe02ed | ||
|
924320a0ac | ||
|
e3890a4033 | ||
|
fa394194e8 | ||
|
79bcb40c04 | ||
|
54719da645 | ||
|
4b78c472b1 | ||
|
92112c812f | ||
|
870d0deae1 | ||
|
acbf57d6f3 | ||
|
2973ce0352 | ||
|
e1b6b804bd | ||
|
456b65871a | ||
|
3f5374820a | ||
|
8a2c7fb601 | ||
|
c1a17c97b8 | ||
|
ac8825c8de | ||
|
1c49dde668 | ||
|
5d6184cd1a | ||
|
0e5f648d2b | ||
|
8057b8ae33 | ||
|
da28b85497 | ||
|
33b5a2a342 | ||
|
5b47df3014 | ||
|
fd77f2b729 | ||
|
6275f4d267 | ||
|
d09be4ab79 | ||
|
246e99a577 | ||
|
0d182dc18f | ||
|
46e0796e77 | ||
|
1055f035ff | ||
|
7a0d348bd4 | ||
|
3cd6d8cfca | ||
|
0f50abf3d9 | ||
|
75a3a80ac1 | ||
|
25539e99f2 | ||
|
f73a6d71ed | ||
|
73af0ed78b | ||
|
1dec059104 | ||
|
88ff5d8fc0 | ||
|
d6d9312e53 | ||
|
2208fe91e8 | ||
|
8d12b908b6 | ||
|
02b20c320c | ||
|
be06a5629e | ||
|
eaa8f5cbdd | ||
|
7f0237d97d | ||
|
2fc93994d1 | ||
|
8feffe70ba | ||
|
31edf948de | ||
|
7cacf471b9 | ||
|
7316b0e7f2 | ||
|
1fa82f5f22 | ||
|
1bb77bf47b | ||
|
07fe02a0a0 | ||
|
9cbccface7 | ||
|
7b773cde51 | ||
|
fd282fa950 | ||
|
008be36125 | ||
|
93eb599df7 | ||
|
98aeb16dc7 | ||
|
6c07920fc6 | ||
|
b54df715ea | ||
|
ce1f507a24 | ||
|
f7cdf5ee23 | ||
|
6208cbb508 | ||
|
377eaf2bb8 | ||
|
363576496d | ||
|
5ab328b01f | ||
|
ac8cd19915 | ||
|
5d535163f1 | ||
|
dc55272317 | ||
|
388b1be056 | ||
|
d70a203449 | ||
|
a93840b240 | ||
|
bc98ab1eed | ||
|
de4fca177e | ||
|
7d1ee82c6b | ||
|
be022cfab8 | ||
|
8789664cfd | ||
|
cf26dd6aa7 | ||
|
18dc536f3d | ||
|
499ffcd300 | ||
|
a65f0e6777 | ||
|
b58f6ede74 | ||
|
8aad6c062b | ||
|
152c8431c6 | ||
|
5a7bf68c8c | ||
|
7aa95fcd93 | ||
|
a9b4788756 | ||
|
eb9dcdd1f9 | ||
|
3f655e330b | ||
|
e6149b7c38 | ||
|
b5da31498d | ||
|
44da054e78 | ||
|
53be96d93c | ||
|
cfcdd666bf | ||
|
90496c89fe | ||
|
1a93da5be0 | ||
|
99ed61a58b | ||
|
a98965031f | ||
|
fd682c3392 | ||
|
2c4a6674d2 | ||
|
7002dcbca3 | ||
|
790de84bbc | ||
|
e3d39f39f2 | ||
|
6e353d78b1 | ||
|
f515eb1100 | ||
|
4487b81de8 | ||
|
8bb6a9518a | ||
|
857ef0c9d3 | ||
|
63c02657c1 | ||
|
5256e7c580 | ||
|
74d301a16f | ||
|
1c7da53386 | ||
|
07f7142ae2 | ||
|
ff581985f3 | ||
|
5e8a442342 | ||
|
0b43bec9a7 | ||
|
afadb2a078 | ||
|
7c185ac4a5 | ||
|
a60edc43dc | ||
|
d4f96db69c | ||
|
b53691c8ad | ||
|
14980d7486 | ||
|
d966a0a991 | ||
|
66c01f2cda | ||
|
2150257c1d | ||
|
8be2fd33f4 | ||
|
26fe5e2bd8 | ||
|
48e04b636b | ||
|
937c9e8921 | ||
|
5c943bbedb | ||
|
418d42b060 | ||
|
4af0393c11 | ||
|
12f05355d3 | ||
|
69268eecfb | ||
|
4351b98d85 | ||
|
051f064c60 | ||
|
caffbf2ebf | ||
|
daed714146 | ||
|
4cefb9fb5b | ||
|
7486249c1e | ||
|
7c13503e22 | ||
|
3db32b03d4 | ||
|
7bea2bc0e6 | ||
|
5271d4236e | ||
|
4281d7b27e | ||
|
7c9744760e | ||
|
b905f517cc | ||
|
c515cbb3bf | ||
|
cba6d19781 | ||
|
bf8ec968e7 | ||
|
fbb003b50f | ||
|
4ce378b6b8 | ||
|
29313bbec3 | ||
|
fe241fe9ee | ||
|
5646d531f3 | ||
|
f46803a8b6 | ||
|
3538d9f410 | ||
|
73ccefa4cb | ||
|
0e35f1cb22 | ||
|
a8c76accdc | ||
|
3da5f4d5db |
3
.clang-tidy
Normal file
3
.clang-tidy
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
Checks: '*,-google-*,-fuchsia-*,-cert-*,-llvm-header-guard,-readability-named-parameter,-misc-non-private-member-variables-in-classes,-*-magic-numbers,-llvm-include-order,-hicpp-no-array-decay,-performance-unnecessary-value-param,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-modernize-use-trailing-return-type,-readability-redundant-member-init'
|
||||
HeaderFilterRegex: '/(fairmq/)'
|
@@ -1,2 +1,3 @@
|
||||
comment:
|
||||
layout: "diff, files"
|
||||
behavior: once
|
||||
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal 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
|
14
CMakeGraphVizOptions.cmake
Normal file
14
CMakeGraphVizOptions.cmake
Normal 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"
|
||||
)
|
191
CMakeLists.txt
191
CMakeLists.txt
@@ -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,16 +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_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_OFI_TRANSPORT "Build experimental OFI transport."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
||||
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
|
||||
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended."
|
||||
DEFAULT OFF)
|
||||
################################################################################
|
||||
|
||||
|
||||
@@ -53,11 +65,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
find_package2(PRIVATE nanomsg REQUIRED)
|
||||
set(PROJECT_nanomsg_VERSION 1.1.3) # Once upstream releases 1.1.5, we should bump again and use version check
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
find_package2(PRIVATE asiofi REQUIRED
|
||||
VERSION 0.3.1
|
||||
@@ -67,17 +74,15 @@ if(BUILD_OFI_TRANSPORT)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
find_package2(PRIVATE msgpack REQUIRED
|
||||
VERSION 3.1.0
|
||||
)
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
find_package2(PRIVATE Flatbuffers REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_DDS_PLUGIN)
|
||||
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
|
||||
find_package2(PRIVATE DDS REQUIRED
|
||||
VERSION 2.4
|
||||
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()
|
||||
|
||||
@@ -87,11 +92,18 @@ if(BUILD_PMIX_PLUGIN)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ)
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
find_package2(PUBLIC FairLogger REQUIRED
|
||||
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
|
||||
@@ -99,7 +111,7 @@ if(BUILD_FAIRMQ)
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
endif()
|
||||
find_package2(PUBLIC Boost REQUIRED
|
||||
VERSION 1.64
|
||||
VERSION 1.66
|
||||
|
||||
COMPONENTS
|
||||
container
|
||||
@@ -113,15 +125,37 @@ if(BUILD_FAIRMQ)
|
||||
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
|
||||
)
|
||||
if(USE_EXTERNAL_GTEST)
|
||||
find_package2(PRIVATE GTest VERSION 1.7.0)
|
||||
endif()
|
||||
if(NOT GTest_FOUND)
|
||||
build_bundled(GTest extern/googletest)
|
||||
find_package2(PRIVATE GTest REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_DOCS)
|
||||
@@ -135,12 +169,7 @@ endif()
|
||||
|
||||
|
||||
# Targets ######################################################################
|
||||
if(BUILD_FAIRMQ)
|
||||
configure_file(${PROJECT_NAME_LOWER}/Version.h.in
|
||||
${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
@ONLY
|
||||
)
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
add_subdirectory(fairmq)
|
||||
endif()
|
||||
|
||||
@@ -177,9 +206,6 @@ endif()
|
||||
if(BUILD_PMIX_PLUGIN)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS pmix_plugin)
|
||||
endif()
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS nanomsg_transport)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS ofi_transport)
|
||||
endif()
|
||||
@@ -189,15 +215,17 @@ endif()
|
||||
if(BUILD_DOCS)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS docs)
|
||||
endif()
|
||||
if(BUILD_SDK)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk)
|
||||
endif()
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
||||
# Installation #################################################################
|
||||
if(BUILD_FAIRMQ)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
||||
)
|
||||
|
||||
install(FILES cmake/FindZeroMQ.cmake
|
||||
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
||||
)
|
||||
@@ -207,6 +235,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()
|
||||
################################################################################
|
||||
@@ -242,16 +286,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()
|
||||
@@ -272,19 +308,12 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
endif()
|
||||
elseif(${dep} STREQUAL GTest)
|
||||
get_filename_component(prefix ${GTEST_INCLUDE_DIRS}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL msgpack)
|
||||
get_target_property(msgpack_include msgpackc-cxx INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${msgpack_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL asiofi)
|
||||
set(prefix ${asiofi_ROOT})
|
||||
elseif(${dep} STREQUAL OFI)
|
||||
get_filename_component(prefix ${${dep}_INCLUDE_DIRS}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL nanomsg)
|
||||
get_target_property(nn_include nanomsg INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${nn_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL DDS)
|
||||
get_target_property(dds_include DDS::dds_intercom_lib INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${dds_include}/.. ABSOLUTE)
|
||||
set(prefix "${DDS_INSTALL_PREFIX}")
|
||||
elseif(${dep} STREQUAL Boost)
|
||||
if(TARGET Boost::headers)
|
||||
get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
@@ -296,10 +325,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)
|
||||
@@ -319,12 +360,6 @@ else()
|
||||
set(tests_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(nn_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=OFF${CR})")
|
||||
else()
|
||||
set(nn_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}nanomsg_transport${CR} ${nn_summary}")
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (requires C++14) (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
|
||||
else()
|
||||
@@ -338,9 +373,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)
|
||||
@@ -355,6 +390,18 @@ else()
|
||||
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
|
||||
if(BUILD_SDK)
|
||||
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (required C++14) (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
|
||||
else()
|
||||
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)
|
||||
@@ -376,6 +423,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 " ")
|
||||
################################################################################
|
||||
|
@@ -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
|
||||
|
69
COPYRIGHT
69
COPYRIGHT
@@ -4,9 +4,9 @@ Upstream-Contact: Mohammad Al-Turany <m.al-turany@gsi.de>
|
||||
Source: https://github.com/FairRootGroup/FairMQ
|
||||
|
||||
Files: *
|
||||
Copyright: 2012-2018, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
Copyright: 2012-2018, [see AUTHORS file]
|
||||
Copyright: 2012-2018, [see CONTRIBUTORS file]
|
||||
Copyright: 2012-2019, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
Copyright: 2012-2019, [see AUTHORS file]
|
||||
Copyright: 2012-2019, [see CONTRIBUTORS file]
|
||||
Comment: The copyright of individual contributors is documented in the
|
||||
Git history.
|
||||
License: LGPL-3.0-only
|
||||
@@ -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.
|
||||
|
2
Dart.sh
2
Dart.sh
@@ -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
|
||||
|
@@ -26,15 +26,16 @@ Set(configure_options "${configure_options};-DCTEST_USE_LAUNCHERS=${CTEST_USE_LA
|
||||
|
||||
Set(configure_options "${configure_options};-DDISABLE_COLOR=ON")
|
||||
Set(configure_options "${configure_options};-DCMAKE_PREFIX_PATH=$ENV{SIMPATH}")
|
||||
Set(configure_options "${configure_options};-DBUILD_NANOMSG_TRANSPORT=ON")
|
||||
# Set(configure_options "${configure_options};-DBUILD_OFI_TRANSPORT=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_DDS_PLUGIN=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_SDK=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_SDK_COMMANDS=ON")
|
||||
Set(configure_options "${configure_options};-DFAST_BUILD=ON")
|
||||
Set(configure_options "${configure_options};-DCOTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES=-j$ENV{number_of_processors}")
|
||||
|
||||
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)
|
||||
@@ -42,6 +43,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()
|
||||
|
||||
@@ -57,19 +59,11 @@ 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 1
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
RETURN_VALUE _ctest_test_ret_val
|
||||
)
|
||||
If("$ENV{do_codecov_upload}")
|
||||
ForEach(i RANGE 4)
|
||||
# Gather statistics to catch time sensitive branches
|
||||
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
)
|
||||
EndForEach()
|
||||
EndIf()
|
||||
|
||||
If(GCOV_COMMAND)
|
||||
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS coverage)
|
||||
@@ -85,7 +79,7 @@ If("$ENV{do_codecov_upload}")
|
||||
EndIf()
|
||||
|
||||
Ctest_Submit()
|
||||
|
||||
|
||||
if (_ctest_test_ret_val)
|
||||
Message(FATAL_ERROR "Some tests failed.")
|
||||
endif()
|
||||
|
16
Jenkinsfile
vendored
16
Jenkinsfile
vendored
@@ -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'
|
||||
|
@@ -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 ->
|
||||
|
67
README.md
67
README.md
@@ -21,7 +21,7 @@ FairMQ is designed to help implementing large-scale data processing workflows ne
|
||||
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
|
||||
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
|
||||
FairMQ provides multiple implementations for its API (so-called "transports",
|
||||
e.g. `zeromq`, `shmem`, `nanomsg`, and `ofi` (in development)) to cover a variety of use cases
|
||||
e.g. `zeromq`, `shmem` and `ofi` (in development)) to cover a variety of use cases
|
||||
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
|
||||
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
|
||||
are communicating through message passing. FairMQ does not only allow the user to use different transport but also to mix them; i.e: A Device can communicate using different transport on different channels at the same time. Device execution is modelled as a simple state machine that
|
||||
@@ -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`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -70,30 +66,48 @@ 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()
|
||||
find_package(FairMQ 1.1.0 COMPONENTS dds_plugin)
|
||||
```
|
||||
|
||||
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)
|
||||
* [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:
|
||||
@@ -101,12 +115,11 @@ On command line:
|
||||
* `-DDISABLE_COLOR=ON` disables coloured console output.
|
||||
* `-DBUILD_TESTING=OFF` disables building of tests.
|
||||
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
|
||||
* `-DBUILD_NANOMSG_TRANSPORT=ON` enables building of nanomsg transport.
|
||||
* `-DBUILD_OFI_TRANSPORT=ON` enables building of the experimental OFI transport.
|
||||
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
|
||||
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
|
||||
* `-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 +178,4 @@ 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)
|
||||
|
@@ -13,12 +13,12 @@ set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
set(@PROJECT_NAME@_GIT_VERSION @PROJECT_GIT_VERSION@)
|
||||
set(@PROJECT_NAME@_GIT_DATE @PROJECT_GIT_DATE@)
|
||||
|
||||
set_and_check(@PROJECT_NAME@_PREFIX @PACKAGE_CMAKE_INSTALL_PREFIX@)
|
||||
set_and_check(@PROJECT_NAME@_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_BINDIR@)
|
||||
set_and_check(@PROJECT_NAME@_INCDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@)
|
||||
set_and_check(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR@)
|
||||
set_and_check(@PROJECT_NAME@_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_DATADIR@)
|
||||
set_and_check(@PROJECT_NAME@_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_CMAKEMODDIR@)
|
||||
set(@PROJECT_NAME@_PREFIX @PACKAGE_CMAKE_INSTALL_PREFIX@)
|
||||
set(@PROJECT_NAME@_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_BINDIR@)
|
||||
set(@PROJECT_NAME@_INCDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@)
|
||||
set(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR@)
|
||||
set(@PROJECT_NAME@_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_DATADIR@)
|
||||
set(@PROJECT_NAME@_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_CMAKEMODDIR@)
|
||||
|
||||
set(@PROJECT_NAME@_CXX_STANDARD_REQUIRED @CMAKE_CXX_STANDARD_REQUIRED@)
|
||||
set(@PROJECT_NAME@_CXX_STANDARD @CMAKE_CXX_STANDARD@)
|
||||
@@ -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@
|
||||
|
@@ -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
|
||||
@@ -176,7 +178,7 @@ macro(set_fairmq_defaults)
|
||||
set(analyser "clang-tidy")
|
||||
find_program(${analyser}_FOUND "${analyser}")
|
||||
if(${analyser}_FOUND)
|
||||
set(CMAKE_CXX_CLANG_TIDY "${${analyser}_FOUND}" "-color")
|
||||
set(CMAKE_CXX_CLANG_TIDY "${${analyser}_FOUND}")
|
||||
endif()
|
||||
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
|
||||
|
||||
@@ -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 ${ARGS_COMPONENTS})
|
||||
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 ${ARGS_COMPONENTS})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${__components__})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
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 ${ARGS_COMPONENTS})
|
||||
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
53
cmake/Findasio.cmake
Normal 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()
|
||||
|
@@ -4,7 +4,37 @@
|
||||
|
||||
## 3.1 Device Configuration
|
||||
|
||||
Devices receive configuration primarily via provided command line options (that can be extended per device).
|
||||
Device Configuration is stored in configuration object - `fair::mq::ProgOptions`. It is accessible by the device, plugins or from DeviceRunner/main:
|
||||
|
||||
Plugins <---read/write---> ProgOptions <---read/write---> Device
|
||||
|
||||
Whenever a configuration property is set, it is set in ProgOptions. Device/Channels/User code read this value and apply it as necessary at different stages:
|
||||
- apply it immidiately
|
||||
- apply it in device/channels during InitializingDevice/Binding/Connecting states
|
||||
|
||||
Here is an overview of the device/channel options and when they are applied:
|
||||
|
||||
| Property | Applied in |
|
||||
| --- | --- |
|
||||
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `file-severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `verbosity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `color` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `log-to-file` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `id` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `io-threads` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `transport` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `network-interface` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `init-timeout` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `max-run-time` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `shm-segment-size` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `shm-monitor` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `ofi-size-hint` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `rate` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `session` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `chan.*` | at the end of `fair::mq::State::InitializingDevice` (channel addresses can be also applied during `fair::mq::State::Binding`/`fair::mq::State::Connecting`) |
|
||||
|
||||
## 3.2 Configuration options
|
||||
|
||||
## 3.2 Communication Channels Configuration
|
||||
|
||||
@@ -32,6 +62,14 @@ This parser reads channel configuration from a JSON file. Example:
|
||||
"address": "tcp://*:5555",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"sndKernelSize" : 0,
|
||||
"rcvKernelSize" : 0,
|
||||
"transport": "shmem",
|
||||
"linger": "500",
|
||||
"portRangeMin": "22000",
|
||||
"portRangeMax": "23000",
|
||||
"autoBind": false,
|
||||
"numSockets": 0,
|
||||
"rateLogging": 1
|
||||
}
|
||||
]
|
||||
@@ -48,9 +86,7 @@ This parser reads channel configuration from a JSON file. Example:
|
||||
"type": "pull",
|
||||
"method": "connect",
|
||||
"address": "tcp://localhost:5555",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
"transport": "shmem"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ Topology configuration is currently happening via setup scripts. This is very ru
|
||||
|
||||
## 1.2 Communication Patterns
|
||||
|
||||
FairMQ devices communicate via the communication patterns offered by ZeroMQ (or nanomsg): PUSH-PULL, PUB-SUB, REQ-REP, PAIR, [more info here](http://api.zeromq.org/4-0:zmq-socket). Each transport may provide further patterns.
|
||||
FairMQ devices communicate via the communication patterns offered by ZeroMQ: PUSH-PULL, PUB-SUB, REQ-REP, PAIR, [more info here](http://api.zeromq.org/4-0:zmq-socket). Each transport may provide further patterns.
|
||||
|
||||
## 1.3 State Machine
|
||||
|
||||
@@ -48,6 +48,6 @@ Without the interactive mode, for example for a run in background, two other con
|
||||
|
||||
## 1.4 Multiple devices in the same process
|
||||
|
||||
Technically one can create two or more devices within the same process without any conflicts. However the configuration (FairMQProgOptions) currently assumes the supplied configuration values are for one device/process.
|
||||
Technically one can create two or more devices within the same process without any conflicts. However the configuration (fair::mq::ProgOptions) currently assumes the supplied configuration values are for one device/process.
|
||||
|
||||
← [Back](../README.md)
|
||||
|
34
docs/SDK.md
Normal file
34
docs/SDK.md
Normal 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)
|
@@ -2,7 +2,7 @@
|
||||
|
||||
# 2. Transport Interface
|
||||
|
||||
The communication layer is available through the transport interface. Three interface implementations are currently available. Main implementation uses the [ZeroMQ](http://zeromq.org) library. Alternative implementation relies on the [nanomsg](http://nanomsg.org) library. Third transport implementation is using shared memory via boost::interprocess & ZeroMQ combination.
|
||||
The communication layer is available through the transport interface. Three interface implementations are currently available. Main implementation uses the [ZeroMQ](http://zeromq.org) library. Second transport implementation is using shared memory via boost::interprocess & ZeroMQ combination.
|
||||
|
||||
Here is an overview to give an idea how the interface is implemented:
|
||||
|
||||
@@ -10,20 +10,20 @@ Here is an overview to give an idea how the interface is implemented:
|
||||
|
||||
Currently, the transports have been tested to work with these communication patterns:
|
||||
|
||||
| | zeromq | nanomsg | shmem |
|
||||
| ------------- |--------| ------- | ----- |
|
||||
| PAIR | yes | yes | yes |
|
||||
| PUSH/PULL | yes | yes | yes |
|
||||
| PUB/SUB | yes | yes | no |
|
||||
| REQ/REP | yes | yes | yes |
|
||||
| | zeromq | shmem |
|
||||
| ------------- |--------| ----- |
|
||||
| PAIR | yes | yes |
|
||||
| PUSH/PULL | yes | yes |
|
||||
| PUB/SUB | yes | no |
|
||||
| REQ/REP | yes | yes |
|
||||
|
||||
The next table shows the supported address types for each transport implementation:
|
||||
|
||||
| | zeromq | nanomsg | shmem | comment |
|
||||
| ----------- | ------ | ------- | ----- | --------------------------------------------- |
|
||||
| `inproc://` | yes | yes | yes | in process: useful for unit testing |
|
||||
| `ipc://` | yes | yes | yes | inter process comm: useful on single machine |
|
||||
| `tcp://` | yes | yes | yes | useful for any communication, local or remote |
|
||||
| | zeromq | shmem | comment |
|
||||
| ----------- | ------ | ----- | --------------------------------------------- |
|
||||
| `inproc://` | yes | yes | in process: useful for unit testing |
|
||||
| `ipc://` | yes | yes | inter process comm: useful on single machine |
|
||||
| `tcp://` | yes | yes | useful for any communication, local or remote |
|
||||
|
||||
## 2.1 Message
|
||||
|
||||
|
@@ -34,11 +34,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BIN
|
||||
add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
|
||||
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.1-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh nanomsg)
|
||||
set_tests_properties(Example.1-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
|
||||
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
|
@@ -6,9 +6,6 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <thread> // this_thread::sleep_for
|
||||
#include <chrono>
|
||||
|
||||
#include "Sampler.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -26,8 +23,8 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
// Get the fText and fMaxIterations values from the command line options (via fConfig)
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
|
@@ -30,7 +30,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_1::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_1::Sink();
|
||||
}
|
||||
|
@@ -42,11 +42,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_B
|
||||
add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
|
||||
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.1-n-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh nanomsg)
|
||||
set_tests_properties(Example.1-n-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
|
||||
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
|
@@ -32,8 +32,8 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
// Get the fText and fMaxIterations values from the command line options (via fConfig)
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
|
@@ -30,7 +30,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Processor();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Sink();
|
||||
}
|
||||
|
@@ -13,9 +13,9 @@ add_subdirectory(copypush)
|
||||
add_subdirectory(dds)
|
||||
add_subdirectory(multipart)
|
||||
add_subdirectory(multiple-channels)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_subdirectory(multiple-transports)
|
||||
endif()
|
||||
add_subdirectory(multiple-transports)
|
||||
add_subdirectory(n-m)
|
||||
add_subdirectory(qc)
|
||||
add_subdirectory(readout)
|
||||
add_subdirectory(region)
|
||||
add_subdirectory(req-rep)
|
||||
|
@@ -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.
|
||||
|
||||
## Multiple Transports
|
||||
|
||||
## Sending Multipart messages
|
||||
This examples shows how to combine different channel transports (zeromq/shmem) inside of one device and/or topology.
|
||||
|
||||
This example shows how to send a multipart message from one device to the other. (two parts message parts - header and body).
|
||||
## n-m
|
||||
|
||||
A topology consisting of three layers of devices: synchronizer -> n * senders -> m * receivers.
|
||||
|
||||
## Multiple Transports example
|
||||
## QC
|
||||
|
||||
This examples shows how to combine different channel transports (zeromq/nanomsg/shmem) inside of one device and/or topology.
|
||||
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.
|
||||
|
||||
## Region example
|
||||
## 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.
|
||||
|
@@ -17,22 +17,12 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-builtin-devices.sh.in ${CMAKE
|
||||
add_test(NAME Example.BuiltinDevices.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq)
|
||||
set_tests_properties(Example.BuiltinDevices.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.BuiltinDevices.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh nanomsg)
|
||||
set_tests_properties(Example.BuiltinDevices.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.BuiltinDevices.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem)
|
||||
set_tests_properties(Example.BuiltinDevices.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
|
||||
add_test(NAME Example.BuiltinDevices.multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq true 2)
|
||||
set_tests_properties(Example.BuiltinDevices.multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.BuiltinDevices.multipart.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh nanomsg true 2)
|
||||
set_tests_properties(Example.BuiltinDevices.multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.BuiltinDevices.multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem true 2)
|
||||
set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
||||
|
||||
|
@@ -35,11 +35,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURREN
|
||||
add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
|
||||
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.CopyPush.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh nanomsg)
|
||||
set_tests_properties(Example.CopyPush.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
|
||||
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
|
@@ -33,12 +33,11 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fNumDataChannels = fChannels.at("data").size();
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
{
|
||||
|
||||
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
|
||||
// Should only be used for small data because of the cost of an additional copy
|
||||
FairMQMessagePtr msg(NewSimpleMessage(fCounter++));
|
||||
|
@@ -27,7 +27,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_copypush::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_copypush::Sink();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2014-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
@@ -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,40 +28,70 @@ 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)
|
||||
|
||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(DDS_PLUGIN_LIB_DIR ${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
|
||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
||||
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)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-hosts.cfg ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh @ONLY)
|
||||
|
||||
# test
|
||||
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
|
||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
||||
set(DDS_PLUGIN_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR})
|
||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
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-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install @ONLY)
|
||||
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-hosts.cfg
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
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}
|
||||
)
|
||||
|
||||
install(
|
||||
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
|
||||
)
|
||||
|
@@ -26,10 +26,14 @@ Sampler::Sampler()
|
||||
{
|
||||
}
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fIterations = fConfig->GetValue<uint64_t>("iterations");
|
||||
fCounter = 0;
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
|
||||
// Should only be used for small data because of the cost of an additional copy
|
||||
FairMQMessagePtr msg(NewSimpleMessage("Data"));
|
||||
@@ -38,11 +42,18 @@ bool Sampler::ConditionalRun()
|
||||
|
||||
// in case of error or transfer interruption, return false to go to IDLE state
|
||||
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
|
||||
if (Send(msg, "data1") < 0)
|
||||
{
|
||||
if (Send(msg, "data1") < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fIterations > 0) {
|
||||
++fCounter;
|
||||
if (fCounter >= fIterations) {
|
||||
LOG(info) << "Sent " << fCounter << " messages. Finished.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -25,9 +25,14 @@ class Sampler : public FairMQDevice
|
||||
public:
|
||||
Sampler();
|
||||
virtual ~Sampler();
|
||||
void InitTask() override;
|
||||
|
||||
protected:
|
||||
virtual bool ConditionalRun();
|
||||
bool ConditionalRun() override;
|
||||
|
||||
private:
|
||||
uint64_t fIterations;
|
||||
uint64_t fCounter;
|
||||
};
|
||||
|
||||
} // namespace example_dds
|
||||
|
@@ -25,11 +25,24 @@ Sink::Sink()
|
||||
OnData("data2", &Sink::HandleData);
|
||||
}
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fIterations = fConfig->GetValue<uint64_t>("iterations");
|
||||
fCounter = 0;
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
|
||||
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
|
||||
{
|
||||
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
|
||||
|
||||
if (fIterations > 0) {
|
||||
++fCounter;
|
||||
if (fCounter >= fIterations) {
|
||||
LOG(info) << "Received " << fCounter << " messages. Finished.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// return true if want to be called again (otherwise go to IDLE state)
|
||||
return true;
|
||||
}
|
||||
|
@@ -25,9 +25,14 @@ class Sink : public FairMQDevice
|
||||
public:
|
||||
Sink();
|
||||
virtual ~Sink();
|
||||
void InitTask() override;
|
||||
|
||||
protected:
|
||||
bool HandleData(FairMQMessagePtr&, int);
|
||||
|
||||
private:
|
||||
uint64_t fIterations;
|
||||
uint64_t fCounter;
|
||||
};
|
||||
|
||||
} // namespace example_dds
|
||||
|
@@ -1,7 +1,3 @@
|
||||
@bash_begin@
|
||||
# source setup.sh
|
||||
@bash_end@
|
||||
|
||||
sampler, username@localhost, , /path/to/dds-work/, 1
|
||||
processor, username@localhost, , /path/to/dds-work/, 10
|
||||
sink, username@localhost, , /path/to/dds-work/, 1
|
||||
sampler, 127.0.0.1, , /tmp/fairmq-ex-dds, 1
|
||||
processor, 127.0.0.1, , /tmp/fairmq-ex-dds, 10
|
||||
sink, 127.0.0.1, , /tmp/fairmq-ex-dds, 1
|
||||
|
52
examples/dds/ex-dds-topology-infinite.xml
Normal file
52
examples/dds/ex-dds-topology-infinite.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<topology name="ExampleDDS">
|
||||
|
||||
<property name="fmqchan_data1" />
|
||||
<property name="fmqchan_data2" />
|
||||
|
||||
<declrequirement name="SamplerWorker" type="wnname" value="sampler"/>
|
||||
<declrequirement name="ProcessorWorker" type="wnname" value="processor"/>
|
||||
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
|
||||
|
||||
<decltask name="Sampler">
|
||||
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind --rate 100 -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SamplerWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">fmqchan_data1</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Processor">
|
||||
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>ProcessorWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="read">fmqchan_data1</name>
|
||||
<name access="read">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Sink">
|
||||
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SinkWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<main name="main">
|
||||
<task>Sampler</task>
|
||||
<task>Sink</task>
|
||||
<group name="ProcessorGroup" n="10">
|
||||
<task>Processor</task>
|
||||
</group>
|
||||
</main>
|
||||
|
||||
</topology>
|
@@ -1,40 +1,43 @@
|
||||
<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"/>
|
||||
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
|
||||
|
||||
<decltask name="Sampler">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-sampler --id sampler --color false --channel-config name=data1,type=push,method=bind -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind -P dds --iterations 10</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SamplerWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">data1</name>
|
||||
<name access="write">fmqchan_data1</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Processor">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-processor --id processor_%taskIndex% --config-key processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<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>
|
||||
|
||||
<decltask name="Sink">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-sink --id sink --color false --channel-config name=data2,type=pull,method=bind -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds --iterations 10</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SinkWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">data2</name>
|
||||
<name access="write">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
|
16
examples/dds/fairmq-ex-dds-env.sh
Executable file
16
examples/dds/fairmq-ex-dds-env.sh
Executable 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
|
85
examples/dds/fairmq-start-ex-dds.sh.in
Executable file
85
examples/dds/fairmq-start-ex-dds.sh.in
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/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-dds.sh [localhost] -> submit agents with localhost plugin
|
||||
# fairmq-start-ex-dds.sh ssh -> submit agents with ssh plugin
|
||||
|
||||
set -e
|
||||
|
||||
cleanup() {
|
||||
dds-session stop $1
|
||||
echo "CLEANUP PERFORMED"
|
||||
}
|
||||
|
||||
source @DDS_INSTALL_PREFIX@/DDS_env.sh
|
||||
export PATH=@BIN_DIR@:$PATH
|
||||
|
||||
plugin=${1:-localhost}
|
||||
|
||||
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=12
|
||||
if [[ "$plugin" == "ssh" ]]; then
|
||||
dds-submit -r ${plugin} -c @DATA_DIR@/ex-dds-hosts.cfg
|
||||
else
|
||||
dds-submit -r ${plugin} --slots ${requiredNofSlots}
|
||||
fi
|
||||
echo "...waiting for ${requiredNofSlots} idle slots..."
|
||||
dds-info --idle-count --wait ${requiredNofSlots}
|
||||
|
||||
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})"
|
||||
|
||||
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
|
||||
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
|
||||
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
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Processor();
|
||||
}
|
||||
|
@@ -11,11 +11,15 @@
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
|
||||
void addCustomOptions(bpo::options_description& /*options*/)
|
||||
void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()(
|
||||
"iterations,i",
|
||||
bpo::value<uint64_t>()->default_value(1000),
|
||||
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Sampler();
|
||||
}
|
||||
|
@@ -11,11 +11,15 @@
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
|
||||
void addCustomOptions(bpo::options_description& /*options*/)
|
||||
void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()(
|
||||
"iterations,i",
|
||||
bpo::value<uint64_t>()->default_value(1000),
|
||||
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Sink();
|
||||
}
|
||||
|
@@ -32,19 +32,14 @@ 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")
|
||||
|
||||
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")
|
||||
endif()
|
||||
set_tests_properties(Example.Multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
|
||||
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
|
||||
|
@@ -31,7 +31,7 @@ Sampler::Sampler()
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
@@ -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
|
||||
|
@@ -24,7 +24,7 @@ class Sampler : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
Sampler();
|
||||
virtual ~Sampler();
|
||||
virtual ~Sampler() {}
|
||||
|
||||
protected:
|
||||
virtual void InitTask();
|
||||
|
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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 &
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(5), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multipart::Sampler();
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multipart::Sink();
|
||||
}
|
||||
|
@@ -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=$!
|
||||
|
||||
|
@@ -39,11 +39,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMA
|
||||
add_test(NAME Example.MultipleChannels.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
|
||||
set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.MultipleChannels.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh nanomsg)
|
||||
set_tests_properties(Example.MultipleChannels.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
|
@@ -33,8 +33,8 @@ Sampler::Sampler()
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Sampler::Run()
|
||||
|
@@ -31,7 +31,7 @@ Sink::Sink()
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sink::HandleBroadcast(FairMQMessagePtr& msg, int /*index*/)
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Broadcaster();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Sink();
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
Multiple Transports example
|
||||
===========================
|
||||
|
||||
This example demonstrates use of multiple transports (zeromq/nanomsg/shmem) within the same topology and/or device. It is a simple topology consisting of two samplers and a sink. The devices are connected via 3 channels:
|
||||
This example demonstrates use of multiple transports (zeromq/shmem) within the same topology and/or device. It is a simple topology consisting of two samplers and a sink. The devices are connected via 3 channels:
|
||||
|
||||

|
||||
|
||||
Each device has main transport that it uses. By default it is ZeroMQ, and can be overriden via the `--transport` cmd option. The device will initialize additional transports if any of the channels have them configured (e.g. as an option to `--channel-config`).
|
||||
|
||||
In this example sampler1 and sink are started with `--transport shmem`, making shared memory their main transport, sampler2 with `--transport nanomsg`. Additionally, the ack channel is configured to use zeromq as its transport.
|
||||
In this example sampler1 and sink are started with `--transport shmem`, making shared memory their main transport, sampler2 with `--transport zeromq`. Additionally, the ack channel is configured to use zeromq as its transport.
|
||||
|
||||
The main two things that a transport does is transfer of data and allocation of memory for the messages. By default, new messages are created via the main device transport. If a message has been created with one transport and is to be transferred with another, it has to be copied into a new message of the target transport. This happens automatically behind the scenes. To avoid this copy the device can create messages via `NewMessageFor(const string& channelName, int subChannelIndex, ...)` method, that creates the messages via the transport of the given channel (check sampler1 and sink for an example) or as the channel directly to create a message.
|
||||
|
@@ -22,7 +22,7 @@ Sampler1::Sampler1()
|
||||
|
||||
void Sampler1::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Sampler1::PreRun()
|
||||
|
@@ -21,7 +21,7 @@ Sampler2::Sampler2()
|
||||
|
||||
void Sampler2::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler2::ConditionalRun()
|
||||
|
@@ -31,7 +31,7 @@ Sink::Sink()
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -13,7 +13,7 @@ xterm -geometry 80x30+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER1 &
|
||||
SAMPLER2="fairmq-ex-multiple-transports-sampler2"
|
||||
SAMPLER2+=" --id sampler2"
|
||||
SAMPLER2+=" --severity debug"
|
||||
SAMPLER2+=" --transport nanomsg"
|
||||
SAMPLER2+=" --transport shmem"
|
||||
SAMPLER2+=" --channel-config name=data2,type=push,method=bind,address=tcp://127.0.0.1:5556"
|
||||
xterm -geometry 80x30+0+450 -hold -e @EX_BIN_DIR@/$SAMPLER2 &
|
||||
|
||||
@@ -22,6 +22,6 @@ SINK+=" --id sink1"
|
||||
SINK+=" --severity debug"
|
||||
SINK+=" --transport shmem"
|
||||
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555"
|
||||
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=nanomsg"
|
||||
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=shmem"
|
||||
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq"
|
||||
xterm -geometry 80x30+500+225 -hold -e @EX_BIN_DIR@/$SINK &
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sampler1();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sampler2();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sink();
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ SINK+=" --max-iterations 1"
|
||||
SINK+=" --control static --color false"
|
||||
SINK+=" --transport shmem"
|
||||
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555"
|
||||
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=nanomsg"
|
||||
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=zeromq"
|
||||
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
|
||||
SINK_PID=$!
|
||||
@@ -37,7 +37,7 @@ SAMPLER2+=" --session $SESSION"
|
||||
SAMPLER2+=" --verbosity veryhigh"
|
||||
SAMPLER2+=" --max-iterations 1"
|
||||
SAMPLER2+=" --control static --color false"
|
||||
SAMPLER2+=" --transport nanomsg"
|
||||
SAMPLER2+=" --transport zeromq"
|
||||
SAMPLER2+=" --channel-config name=data2,type=push,method=bind,address=tcp://127.0.0.1:5556"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER2 &
|
||||
SAMPLER2_PID=$!
|
||||
|
99
examples/n-m/CMakeLists.txt
Normal file
99
examples/n-m/CMakeLists.txt
Normal 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
|
||||
)
|
@@ -5,31 +5,20 @@
|
||||
* 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 "FairMQUnmanagedRegionNN.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <cstdint>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQUnmanagedRegionNN::FairMQUnmanagedRegionNN(const size_t size, FairMQRegionCallback callback)
|
||||
: fBuffer(malloc(size))
|
||||
, fSize(size)
|
||||
, fCallback(callback)
|
||||
namespace example_n_m
|
||||
{
|
||||
}
|
||||
|
||||
void* FairMQUnmanagedRegionNN::GetData() const
|
||||
struct Header
|
||||
{
|
||||
return fBuffer;
|
||||
}
|
||||
std::uint16_t id;
|
||||
int senderIndex;
|
||||
};
|
||||
|
||||
size_t FairMQUnmanagedRegionNN::GetSize() const
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
} // namespace example_n_m
|
||||
|
||||
FairMQUnmanagedRegionNN::~FairMQUnmanagedRegionNN()
|
||||
{
|
||||
LOG(debug) << "destroying region";
|
||||
free(fBuffer);
|
||||
}
|
||||
#endif /* FAIR_MQ_EXAMPLE_N_M_HEADER_H */
|
4
examples/n-m/README.md
Normal file
4
examples/n-m/README.md
Normal 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.
|
44
examples/n-m/ex-n-m-pair-topology.xml
Normal file
44
examples/n-m/ex-n-m-pair-topology.xml
Normal 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>
|
44
examples/n-m/ex-n-m-topology.xml
Normal file
44
examples/n-m/ex-n-m-topology.xml
Normal 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>
|
16
examples/n-m/fairmq-ex-n-m-env.sh
Executable file
16
examples/n-m/fairmq-ex-n-m-env.sh
Executable 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
|
76
examples/n-m/fairmq-start-ex-n-m-dds.sh.in
Executable file
76
examples/n-m/fairmq-start-ex-n-m-dds.sh.in
Executable 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
|
76
examples/n-m/fairmq-start-ex-n-m-pair-dds.sh.in
Executable file
76
examples/n-m/fairmq-start-ex-n-m-pair-dds.sh.in
Executable 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
|
60
examples/n-m/fairmq-start-ex-n-m-pair.sh.in
Executable file
60
examples/n-m/fairmq-start-ex-n-m-pair.sh.in
Executable 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 &
|
60
examples/n-m/fairmq-start-ex-n-m.sh.in
Executable file
60
examples/n-m/fairmq-start-ex-n-m.sh.in
Executable 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 &
|
119
examples/n-m/runReceiver.cxx
Normal file
119
examples/n-m/runReceiver.cxx
Normal 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(); }
|
79
examples/n-m/runSender.cxx
Normal file
79
examples/n-m/runSender.cxx
Normal 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(); }
|
46
examples/n-m/runSynchronizer.cxx
Normal file
46
examples/n-m/runSynchronizer.cxx
Normal 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(); }
|
71
examples/qc/CMakeLists.txt
Normal file
71
examples/qc/CMakeLists.txt
Normal 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
4
examples/qc/README.md
Normal 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.
|
48
examples/qc/ex-qc-topology.xml
Normal file
48
examples/qc/ex-qc-topology.xml
Normal 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
16
examples/qc/fairmq-ex-qc-env.sh
Executable 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
|
82
examples/qc/fairmq-start-ex-qc.sh.in
Executable file
82
examples/qc/fairmq-start-ex-qc.sh.in
Executable 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
|
59
examples/qc/runQCDispatcher.cxx
Normal file
59
examples/qc/runQCDispatcher.cxx
Normal 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
26
examples/qc/runQCTask.cxx
Normal 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(); }
|
36
examples/qc/runSampler.cxx
Normal file
36
examples/qc/runSampler.cxx
Normal 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(); }
|
@@ -6,30 +6,20 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "FairMQUnmanagedRegionZMQ.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include "runFairMQDevice.h"
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
using namespace std;
|
||||
#include <string>
|
||||
|
||||
FairMQUnmanagedRegionZMQ::FairMQUnmanagedRegionZMQ(const size_t size, FairMQRegionCallback callback)
|
||||
: fBuffer(malloc(size))
|
||||
, fSize(size)
|
||||
, fCallback(callback)
|
||||
class Sink : public FairMQDevice
|
||||
{
|
||||
}
|
||||
public:
|
||||
Sink() { OnData("data2", &Sink::HandleData); }
|
||||
|
||||
void* FairMQUnmanagedRegionZMQ::GetData() const
|
||||
{
|
||||
return fBuffer;
|
||||
}
|
||||
protected:
|
||||
bool HandleData(FairMQMessagePtr& /*msg*/, int /*index*/) { return true; }
|
||||
};
|
||||
|
||||
size_t FairMQUnmanagedRegionZMQ::GetSize() const
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
|
||||
FairMQUnmanagedRegionZMQ::~FairMQUnmanagedRegionZMQ()
|
||||
{
|
||||
LOG(debug) << "destroying region";
|
||||
free(fBuffer);
|
||||
}
|
||||
namespace bpo = boost::program_options;
|
||||
void addCustomOptions(bpo::options_description&) {}
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new Sink(); }
|
@@ -24,7 +24,7 @@ class Builder : public FairMQDevice
|
||||
|
||||
void Init() override
|
||||
{
|
||||
fOutputChannelName = fConfig->GetValue<std::string>("output-name");
|
||||
fOutputChannelName = fConfig->GetProperty<std::string>("output-name");
|
||||
OnData("rb", &Builder::HandleData);
|
||||
}
|
||||
|
||||
|
@@ -31,16 +31,16 @@ class Readout : public FairMQDevice
|
||||
protected:
|
||||
void InitTask() override
|
||||
{
|
||||
fMsgSize = fConfig->GetValue<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("rb",
|
||||
0,
|
||||
10000000,
|
||||
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
|
||||
--fNumUnackedMsgs;
|
||||
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
|
||||
fNumUnackedMsgs -= blocks.size();
|
||||
if (fMaxIterations > 0) {
|
||||
LOG(debug) << "Received ack";
|
||||
LOG(debug) << "Received " << blocks.size() << " acks";
|
||||
}
|
||||
}
|
||||
));
|
||||
|
@@ -25,7 +25,7 @@ class Receiver : public FairMQDevice
|
||||
void InitTask() override
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Run() override
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user