mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-15 17:41:45 +00:00
Compare commits
260 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f3bc9e05a8 | ||
|
5facc441b8 | ||
|
2602f53585 | ||
|
0976465338 | ||
|
9144258b89 | ||
|
be55565617 | ||
|
d7e2fbecea | ||
|
72175e5757 | ||
|
effba534f0 | ||
|
efd42075a9 | ||
|
5228407932 | ||
|
30e81d58f8 | ||
|
2c7c46f2fd | ||
|
0a5122bb24 | ||
|
fc49687879 | ||
|
66a4df0667 | ||
|
978191fa6c | ||
|
cef6d0afcd | ||
|
47ec550792 | ||
|
b4aeb320e5 | ||
|
107248be0a | ||
|
68ceaba501 | ||
|
4b6cf8b181 | ||
|
21d6cf9830 | ||
|
bffe74c5cf | ||
|
72f319e276 | ||
|
62438bd99e | ||
|
c8ad684b18 | ||
|
a5ec83208d | ||
|
fc2241ece7 | ||
|
1f26883b75 | ||
|
edbdc57332 | ||
|
0fd2fcadc2 | ||
|
9b48b31a75 | ||
|
cb4335e59f | ||
|
ce4584b3d8 | ||
|
bbc1dd4600 | ||
|
8327810942 | ||
|
c37742e3b4 | ||
|
93dff3c5a7 | ||
|
2b3e38d9a4 | ||
|
c6b13cd3a1 | ||
|
c5487a11ed | ||
|
4a09154a91 | ||
|
d9a5e82160 | ||
|
751c53171c | ||
|
6815c9c172 | ||
|
02a3980343 | ||
|
38b34785e0 | ||
|
be94ceb7a7 | ||
|
afadbb53e4 | ||
|
749d28a3b5 | ||
|
29f45fa77d | ||
|
ea746b17d0 | ||
|
636846fcdb | ||
|
f46d446d52 | ||
|
db0937f339 | ||
|
bb1ce794b6 | ||
|
9e2373b55d | ||
|
c51e88e114 | ||
|
f9219dab65 | ||
|
0806720f61 | ||
|
e39d17d09e | ||
|
a14502242f | ||
|
d3697ec97b | ||
|
73377c5100 | ||
|
49d8a1b4dd | ||
|
f14f507584 | ||
|
8dd0b25c06 | ||
|
7edf436919 | ||
|
0e5978b160 | ||
|
71b1866d7b | ||
|
6699711e17 | ||
|
120760da0a | ||
|
d03a504ccd | ||
|
cf004f69b2 | ||
|
cfa18ccfce | ||
|
e332e20dbd | ||
|
3ab10ced7a | ||
|
1b30f3ac14 | ||
|
35c7959c53 | ||
|
5ea8ffeb34 | ||
|
04ee1db8e5 | ||
|
4a15a38dd4 | ||
|
0f5e1b6815 | ||
|
5e6ad47223 | ||
|
6932f88c84 | ||
|
5e97d85956 | ||
|
fdbf289364 | ||
|
266843cda5 | ||
|
b126ede45a | ||
|
12e6a874db | ||
|
73109fe6d3 | ||
|
3b2d2a0ac8 | ||
|
72a45f78b3 | ||
|
b63f31d0e0 | ||
|
70a583d08d | ||
|
fe9b87e4e2 | ||
|
2ac27905e7 | ||
|
690e8a0370 | ||
|
1f0c94f898 | ||
|
62ed4e5f80 | ||
|
f1d6b18668 | ||
|
c0153a6b55 | ||
|
86a1dd38a2 | ||
|
be8ab06cc1 | ||
|
b0f73017e2 | ||
|
b83655d5da | ||
|
9c27051cdc | ||
|
65f9519917 | ||
|
b5545c1575 | ||
|
3eca8e9def | ||
|
beb7766fca | ||
|
bf909f94dc | ||
|
1140c4c6ab | ||
|
a6da208e79 | ||
|
ba3a82b1df | ||
|
e8cc104344 | ||
|
d5d5c27958 | ||
|
5a7dcd9fc1 | ||
|
78b1c188bf | ||
|
66bc7ba762 | ||
|
88bc1f7a06 | ||
|
f70201610b | ||
|
fc7f6f1116 | ||
|
8125489776 | ||
|
6dd0a44308 | ||
|
afe2dcaa02 | ||
|
aeab9e5407 | ||
|
539e5602a6 | ||
|
beb510ded8 | ||
|
d1c51e0f1f | ||
|
f885b4618e | ||
|
3364da9541 | ||
|
7aec6f91de | ||
|
9e2a002942 | ||
|
52c6264faf | ||
|
79489bb501 | ||
|
c60dd9965c | ||
|
79ca436b74 | ||
|
36d4f3c937 | ||
|
bdf895ae9e | ||
|
42986e664c | ||
|
dd47b34e06 | ||
|
a59c902c74 | ||
|
dabc48c21a | ||
|
236d5a8608 | ||
|
5a782e8726 | ||
|
5008fa4732 | ||
|
b5bb476b0d | ||
|
ea7ae04025 | ||
|
02692e7002 | ||
|
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 |
@@ -1,3 +1,3 @@
|
||||
---
|
||||
Checks: '*,-google-*,-fuchsia-*,-cert-*,-llvm-header-guard,-readability-named-parameter,-misc-non-private-member-variables-in-classes,-*-magic-numbers,-llvm-include-order,-hicpp-no-array-decay,-performance-unnecessary-value-param,-cppcoreguidelines-pro-bounds-array-to-pointer-decay'
|
||||
Checks: 'cppcoreguidelines-*,misc-unused-alias-decls,misc-unused-parameters,modernize-deprecated-headers,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-using,performance-faster-string-find,performance-for-range-copy,performance-unnecessary-copy-initialization,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-container-size-empty,readability-delete-null-pointer,readability-redundant-member-init,readability-redundant-string-init,readability-static-accessed-through-instance,readability-string-compare'
|
||||
HeaderFilterRegex: '/(fairmq/)'
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "extern/asio"]
|
||||
path = extern/asio
|
||||
url = https://github.com/chriskohlhoff/asio
|
||||
[submodule "extern/PicoSHA2"]
|
||||
path = extern/PicoSHA2
|
||||
url = https://github.com/okdshin/PicoSHA2
|
||||
|
122
CMakeLists.txt
122
CMakeLists.txt
@@ -6,8 +6,8 @@
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
|
||||
cmake_policy(VERSION 3.11...3.15)
|
||||
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,11 +18,7 @@ get_git_version()
|
||||
project(FairMQ VERSION ${PROJECT_VERSION} LANGUAGES CXX)
|
||||
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
|
||||
|
||||
if(BUILD_OFI_TRANSPORT OR BUILD_SDK)
|
||||
set(PROJECT_MIN_CXX_STANDARD 14)
|
||||
else()
|
||||
set(PROJECT_MIN_CXX_STANDARD 11)
|
||||
endif()
|
||||
set(PROJECT_MIN_CXX_STANDARD 17)
|
||||
|
||||
set_fairmq_defaults()
|
||||
|
||||
@@ -31,28 +27,30 @@ include(CTest)
|
||||
|
||||
|
||||
# Build options ################################################################
|
||||
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
|
||||
DEFAULT ON)
|
||||
fairmq_build_option(BUILD_TESTING "Build tests."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_NANOMSG_TRANSPORT "Build nanomsg transport."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
||||
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
|
||||
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
|
||||
DEFAULT ON)
|
||||
fairmq_build_option(BUILD_TESTING "Build tests."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
||||
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
|
||||
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(FAST_BUILD "Fast production build. Not recommended for development."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease performance)."
|
||||
DEFAULT OFF)
|
||||
################################################################################
|
||||
|
||||
|
||||
@@ -65,11 +63,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
find_package2(PRIVATE nanomsg REQUIRED)
|
||||
set(PROJECT_nanomsg_VERSION 1.1.3) # Once upstream releases 1.1.5, we should bump again and use version check
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
find_package2(PRIVATE asiofi REQUIRED
|
||||
VERSION 0.3.1
|
||||
@@ -79,27 +72,15 @@ if(BUILD_OFI_TRANSPORT)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
find_package2(PRIVATE msgpack REQUIRED
|
||||
VERSION 3.1.0
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_SDK)
|
||||
set(required_dds_version 2.5.46)
|
||||
else()
|
||||
set(required_dds_version 2.4)
|
||||
endif()
|
||||
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
find_package2(PRIVATE Flatbuffers REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
|
||||
find_package2(PRIVATE DDS REQUIRED
|
||||
VERSION ${required_dds_version}
|
||||
VERSION 3.5.3
|
||||
)
|
||||
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()
|
||||
|
||||
@@ -111,7 +92,7 @@ endif()
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
find_package2(PUBLIC FairLogger REQUIRED
|
||||
VERSION 1.2.0
|
||||
VERSION 1.6.0
|
||||
)
|
||||
|
||||
foreach(dep IN LISTS FairLogger_PACKAGE_DEPENDENCIES)
|
||||
@@ -151,7 +132,7 @@ endif()
|
||||
|
||||
if(BUILD_SDK)
|
||||
find_package2(BUNDLED asio
|
||||
VERSION 1.13.0
|
||||
VERSION 1.18.0
|
||||
)
|
||||
if(NOT asio_FOUND)
|
||||
build_bundled(asio extern/asio)
|
||||
@@ -163,10 +144,14 @@ if(BUILD_FAIRMQ)
|
||||
find_package2(PRIVATE ZeroMQ REQUIRED
|
||||
VERSION 4.1.4
|
||||
)
|
||||
build_bundled(PicoSHA2 extern/PicoSHA2)
|
||||
find_package2(PRIVATE PicoSHA2 REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
find_package2(PRIVATE GTest VERSION 1.7.0)
|
||||
if(USE_EXTERNAL_GTEST)
|
||||
find_package2(PRIVATE GTest VERSION 1.7.0)
|
||||
endif()
|
||||
if(NOT GTest_FOUND)
|
||||
build_bundled(GTest extern/googletest)
|
||||
find_package2(PRIVATE GTest REQUIRED)
|
||||
@@ -221,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()
|
||||
@@ -276,7 +258,7 @@ install_cmake_package()
|
||||
|
||||
# Summary ######################################################################
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}CXX STANDARD${CR} ${BGreen}C++${CMAKE_CXX_STANDARD}${CR} (>= C++${PROJECT_MIN_CXX_STANDARD}, change with ${BMagenta}-DCMAKE_CXX_STANDARD=17${CR})")
|
||||
message(STATUS " ${Cyan}CXX STANDARD${CR} ${BGreen}C++${CMAKE_CXX_STANDARD}${CR} (>= C++${PROJECT_MIN_CXX_STANDARD}, change with ${BMagenta}-DCMAKE_CXX_STANDARD=20${CR})")
|
||||
if(CMAKE_CXX_FLAGS)
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}GLOBAL CXX FLAGS${CR} ${BGreen}${CMAKE_CXX_FLAGS}${CR}")
|
||||
@@ -326,16 +308,10 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
endif()
|
||||
elseif(${dep} STREQUAL GTest)
|
||||
get_filename_component(prefix ${GTEST_INCLUDE_DIRS}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL msgpack)
|
||||
get_target_property(msgpack_include msgpackc-cxx INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${msgpack_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL asiofi)
|
||||
set(prefix ${asiofi_ROOT})
|
||||
elseif(${dep} STREQUAL OFI)
|
||||
get_filename_component(prefix ${${dep}_INCLUDE_DIRS}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL nanomsg)
|
||||
get_target_property(nn_include nanomsg INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${nn_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL DDS)
|
||||
set(prefix "${DDS_INSTALL_PREFIX}")
|
||||
elseif(${dep} STREQUAL Boost)
|
||||
@@ -384,16 +360,10 @@ else()
|
||||
set(tests_summary "${BRed} NO${CR} (enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(nn_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=OFF${CR})")
|
||||
else()
|
||||
set(nn_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_NANOMSG_TRANSPORT=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}nanomsg_transport${CR} ${nn_summary}")
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (requires C++14) (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
|
||||
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
|
||||
else()
|
||||
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (requires C++14) (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
|
||||
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}ofi_transport${CR} ${ofi_summary}")
|
||||
if(BUILD_DDS_PLUGIN)
|
||||
@@ -403,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 (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 (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}pmix_plugin${CR} ${pmix_summary}")
|
||||
if(BUILD_EXAMPLES)
|
||||
@@ -421,9 +391,9 @@ else()
|
||||
endif()
|
||||
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
|
||||
if(BUILD_SDK)
|
||||
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (required C++14) (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
|
||||
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
|
||||
else()
|
||||
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (required C++14) (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
|
||||
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}sdk${CR} ${sdk_summary}")
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
@@ -457,4 +427,10 @@ message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
|
||||
message(STATUS " ")
|
||||
if(FAIRMQ_DEBUG_MODE)
|
||||
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BGreen}${FAIRMQ_DEBUG_MODE}${CR} (disable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=OFF${CR})")
|
||||
else()
|
||||
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ")
|
||||
################################################################################
|
||||
|
@@ -4,8 +4,10 @@ Eulisse, Giulio
|
||||
Karabowicz, Radoslaw
|
||||
Kretz, Matthias <kretz@kde.org>
|
||||
Krzewicki, Mikolaj
|
||||
Lebedev, Andrey
|
||||
Mrnjavac, Teo <teo.m@cern.ch>
|
||||
Neskovic, Gvozden
|
||||
Richter, Matthias
|
||||
Tacke, Christian
|
||||
Uhlig, Florian
|
||||
Wenzel, Sandro
|
||||
|
23
COPYRIGHT
23
COPYRIGHT
@@ -23,6 +23,10 @@ Files: extern/asio
|
||||
Copyright: 2003-2019, Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
License: BSL-1.0
|
||||
|
||||
Files: extern/PicoSHA2
|
||||
Copyright: 2017 okdshin
|
||||
License: MIT
|
||||
|
||||
License: LGPL-3.0-only
|
||||
[see LICENSE file]
|
||||
|
||||
@@ -102,3 +106,22 @@ License: BSL-1.0
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
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
|
||||
|
113
FairMQTest.cmake
113
FairMQTest.cmake
@@ -1,86 +1,65 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
Set(CTEST_SOURCE_DIRECTORY $ENV{SOURCEDIR})
|
||||
Set(CTEST_BINARY_DIRECTORY $ENV{BUILDDIR})
|
||||
Set(CTEST_SITE $ENV{SITE})
|
||||
Set(CTEST_BUILD_NAME $ENV{LABEL})
|
||||
Set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
Set(CTEST_PROJECT_NAME "FairMQ")
|
||||
|
||||
Find_Program(CTEST_GIT_COMMAND NAMES git)
|
||||
Set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
|
||||
cmake_host_system_information(RESULT fqdn QUERY FQDN)
|
||||
|
||||
Set(BUILD_COMMAND "make")
|
||||
Set(CTEST_BUILD_COMMAND "${BUILD_COMMAND} -j$ENV{number_of_processors}")
|
||||
set(CTEST_SOURCE_DIRECTORY .)
|
||||
set(CTEST_BINARY_DIRECTORY build)
|
||||
set(CTEST_CMAKE_GENERATOR "Ninja")
|
||||
set(CTEST_USE_LAUNCHERS ON)
|
||||
set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo")
|
||||
|
||||
String(TOUPPER $ENV{ctest_model} _Model)
|
||||
Set(configure_options "-DCMAKE_BUILD_TYPE=$ENV{ctest_model}")
|
||||
if(NOT NCPUS)
|
||||
if(ENV{SLURM_CPUS_PER_TASK})
|
||||
set(NCPUS $ENV{SLURM_CPUS_PER_TASK})
|
||||
else()
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(NCPUS)
|
||||
if(NCPUS EQUAL 0)
|
||||
set(NCPUS 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
Set(CTEST_USE_LAUNCHERS 1)
|
||||
Set(configure_options "${configure_options};-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}")
|
||||
if ("$ENV{CTEST_SITE}" STREQUAL "")
|
||||
set(CTEST_SITE "${fqdn}")
|
||||
else()
|
||||
set(CTEST_SITE $ENV{CTEST_SITE})
|
||||
endif()
|
||||
|
||||
Set(configure_options "${configure_options};-DDISABLE_COLOR=ON")
|
||||
Set(configure_options "${configure_options};-DCMAKE_PREFIX_PATH=$ENV{SIMPATH}")
|
||||
Set(configure_options "${configure_options};-DBUILD_NANOMSG_TRANSPORT=ON")
|
||||
# Set(configure_options "${configure_options};-DBUILD_OFI_TRANSPORT=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_DDS_PLUGIN=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_SDK=ON")
|
||||
Set(configure_options "${configure_options};-DBUILD_SDK_COMMANDS=ON")
|
||||
Set(configure_options "${configure_options};-DFAST_BUILD=ON")
|
||||
Set(configure_options "${configure_options};-DCOTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES=-j$ENV{number_of_processors}")
|
||||
if ("$ENV{LABEL}" STREQUAL "")
|
||||
set(CTEST_BUILD_NAME "build")
|
||||
else()
|
||||
set(CTEST_BUILD_NAME $ENV{LABEL})
|
||||
endif()
|
||||
|
||||
Set(EXTRA_FLAGS $ENV{EXTRA_FLAGS})
|
||||
If(EXTRA_FLAGS)
|
||||
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
|
||||
EndIf()
|
||||
ctest_start(Continuous)
|
||||
|
||||
If($ENV{ctest_model} MATCHES Profile)
|
||||
Find_Program(GCOV_COMMAND gcov)
|
||||
If(GCOV_COMMAND)
|
||||
Message("Found GCOV: ${GCOV_COMMAND}")
|
||||
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
|
||||
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
|
||||
EndIf(GCOV_COMMAND)
|
||||
EndIf()
|
||||
list(APPEND options
|
||||
"-DDISABLE_COLOR=ON"
|
||||
"-DBUILD_SDK_COMMANDS=ON"
|
||||
"-DBUILD_SDK=ON"
|
||||
"-DBUILD_DDS_PLUGIN=ON")
|
||||
if(RUN_STATIC_ANALYSIS)
|
||||
list(APPEND options "-DRUN_STATIC_ANALYSIS=ON")
|
||||
endif()
|
||||
list(JOIN options ";" optionsstr)
|
||||
ctest_configure(OPTIONS "${optionsstr}")
|
||||
|
||||
If($ENV{ctest_model} MATCHES Nightly OR $ENV{ctest_model} MATCHES Profile)
|
||||
Ctest_Empty_Binary_Directory(${CTEST_BINARY_DIRECTORY})
|
||||
EndIf()
|
||||
ctest_build(FLAGS "-j${NCPUS}")
|
||||
|
||||
Ctest_Start($ENV{ctest_model})
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
PARALLEL_LEVEL 1
|
||||
SCHEDULE_RANDOM ON
|
||||
RETURN_VALUE _ctest_test_ret_val)
|
||||
|
||||
Ctest_Configure(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
OPTIONS "${configure_options}"
|
||||
)
|
||||
ctest_submit()
|
||||
|
||||
Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
|
||||
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
# PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
RETURN_VALUE _ctest_test_ret_val
|
||||
)
|
||||
|
||||
If(GCOV_COMMAND)
|
||||
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS coverage)
|
||||
EndIf()
|
||||
|
||||
If("$ENV{do_codecov_upload}")
|
||||
Execute_Process(COMMAND curl https://codecov.io/bash -o codecov_uploader.sh
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
|
||||
TIMEOUT 60)
|
||||
Execute_Process(COMMAND bash ./codecov_uploader.sh -X gcov
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
|
||||
TIMEOUT 60)
|
||||
EndIf()
|
||||
|
||||
Ctest_Submit()
|
||||
|
||||
if (_ctest_test_ret_val)
|
||||
if(_ctest_test_ret_val)
|
||||
Message(FATAL_ERROR "Some tests failed.")
|
||||
endif()
|
||||
|
104
Jenkinsfile
vendored
104
Jenkinsfile
vendored
@@ -1,60 +1,63 @@
|
||||
#!groovy
|
||||
|
||||
def specToLabel(Map spec) {
|
||||
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
|
||||
}
|
||||
|
||||
def jobMatrix(String prefix, List specs, Closure callback) {
|
||||
def jobMatrix(String type, List specs) {
|
||||
def nodes = [:]
|
||||
for (spec in specs) {
|
||||
def label = specToLabel(spec)
|
||||
def fairsoft = spec.fairsoft
|
||||
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
|
||||
def label = "${type}/${job}"
|
||||
def selector = "${spec.os}-${spec.ver}-${spec.arch}"
|
||||
def os = spec.os
|
||||
def compiler = spec.compiler
|
||||
nodes["${prefix}/${label}"] = {
|
||||
node(label) {
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Building ...', status: 'PENDING')
|
||||
def ver = spec.ver
|
||||
def check = spec.check
|
||||
|
||||
nodes[label] = {
|
||||
node(selector) {
|
||||
githubNotify(context: "${label}", description: 'Building ...', status: 'PENDING')
|
||||
try {
|
||||
deleteDir()
|
||||
checkout scm
|
||||
|
||||
sh """\
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
|
||||
def jobscript = 'job.sh'
|
||||
def ctestcmd = "ctest -S FairMQTest.cmake -V --output-on-failure"
|
||||
sh "echo \"set -e\" >> ${jobscript}"
|
||||
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
|
||||
if (selector =~ /^macos/) {
|
||||
sh """\
|
||||
echo \"export DDS_ROOT=\\\"\\\$(brew --prefix dds)\\\"\" >> ${jobscript}
|
||||
echo \"${ctestcmd}\" >> ${jobscript}
|
||||
"""
|
||||
sh "cat ${jobscript}"
|
||||
sh "bash ${jobscript}"
|
||||
} else {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
|
||||
def containercmd = "singularity exec -B/shared ${env.SINGULARITY_CONTAINER_ROOT}/fairmq/${os}.${ver}.sif bash -l -c \\\"${ctestcmd} -DRUN_STATIC_ANALYSIS=ON\\\""
|
||||
sh """\
|
||||
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
|
||||
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
|
||||
echo \"echo \\\"*** Compute node .........: \\\$(hostname -f)\\\"\" >> ${jobscript}
|
||||
echo \"unset http_proxy\" >> ${jobscript}
|
||||
echo \"unset HTTP_PROXY\" >> ${jobscript}
|
||||
echo \"${containercmd}\" >> ${jobscript}
|
||||
"""
|
||||
sh "cat ${jobscript}"
|
||||
sh "test/ci/slurm-submit.sh \"FairMQ \${JOB_BASE_NAME} ${label}\" ${jobscript}"
|
||||
|
||||
withChecks('Static Analysis') {
|
||||
recordIssues(enabledForFailure: true,
|
||||
tools: [gcc(pattern: 'build/Testing/Temporary/*.log')],
|
||||
filters: [excludeFile('extern/*'), excludeFile('usr/*')],
|
||||
skipBlames: true)
|
||||
}
|
||||
}
|
||||
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
echo "export SOURCEDIR=$PWD" >> Dart.cfg
|
||||
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
|
||||
echo "export GIT_BRANCH=$JOB_BASE_NAME" >> Dart.cfg
|
||||
echo "echo \\\$PATH" >> Dart.cfg
|
||||
'''
|
||||
sh 'cat Dart.cfg'
|
||||
|
||||
callback.call(spec, label)
|
||||
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
|
||||
githubNotify(context: "${label}", description: 'Success', status: 'SUCCESS')
|
||||
} catch (e) {
|
||||
def tarball = "${prefix}_${label}_dds_logs.tar.gz"
|
||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
|
||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test .DDS/"
|
||||
archiveArtifacts tarball
|
||||
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
|
||||
githubNotify(context: "${label}", description: 'Error', status: 'ERROR')
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@@ -66,26 +69,15 @@ def jobMatrix(String prefix, List specs, Closure callback) {
|
||||
pipeline{
|
||||
agent none
|
||||
stages {
|
||||
stage("Run CI Matrix") {
|
||||
stage("CI") {
|
||||
steps{
|
||||
script {
|
||||
def build_jobs = jobMatrix('build', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
sh './Dart.sh alfa_ci Dart.cfg'
|
||||
}
|
||||
def builds = jobMatrix('build', [
|
||||
[os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10'],
|
||||
[os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12'],
|
||||
])
|
||||
|
||||
def profile_jobs = jobMatrix('codecov', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
withCredentials([string(credentialsId: 'fairmq_codecov_token', variable: 'CODECOV_TOKEN')]) {
|
||||
sh './Dart.sh codecov Dart.cfg'
|
||||
}
|
||||
}
|
||||
|
||||
parallel(build_jobs + profile_jobs)
|
||||
parallel(builds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,81 +0,0 @@
|
||||
#!groovy
|
||||
|
||||
def specToLabel(Map spec) {
|
||||
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
|
||||
}
|
||||
|
||||
def buildMatrix(List specs, Closure callback) {
|
||||
def nodes = [:]
|
||||
for (spec in specs) {
|
||||
def label = specToLabel(spec)
|
||||
def fairsoft = spec.fairsoft
|
||||
def os = spec.os
|
||||
def compiler = spec.compiler
|
||||
nodes[label] = {
|
||||
node(label) {
|
||||
try {
|
||||
deleteDir()
|
||||
checkout scm
|
||||
|
||||
sh """\
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
|
||||
} else {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
|
||||
}
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
echo "export SOURCEDIR=$PWD" >> Dart.cfg
|
||||
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
|
||||
echo "export GIT_BRANCH=dev" >> Dart.cfg
|
||||
echo "echo \\\$PATH" >> Dart.cfg
|
||||
'''
|
||||
sh 'cat Dart.cfg'
|
||||
|
||||
callback.call(spec, label)
|
||||
|
||||
deleteDir()
|
||||
} catch (e) {
|
||||
def tarball = "${label}_dds_logs.tar.gz"
|
||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
|
||||
archiveArtifacts tarball
|
||||
|
||||
deleteDir()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
pipeline{
|
||||
agent none
|
||||
triggers { cron('H 2 * * *') }
|
||||
stages {
|
||||
stage("Run Nightly Build/Test Matrix") {
|
||||
steps{
|
||||
script {
|
||||
parallel(buildMatrix([
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
sh './Dart.sh Nightly Dart.cfg'
|
||||
sh './Dart.sh Profile Dart.cfg'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
README.md
12
README.md
@@ -1,5 +1,5 @@
|
||||
<!-- {#mainpage} -->
|
||||
# FairMQ [](COPYRIGHT) [](https://alfa-ci.gsi.de/blue/organizations/jenkins/FairRootGroup%2FFairMQ/branches) [](https://codecov.io/gh/FairRootGroup/FairMQ/branch/master) [](https://scan.coverity.com/projects/fairrootgroup-fairmq) [](https://www.codacy.com/app/dennisklein/FairMQ?utm_source=github.com&utm_medium=referral&utm_content=FairRootGroup/FairMQ&utm_campaign=Badge_Grade)
|
||||
# FairMQ [](COPYRIGHT) [](https://alfa-ci.gsi.de/blue/organizations/jenkins/FairRootGroup%2FFairMQ/branches) [](https://scan.coverity.com/projects/fairrootgroup-fairmq)
|
||||
|
||||
C++ Message Queuing Library and Framework
|
||||
|
||||
@@ -21,7 +21,7 @@ FairMQ is designed to help implementing large-scale data processing workflows ne
|
||||
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
|
||||
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
|
||||
FairMQ provides multiple implementations for its API (so-called "transports",
|
||||
e.g. `zeromq`, `shmem`, `nanomsg`, and `ofi` (in development)) to cover a variety of use cases
|
||||
e.g. `zeromq`, `shmem` and `ofi` (in development)) to cover a variety of use cases
|
||||
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
|
||||
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
|
||||
are communicating through message passing. FairMQ does not only allow the user to use different transport but also to mix them; i.e: A Device can communicate using different transport on different channels at the same time. Device execution is modelled as a simple state machine that
|
||||
@@ -47,7 +47,7 @@ cmake --build fairmq_build --target install
|
||||
|
||||
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
|
||||
|
||||
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `MSGPACK`, `NANOMSG`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
|
||||
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -86,7 +86,7 @@ If your project shares a dependency with FairMQ or if you want to omit a certain
|
||||
Optionally, you can require certain FairMQ package components and a minimum version:
|
||||
|
||||
```cmake
|
||||
find_package(FairMQ 1.1.0 COMPONENTS nanomsg_transport dds_plugin)
|
||||
find_package(FairMQ 1.1.0 COMPONENTS dds_plugin)
|
||||
```
|
||||
|
||||
When building FairMQ, CMake will print a summary table of all available package components.
|
||||
@@ -101,8 +101,6 @@ When building FairMQ, CMake will print a summary table of all available package
|
||||
* [Doxygen](http://www.doxygen.org/)
|
||||
* [FairLogger](https://github.com/FairRootGroup/FairLogger)
|
||||
* [GTest](https://github.com/google/googletest) (optionally bundled)
|
||||
* [Msgpack](https://msgpack.org/index.html)
|
||||
* [nanomsg](http://nanomsg.org/)
|
||||
* [PMIx](https://pmix.org/)
|
||||
* [ZeroMQ](http://zeromq.org/)
|
||||
|
||||
@@ -117,7 +115,6 @@ On command line:
|
||||
* `-DDISABLE_COLOR=ON` disables coloured console output.
|
||||
* `-DBUILD_TESTING=OFF` disables building of tests.
|
||||
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
|
||||
* `-DBUILD_NANOMSG_TRANSPORT=ON` enables building of nanomsg transport.
|
||||
* `-DBUILD_OFI_TRANSPORT=ON` enables building of the experimental OFI transport.
|
||||
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
|
||||
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
|
||||
@@ -182,4 +179,3 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
|
||||
1. [DDS](docs/Plugins.md#731-dds)
|
||||
2. [PMIx](docs/Plugins.md#732-pmix)
|
||||
8. [Controller SDK](docs/SDK.md)
|
||||
|
||||
|
@@ -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 "-Og -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
|
||||
@@ -496,6 +498,8 @@ function(build_bundled package bundle)
|
||||
set(${package}_BUILD_INCLUDE_DIR ${${package}_SOURCE_DIR}/asio/include CACHE PATH "Bundled ${package} build-interface include dir")
|
||||
set(${package}_INSTALL_INCLUDE_DIR ${PROJECT_INSTALL_INCDIR}/bundled CACHE PATH "Bundled ${package} install-interface include dir")
|
||||
set(${package}_ROOT ${${package}_SOURCE_DIR}/asio)
|
||||
elseif(${package} STREQUAL PicoSHA2)
|
||||
set(${package}_ROOT ${${package}_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
string(TOUPPER ${package} package_upper)
|
||||
@@ -522,7 +526,7 @@ macro(fairmq_build_option option description)
|
||||
if(${__requires_condition__})
|
||||
else()
|
||||
if(${option})
|
||||
message(WARNING "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
|
||||
message(FATAL_ERROR "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
@@ -6,28 +6,35 @@
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
|
||||
# The "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix" part in all
|
||||
# the PATH_SUFFIXES is here to be able to find Debian's
|
||||
# libpmix-dev package. It installs everything below
|
||||
# /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix
|
||||
|
||||
|
||||
find_path(PMIx_INCLUDE_DIR
|
||||
NAMES pmix.h
|
||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
||||
PATH_SUFFIXES include
|
||||
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
|
||||
)
|
||||
|
||||
find_path(PMIx_LIBRARY_DIR
|
||||
NAMES libpmix.dylib libpmix.so
|
||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
||||
PATH_SUFFIXES lib lib64
|
||||
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
|
||||
)
|
||||
|
||||
find_library(PMIx_LIBRARY_SHARED
|
||||
NAMES libpmix.dylib libpmix.so
|
||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
||||
PATH_SUFFIXES lib lib64
|
||||
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
|
||||
)
|
||||
|
||||
find_file(PMIx_VERSION_FILE
|
||||
NAMES pmix_version.h
|
||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
||||
PATH_SUFFIXES include
|
||||
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
|
||||
)
|
||||
|
||||
file(READ "${PMIx_VERSION_FILE}" __version_raw)
|
||||
|
21
cmake/FindPicoSHA2.cmake
Normal file
21
cmake/FindPicoSHA2.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
find_path(PicoSHA2_INCLUDE_DIR NAMES picosha2.h)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PicoSHA2
|
||||
REQUIRED_VARS PicoSHA2_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(PicoSHA2_FOUND)
|
||||
add_library(PicoSHA2 INTERFACE IMPORTED)
|
||||
set_target_properties(PicoSHA2 PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PicoSHA2_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -7,10 +7,10 @@
|
||||
################################################################################
|
||||
|
||||
add_library(Example11Lib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(Example11Lib PUBLIC FairMQ)
|
||||
@@ -34,23 +34,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BIN
|
||||
add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
|
||||
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.1-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh nanomsg)
|
||||
set_tests_properties(Example.1-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
|
||||
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-1-1-sampler
|
||||
fairmq-ex-1-1-sink
|
||||
TARGETS
|
||||
fairmq-ex-1-1-sampler
|
||||
fairmq-ex-1-1-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -59,7 +54,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-1-1.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-1-1.sh
|
||||
)
|
||||
|
@@ -17,8 +17,7 @@ Sampler::Sampler()
|
||||
: fText()
|
||||
, fMaxIterations(0)
|
||||
, fNumIterations(0)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
@@ -32,25 +31,22 @@ bool Sampler::ConditionalRun()
|
||||
// create a copy of the data with new(), that will be deleted after the transfer is complete
|
||||
string* text = new string(fText);
|
||||
|
||||
// create message object with a pointer to the data buffer,
|
||||
// its size,
|
||||
// create message object with a pointer to the data buffer, its size,
|
||||
// custom deletion function (called when transfer is done),
|
||||
// and pointer to the object managing the data buffer
|
||||
FairMQMessagePtr msg(NewMessage(const_cast<char*>(text->c_str()),
|
||||
text->length(),
|
||||
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
|
||||
text));
|
||||
FairMQMessagePtr msg(NewMessage(
|
||||
const_cast<char*>(text->c_str()),
|
||||
text->length(),
|
||||
[](void* /*data*/, void* object) { delete static_cast<string*>(object); },
|
||||
text));
|
||||
|
||||
LOG(info) << "Sending \"" << fText << "\"";
|
||||
|
||||
// in case of error or transfer interruption, return false to go to IDLE state
|
||||
// in case of error or transfer interruption, return false to go to the Ready state
|
||||
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
|
||||
if (Send(msg, "data") < 0)
|
||||
{
|
||||
if (Send(msg, "data") < 0) {
|
||||
return false;
|
||||
}
|
||||
else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
|
||||
{
|
||||
} else if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
return false;
|
||||
}
|
||||
@@ -58,8 +54,6 @@ bool Sampler::ConditionalRun()
|
||||
return true;
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
}
|
||||
Sampler::~Sampler() {}
|
||||
|
||||
} // namespace example_1_1
|
||||
|
@@ -33,23 +33,22 @@ void Sink::InitTask()
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a
|
||||
// sub-channel index (here 0)
|
||||
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
|
||||
{
|
||||
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
|
||||
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
|
||||
{
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true if want to be called again (otherwise return false go to IDLE state)
|
||||
// return true if you want the handler to be called again (otherwise return false go to the
|
||||
// Ready state)
|
||||
return true;
|
||||
}
|
||||
|
||||
Sink::~Sink()
|
||||
{
|
||||
}
|
||||
Sink::~Sink() {}
|
||||
|
||||
} // namespace example_1_1
|
||||
|
@@ -7,12 +7,12 @@
|
||||
################################################################################
|
||||
|
||||
add_library(Example1N1Lib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Processor.cxx"
|
||||
"Processor.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Processor.cxx"
|
||||
"Processor.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(Example1N1Lib PUBLIC FairMQ)
|
||||
@@ -42,24 +42,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_B
|
||||
add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
|
||||
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.1-n-1.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh nanomsg)
|
||||
set_tests_properties(Example.1-n-1.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
|
||||
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-1-n-1-sampler
|
||||
fairmq-ex-1-n-1-processor
|
||||
fairmq-ex-1-n-1-sink
|
||||
TARGETS
|
||||
fairmq-ex-1-n-1-sampler
|
||||
fairmq-ex-1-n-1-processor
|
||||
fairmq-ex-1-n-1-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -69,12 +64,12 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-1-n-1.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-1-n-1.sh
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
)
|
||||
|
@@ -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")
|
||||
|
||||
@@ -44,7 +34,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-builtin-devices.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-builtin-devices.sh
|
||||
)
|
||||
|
@@ -7,10 +7,10 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleCopyPushLib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleCopyPushLib PUBLIC FairMQ)
|
||||
@@ -35,23 +35,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURREN
|
||||
add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
|
||||
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.CopyPush.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh nanomsg)
|
||||
set_tests_properties(Example.CopyPush.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
|
||||
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-copypush-sampler
|
||||
fairmq-ex-copypush-sink
|
||||
TARGETS
|
||||
fairmq-ex-copypush-sampler
|
||||
fairmq-ex-copypush-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -60,7 +55,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-copypush.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-copypush.sh
|
||||
)
|
||||
|
@@ -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,13 +28,8 @@ 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)
|
||||
|
||||
if(DDS_VERSION VERSION_LESS 2.5.25)
|
||||
set(WAIT_COMMAND "dds-info --wait-for-idle-agents")
|
||||
else()
|
||||
set(WAIT_COMMAND "dds-info --idle-count --wait")
|
||||
endif()
|
||||
|
||||
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
|
||||
list(JOIN Boost_LIBRARY_DIRS ":" LIB_DIR)
|
||||
set(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_BINARY_DIR}/fairmq/sdk)
|
||||
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml @ONLY)
|
||||
@@ -44,24 +39,24 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CUR
|
||||
|
||||
# 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
|
||||
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
|
||||
@@ -73,30 +68,30 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install @ONLY)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
RENAME ex-dds-topology.xml
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
RENAME ex-dds-topology.xml
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
RENAME ex-dds-topology-infinite.xml
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
RENAME ex-dds-topology-infinite.xml
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-ex-dds-env.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-ex-dds-env.sh
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-dds.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-dds.sh
|
||||
)
|
||||
|
@@ -9,3 +9,8 @@
|
||||
################################################################################
|
||||
|
||||
export PATH=@BIN_DIR@:$PATH
|
||||
|
||||
OS=$(uname -s 2>&1)
|
||||
if [ "$OS" == "Darwin" ]; then
|
||||
export DYLD_LIBRARY_PATH=@LIB_DIR@:$DYLD_LIBRARY_PATH
|
||||
fi
|
||||
|
@@ -30,52 +30,49 @@ echo "SESSION ID: ${DDS_SESSION_ID}"
|
||||
|
||||
trap "cleanup ${DDS_SESSION_ID}" EXIT
|
||||
|
||||
requiredNofAgents=12
|
||||
requiredNofSlots=12
|
||||
if [[ "$plugin" == "ssh" ]]; then
|
||||
dds-submit -r ${plugin} -c @DATA_DIR@/ex-dds-hosts.cfg
|
||||
else
|
||||
dds-submit -r ${plugin} -n ${requiredNofAgents}
|
||||
dds-submit -r ${plugin} --slots ${requiredNofSlots}
|
||||
fi
|
||||
echo "...waiting for ${requiredNofAgents} idle agents..."
|
||||
@WAIT_COMMAND@ ${requiredNofAgents}
|
||||
echo "...waiting for ${requiredNofSlots} idle slots..."
|
||||
dds-info --idle-count --wait ${requiredNofSlots}
|
||||
|
||||
topologyFile=@DATA_DIR@/ex-dds-topology.xml
|
||||
echo "TOPOLOGY FILE: ${topologyFile}"
|
||||
# TODO Uncomment once DDS 2.6 is released
|
||||
# echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${topologyFile})"
|
||||
export FAIRMQ_DDS_TOPO_FILE=@DATA_DIR@/ex-dds-topology.xml
|
||||
echo "TOPOLOGY FILE: ${FAIRMQ_DDS_TOPO_FILE}"
|
||||
echo "TOPOLOGY NAME: $(dds-topology --disable-validation --topology-name ${FAIRMQ_DDS_TOPO_FILE})"
|
||||
|
||||
# TODO Uncomment once DDS 2.6 is released
|
||||
# dds-info --active-topology
|
||||
dds-topology --activate ${topologyFile}
|
||||
# dds-info --active-topology
|
||||
# dds-info --wait-for-executing-agents ${requiredNofAgents}
|
||||
sleep 1
|
||||
dds-info --active-topology
|
||||
dds-topology --activate ${FAIRMQ_DDS_TOPO_FILE}
|
||||
dds-info --active-topology
|
||||
echo "...waiting for ${requiredNofSlots} executing slots..."
|
||||
dds-info --executing-count --wait ${requiredNofSlots}
|
||||
|
||||
echo "------------------------"
|
||||
echo "...waiting for Topology to finish..."
|
||||
# TODO Retrieve number of devices from DDS topology API instead of having the user pass it explicitely
|
||||
fairmq-dds-command-ui -w "IDLE" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c i -w "INITIALIZING DEVICE" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c k -w "INITIALIZED" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c b -w "BOUND" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c x -w "DEVICE READY" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c j -w "READY" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -w "IDLE"
|
||||
fairmq-dds-command-ui -c i
|
||||
fairmq-dds-command-ui -c k
|
||||
fairmq-dds-command-ui -c b
|
||||
fairmq-dds-command-ui -c x
|
||||
fairmq-dds-command-ui -c j
|
||||
fairmq-dds-command-ui -c r
|
||||
sampler_and_sink="main/(Sampler|Sink)"
|
||||
fairmq-dds-command-ui -p $sampler_and_sink -w "RUNNING->READY" -n 2
|
||||
sampler_and_sink="main/(Sampler|Sink).*"
|
||||
fairmq-dds-command-ui -w "RUNNING->READY" -p $sampler_and_sink
|
||||
echo "...$sampler_and_sink are READY, sending shutdown..."
|
||||
fairmq-dds-command-ui -c s -w "RUNNING->READY" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c t -w "DEVICE READY" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c d -w "IDLE" -n ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c q -w "EXITING" -n ${requiredNofAgents}
|
||||
echo "...waiting for ${requiredNofAgents} idle agents..."
|
||||
@WAIT_COMMAND@ ${requiredNofAgents}
|
||||
fairmq-dds-command-ui -c s
|
||||
fairmq-dds-command-ui -c t
|
||||
fairmq-dds-command-ui -c d
|
||||
fairmq-dds-command-ui -c q
|
||||
echo "...waiting for ${requiredNofSlots} idle slots..."
|
||||
dds-info --idle-count --wait ${requiredNofSlots}
|
||||
echo "------------------------"
|
||||
|
||||
# TODO Uncomment once DDS 2.6 is released
|
||||
# dds-info --active-topology
|
||||
dds-info --active-topology
|
||||
dds-topology --stop
|
||||
# dds-info --active-topology
|
||||
dds-info --active-topology
|
||||
|
||||
dds-agent-cmd getlog -a
|
||||
logDir="${wrkDir}/logs"
|
||||
|
@@ -7,10 +7,10 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleMultipartLib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleMultipartLib PUBLIC FairMQ)
|
||||
@@ -34,11 +34,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multipart.sh.in ${CMAKE_CURRE
|
||||
add_test(NAME Example.Multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh zeromq)
|
||||
set_tests_properties(Example.Multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.Multipart.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh nanomsg)
|
||||
set_tests_properties(Example.Multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.Multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh shmem)
|
||||
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
|
||||
@@ -50,12 +45,12 @@ endif()
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-multipart-sampler
|
||||
fairmq-ex-multipart-sink
|
||||
TARGETS
|
||||
fairmq-ex-multipart-sampler
|
||||
fairmq-ex-multipart-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -64,7 +59,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multipart.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multipart.sh
|
||||
)
|
||||
|
@@ -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=$!
|
||||
|
||||
|
@@ -7,12 +7,12 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleMultipleChannelsLib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Broadcaster.cxx"
|
||||
"Broadcaster.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Broadcaster.cxx"
|
||||
"Broadcaster.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleMultipleChannelsLib PUBLIC FairMQ)
|
||||
@@ -39,21 +39,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMA
|
||||
add_test(NAME Example.MultipleChannels.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
|
||||
set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.MultipleChannels.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh nanomsg)
|
||||
set_tests_properties(Example.MultipleChannels.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-multiple-channels-sampler
|
||||
fairmq-ex-multiple-channels-broadcaster
|
||||
fairmq-ex-multiple-channels-sink
|
||||
TARGETS
|
||||
fairmq-ex-multiple-channels-sampler
|
||||
fairmq-ex-multiple-channels-broadcaster
|
||||
fairmq-ex-multiple-channels-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -62,7 +57,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multiple-channels.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multiple-channels.sh
|
||||
)
|
||||
|
@@ -7,12 +7,12 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleMultipleTransportsLib STATIC
|
||||
"Sampler1.cxx"
|
||||
"Sampler1.h"
|
||||
"Sampler2.cxx"
|
||||
"Sampler2.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler1.cxx"
|
||||
"Sampler1.h"
|
||||
"Sampler2.cxx"
|
||||
"Sampler2.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleMultipleTransportsLib PUBLIC FairMQ)
|
||||
@@ -41,13 +41,13 @@ set_tests_properties(Example.MultipleTransports PROPERTIES TIMEOUT "30" RUN_SERI
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-multiple-transports-sampler1
|
||||
fairmq-ex-multiple-transports-sampler2
|
||||
fairmq-ex-multiple-transports-sink
|
||||
TARGETS
|
||||
fairmq-ex-multiple-transports-sampler1
|
||||
fairmq-ex-multiple-transports-sampler2
|
||||
fairmq-ex-multiple-transports-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for install directories
|
||||
@@ -56,7 +56,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multiple-transports.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-multiple-transports.sh
|
||||
)
|
||||
|
@@ -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.
|
||||
|
@@ -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 &
|
||||
|
@@ -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/sdk)
|
||||
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-topology.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-n-m-pair-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-n-m-pair-topology.xml @ONLY)
|
||||
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,34 +5,20 @@
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
* FairMQMerger.h
|
||||
*
|
||||
* @since 2012-12-06
|
||||
* @author D. Klein, A. Rybalchenko
|
||||
*/
|
||||
#ifndef FAIR_MQ_EXAMPLE_N_M_HEADER_H
|
||||
#define FAIR_MQ_EXAMPLE_N_M_HEADER_H
|
||||
|
||||
#ifndef FAIRMQMERGER_H_
|
||||
#define FAIRMQMERGER_H_
|
||||
#include <cstdint>
|
||||
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class FairMQMerger : public FairMQDevice
|
||||
namespace example_n_m
|
||||
{
|
||||
public:
|
||||
FairMQMerger();
|
||||
virtual ~FairMQMerger();
|
||||
|
||||
protected:
|
||||
bool fMultipart;
|
||||
std::string fInChannelName;
|
||||
std::string fOutChannelName;
|
||||
|
||||
virtual void RegisterChannelEndpoints() override;
|
||||
virtual void Run() override;
|
||||
virtual void InitTask() override;
|
||||
struct Header
|
||||
{
|
||||
std::uint16_t id;
|
||||
int senderIndex;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQMERGER_H_ */
|
||||
} // namespace example_n_m
|
||||
|
||||
#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</name>
|
||||
</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</name>
|
||||
<name access="read">fmqchan_data</name>
|
||||
</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</name>
|
||||
</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</name>
|
||||
</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</name>
|
||||
<name access="read">fmqchan_data</name>
|
||||
</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</name>
|
||||
</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/sdk)
|
||||
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-qc-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-qc-topology.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-qc-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-qc-env.sh @ONLY)
|
||||
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(); }
|
@@ -6,29 +6,21 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIRMQMULTIPLIER_H_
|
||||
#define FAIRMQMULTIPLIER_H_
|
||||
|
||||
#include "runFairMQDevice.h"
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class FairMQMultiplier : public FairMQDevice
|
||||
class QCTask : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
FairMQMultiplier();
|
||||
virtual ~FairMQMultiplier();
|
||||
|
||||
protected:
|
||||
bool fMultipart;
|
||||
int fNumOutputs;
|
||||
std::string fInChannelName;
|
||||
std::vector<std::string> fOutChannelNames;
|
||||
|
||||
virtual void InitTask();
|
||||
|
||||
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
|
||||
bool HandleMultipartData(FairMQParts&, int);
|
||||
QCTask()
|
||||
{
|
||||
OnData("qc", [](FairMQMessagePtr& /*msg*/, int) {
|
||||
LOG(info) << "received data";
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FAIRMQMULTIPLIER_H_ */
|
||||
namespace bpo = boost::program_options;
|
||||
void addCustomOptions(bpo::options_description& /*options*/) {}
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new QCTask(); }
|
@@ -5,37 +5,32 @@
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
* FairMQSplitter.h
|
||||
*
|
||||
* @since 2012-12-06
|
||||
* @author D. Klein, A. Rybalchenko
|
||||
*/
|
||||
|
||||
#ifndef FAIRMQSPLITTER_H_
|
||||
#define FAIRMQSPLITTER_H_
|
||||
|
||||
#include "runFairMQDevice.h"
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
#include <string>
|
||||
#include <thread> // this_thread::sleep_for
|
||||
#include <chrono>
|
||||
|
||||
class FairMQSplitter : public FairMQDevice
|
||||
class Sampler : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
FairMQSplitter();
|
||||
virtual ~FairMQSplitter();
|
||||
Sampler() {}
|
||||
|
||||
protected:
|
||||
bool fMultipart;
|
||||
int fNumOutputs;
|
||||
int fDirection;
|
||||
std::string fInChannelName;
|
||||
std::string fOutChannelName;
|
||||
virtual bool ConditionalRun()
|
||||
{
|
||||
FairMQMessagePtr msg(NewMessage(1000));
|
||||
|
||||
virtual void InitTask();
|
||||
if (Send(msg, "data1") < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
|
||||
bool HandleMultipartData(FairMQParts&, int);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FAIRMQSPLITTER_H_ */
|
||||
namespace bpo = boost::program_options;
|
||||
void addCustomOptions(bpo::options_description&) {}
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new Sampler(); }
|
@@ -5,33 +5,21 @@
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
* FairMQProxy.h
|
||||
*
|
||||
* @since 2013-10-02
|
||||
* @author A. Rybalchenko
|
||||
*/
|
||||
|
||||
#ifndef FAIRMQPROXY_H_
|
||||
#define FAIRMQPROXY_H_
|
||||
|
||||
#include "runFairMQDevice.h"
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class FairMQProxy : public FairMQDevice
|
||||
class Sink : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
FairMQProxy();
|
||||
virtual ~FairMQProxy();
|
||||
Sink() { OnData("data2", &Sink::HandleData); }
|
||||
|
||||
protected:
|
||||
bool fMultipart;
|
||||
std::string fInChannelName;
|
||||
std::string fOutChannelName;
|
||||
|
||||
virtual void Run();
|
||||
virtual void InitTask();
|
||||
bool HandleData(FairMQMessagePtr& /*msg*/, int /*index*/) { return true; }
|
||||
};
|
||||
|
||||
#endif /* FAIRMQPROXY_H_ */
|
||||
namespace bpo = boost::program_options;
|
||||
void addCustomOptions(bpo::options_description&) {}
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/) { return new Sink(); }
|
@@ -29,15 +29,15 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-readout-readout
|
||||
fairmq-ex-readout-builder
|
||||
fairmq-ex-readout-processor
|
||||
fairmq-ex-readout-sender
|
||||
fairmq-ex-readout-receiver
|
||||
TARGETS
|
||||
fairmq-ex-readout-readout
|
||||
fairmq-ex-readout-builder
|
||||
fairmq-ex-readout-processor
|
||||
fairmq-ex-readout-sender
|
||||
fairmq-ex-readout-receiver
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -47,13 +47,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout.sh.in ${CMAKE
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-readout.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-readout.sh
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-readout-processing.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-readout-processing.sh
|
||||
)
|
||||
|
@@ -37,10 +37,10 @@ class Readout : public FairMQDevice
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("rb",
|
||||
0,
|
||||
10000000,
|
||||
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
|
||||
--fNumUnackedMsgs;
|
||||
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
|
||||
fNumUnackedMsgs -= blocks.size();
|
||||
if (fMaxIterations > 0) {
|
||||
LOG(debug) << "Received ack";
|
||||
LOG(debug) << "Received " << blocks.size() << " acks";
|
||||
}
|
||||
}
|
||||
));
|
||||
|
@@ -7,10 +7,10 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleRegionLib STATIC
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
"Sampler.cxx"
|
||||
"Sampler.h"
|
||||
"Sink.cxx"
|
||||
"Sink.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleRegionLib PUBLIC FairMQ)
|
||||
@@ -32,25 +32,20 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh)
|
||||
|
||||
add_test(NAME Example.Region.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh zeromq)
|
||||
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.Region.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh nanomsg)
|
||||
set_tests_properties(Example.Region.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
endif()
|
||||
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
|
||||
|
||||
add_test(NAME Example.Region.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh shmem)
|
||||
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-region-sampler
|
||||
fairmq-ex-region-sink
|
||||
TARGETS
|
||||
fairmq-ex-region-sampler
|
||||
fairmq-ex-region-sink
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -59,7 +54,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-region.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-region.sh
|
||||
)
|
||||
|
@@ -23,28 +23,41 @@ namespace example_region
|
||||
|
||||
Sampler::Sampler()
|
||||
: fMsgSize(10000)
|
||||
, fLinger(100)
|
||||
, fMaxIterations(0)
|
||||
, fNumIterations(0)
|
||||
, fRegion(nullptr)
|
||||
, fNumUnackedMsgs(0)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
||||
fLinger = fConfig->GetProperty<uint32_t>("region-linger");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
|
||||
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
||||
LOG(info) << "Region event: " << info.event
|
||||
<< ", managed: " << info.managed
|
||||
<< ", id: " << info.id
|
||||
<< ", ptr: " << info.ptr
|
||||
<< ", size: " << info.size
|
||||
<< ", flags: " << info.flags;
|
||||
});
|
||||
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data",
|
||||
0,
|
||||
10000000,
|
||||
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
|
||||
--fNumUnackedMsgs;
|
||||
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fNumUnackedMsgs -= blocks.size();
|
||||
|
||||
if (fMaxIterations > 0) {
|
||||
LOG(debug) << "Received ack";
|
||||
LOG(info) << "Received " << blocks.size() << " acks";
|
||||
}
|
||||
}
|
||||
));
|
||||
fRegion->SetLinger(fLinger);
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
@@ -61,27 +74,31 @@ bool Sampler::ConditionalRun()
|
||||
// LOG(info) << "check: " << static_cast<char*>(fRegion->GetData())[3];
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
if (Send(msg, "data", 0) > 0) {
|
||||
++fNumUnackedMsgs;
|
||||
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++fNumUnackedMsgs;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sampler::ResetTask()
|
||||
{
|
||||
// if not all messages acknowledged, wait for a bit. But only once, since receiver could be already dead.
|
||||
if (fNumUnackedMsgs != 0) {
|
||||
LOG(debug) << "waiting for all acknowledgements... (" << fNumUnackedMsgs << ")";
|
||||
this_thread::sleep_for(chrono::milliseconds(500));
|
||||
LOG(debug) << "done, still unacked: " << fNumUnackedMsgs;
|
||||
}
|
||||
// On destruction UnmanagedRegion will try to TODO
|
||||
fRegion.reset();
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
if (fNumUnackedMsgs != 0) {
|
||||
LOG(info) << "Done, still not acknowledged: " << fNumUnackedMsgs;
|
||||
} else {
|
||||
LOG(info) << "All acknowledgements received.";
|
||||
}
|
||||
}
|
||||
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents();
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
|
@@ -15,7 +15,8 @@
|
||||
#ifndef FAIRMQEXAMPLEREGIONSAMPLER_H
|
||||
#define FAIRMQEXAMPLEREGIONSAMPLER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <cstdint>
|
||||
|
||||
#include "FairMQDevice.h"
|
||||
|
||||
@@ -35,10 +36,12 @@ class Sampler : public FairMQDevice
|
||||
|
||||
private:
|
||||
int fMsgSize;
|
||||
uint32_t fLinger;
|
||||
uint64_t fMaxIterations;
|
||||
uint64_t fNumIterations;
|
||||
FairMQUnmanagedRegionPtr fRegion;
|
||||
std::atomic<uint64_t> fNumUnackedMsgs;
|
||||
std::mutex fMtx;
|
||||
uint64_t fNumUnackedMsgs;
|
||||
};
|
||||
|
||||
} // namespace example_region
|
||||
|
@@ -29,6 +29,14 @@ void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
||||
LOG(info) << "Region event: " << info.event
|
||||
<< ", managed: " << info.managed
|
||||
<< ", id: " << info.id
|
||||
<< ", ptr: " << info.ptr
|
||||
<< ", size: " << info.size
|
||||
<< ", flags: " << info.flags;
|
||||
});
|
||||
}
|
||||
|
||||
void Sink::Run()
|
||||
@@ -50,6 +58,11 @@ void Sink::Run()
|
||||
}
|
||||
}
|
||||
|
||||
void Sink::ResetTask()
|
||||
{
|
||||
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents();
|
||||
}
|
||||
|
||||
Sink::~Sink()
|
||||
{
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ class Sink : public FairMQDevice
|
||||
protected:
|
||||
virtual void Run();
|
||||
virtual void InitTask();
|
||||
virtual void ResetTask();
|
||||
|
||||
private:
|
||||
uint64_t fMaxIterations;
|
||||
|
@@ -15,6 +15,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()
|
||||
("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
|
||||
("region-linger", bpo::value<uint32_t>()->default_value(100), "Linger period for regions")
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
|
@@ -19,9 +19,11 @@ SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --severity debug"
|
||||
SAMPLER+=" --session $SESSION"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --control static --color false"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
SAMPLER+=" --msg-size $msgSize"
|
||||
SAMPLER+=" --region-linger 500"
|
||||
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
|
||||
SAMPLER_PID=$!
|
||||
|
@@ -7,10 +7,10 @@
|
||||
################################################################################
|
||||
|
||||
add_library(ExampleReqRepLib STATIC
|
||||
"Client.cxx"
|
||||
"Client.h"
|
||||
"Server.cxx"
|
||||
"Server.h"
|
||||
"Client.cxx"
|
||||
"Client.h"
|
||||
"Server.cxx"
|
||||
"Server.h"
|
||||
)
|
||||
|
||||
target_link_libraries(ExampleReqRepLib PUBLIC FairMQ)
|
||||
@@ -35,23 +35,18 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-req-rep.sh.in ${CMAKE_CURRENT
|
||||
add_test(NAME Example.ReqRep.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh zeromq)
|
||||
set_tests_properties(Example.ReqRep.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.ReqRep.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh nanomsg)
|
||||
set_tests_properties(Example.ReqRep.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.ReqRep.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh shmem)
|
||||
set_tests_properties(Example.ReqRep.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
fairmq-ex-req-rep-client
|
||||
fairmq-ex-req-rep-server
|
||||
TARGETS
|
||||
fairmq-ex-req-rep-client
|
||||
fairmq-ex-req-rep-server
|
||||
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
@@ -60,7 +55,7 @@ set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-req-rep.sh
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-req-rep.sh
|
||||
)
|
||||
|
1
extern/PicoSHA2
vendored
Submodule
1
extern/PicoSHA2
vendored
Submodule
Submodule extern/PicoSHA2 added at 599843c396
2
extern/asio
vendored
2
extern/asio
vendored
Submodule extern/asio updated: 90f32660cd...be7badc31a
@@ -1,21 +1,11 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2012-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
####################
|
||||
# external plugins #
|
||||
####################
|
||||
if(BUILD_DDS_PLUGIN)
|
||||
add_subdirectory(plugins/DDS)
|
||||
endif()
|
||||
if(BUILD_PMIX_PLUGIN)
|
||||
add_subdirectory(plugins/PMIx)
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
###########
|
||||
# Version #
|
||||
@@ -58,6 +48,12 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
${TOOLS_PUBLIC_HEADER_FILES}
|
||||
)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
# workaround https://github.com/boostorg/asio/commit/43874d5497414c67655d901e48c939ef01337edb
|
||||
if( Boost_VERSION VERSION_LESS 1.69
|
||||
AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang
|
||||
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0.1)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
endif()
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
@@ -66,6 +62,7 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
FairLogger::FairLogger
|
||||
Threads::Threads
|
||||
PUBLIC
|
||||
Boost::boost
|
||||
)
|
||||
@@ -149,6 +146,7 @@ if(BUILD_FAIRMQ)
|
||||
# libFairMQ header files #
|
||||
##########################
|
||||
set(FAIRMQ_PUBLIC_HEADER_FILES
|
||||
Device.h
|
||||
DeviceRunner.h
|
||||
EventManager.h
|
||||
FairMQChannel.h
|
||||
@@ -173,44 +171,37 @@ if(BUILD_FAIRMQ)
|
||||
Plugin.h
|
||||
PluginManager.h
|
||||
PluginServices.h
|
||||
runDevice.h
|
||||
runFairMQDevice.h
|
||||
shmem/Monitor.h
|
||||
)
|
||||
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||
devices/FairMQBenchmarkSampler.h
|
||||
devices/FairMQMerger.h
|
||||
devices/FairMQMultiplier.h
|
||||
devices/FairMQProxy.h
|
||||
devices/FairMQSink.h
|
||||
devices/FairMQSplitter.h
|
||||
devices/BenchmarkSampler.h
|
||||
devices/Merger.h
|
||||
devices/Multiplier.h
|
||||
devices/Proxy.h
|
||||
devices/Sink.h
|
||||
devices/Splitter.h
|
||||
plugins/Builtin.h
|
||||
plugins/config/Config.h
|
||||
plugins/Control.h
|
||||
shmem/FairMQMessageSHM.h
|
||||
shmem/FairMQPollerSHM.h
|
||||
shmem/FairMQUnmanagedRegionSHM.h
|
||||
shmem/FairMQSocketSHM.h
|
||||
shmem/FairMQTransportFactorySHM.h
|
||||
plugins/control/Control.h
|
||||
shmem/Message.h
|
||||
shmem/Poller.h
|
||||
shmem/UnmanagedRegion.h
|
||||
shmem/Socket.h
|
||||
shmem/TransportFactory.h
|
||||
shmem/Common.h
|
||||
shmem/Manager.h
|
||||
shmem/Region.h
|
||||
zeromq/FairMQMessageZMQ.h
|
||||
zeromq/FairMQPollerZMQ.h
|
||||
zeromq/FairMQUnmanagedRegionZMQ.h
|
||||
zeromq/FairMQSocketZMQ.h
|
||||
zeromq/FairMQTransportFactoryZMQ.h
|
||||
zeromq/Context.h
|
||||
zeromq/Message.h
|
||||
zeromq/Poller.h
|
||||
zeromq/UnmanagedRegion.h
|
||||
zeromq/Socket.h
|
||||
zeromq/TransportFactory.h
|
||||
)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
nanomsg/FairMQMessageNN.h
|
||||
nanomsg/FairMQPollerNN.h
|
||||
nanomsg/FairMQUnmanagedRegionNN.h
|
||||
nanomsg/FairMQSocketNN.h
|
||||
nanomsg/FairMQTransportFactoryNN.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
ofi/Context.h
|
||||
@@ -233,11 +224,6 @@ if(BUILD_FAIRMQ)
|
||||
FairMQPoller.cxx
|
||||
FairMQSocket.cxx
|
||||
FairMQTransportFactory.cxx
|
||||
devices/FairMQBenchmarkSampler.cxx
|
||||
devices/FairMQMerger.cxx
|
||||
devices/FairMQMultiplier.cxx
|
||||
devices/FairMQProxy.cxx
|
||||
devices/FairMQSplitter.cxx
|
||||
Plugin.cxx
|
||||
PluginManager.cxx
|
||||
PluginServices.cxx
|
||||
@@ -246,32 +232,11 @@ if(BUILD_FAIRMQ)
|
||||
Properties.cxx
|
||||
SuboptParser.cxx
|
||||
plugins/config/Config.cxx
|
||||
plugins/Control.cxx
|
||||
shmem/FairMQMessageSHM.cxx
|
||||
shmem/FairMQPollerSHM.cxx
|
||||
shmem/FairMQUnmanagedRegionSHM.cxx
|
||||
shmem/FairMQSocketSHM.cxx
|
||||
shmem/FairMQTransportFactorySHM.cxx
|
||||
shmem/Manager.cxx
|
||||
shmem/Region.cxx
|
||||
zeromq/FairMQMessageZMQ.cxx
|
||||
zeromq/FairMQPollerZMQ.cxx
|
||||
zeromq/FairMQUnmanagedRegionZMQ.cxx
|
||||
zeromq/FairMQSocketZMQ.cxx
|
||||
zeromq/FairMQTransportFactoryZMQ.cxx
|
||||
plugins/control/Control.cxx
|
||||
MemoryResources.cxx
|
||||
shmem/Monitor.cxx
|
||||
)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
|
||||
nanomsg/FairMQMessageNN.cxx
|
||||
nanomsg/FairMQPollerNN.cxx
|
||||
nanomsg/FairMQUnmanagedRegionNN.cxx
|
||||
nanomsg/FairMQSocketNN.cxx
|
||||
nanomsg/FairMQTransportFactoryNN.cxx
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
|
||||
ofi/Context.cxx
|
||||
@@ -287,7 +252,7 @@ if(BUILD_FAIRMQ)
|
||||
# configure files #
|
||||
###################
|
||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run/startMQBenchmark.sh.in ${CMAKE_CURRENT_BINARY_DIR}/startMQBenchmark.sh)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/devices/startMQBenchmark.sh.in ${CMAKE_CURRENT_BINARY_DIR}/startMQBenchmark.sh)
|
||||
|
||||
#################################
|
||||
# define libFairMQ build target #
|
||||
@@ -312,8 +277,8 @@ if(BUILD_FAIRMQ)
|
||||
# preprocessor definitions #
|
||||
############################
|
||||
target_compile_definitions(${_target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
target_compile_definitions(${_target} PRIVATE BUILD_NANOMSG_TRANSPORT)
|
||||
if(FAIRMQ_DEBUG_MODE)
|
||||
target_compile_definitions(${_target} PUBLIC FAIRMQ_DEBUG_MODE)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
target_compile_definitions(${_target} PRIVATE BUILD_OFI_TRANSPORT)
|
||||
@@ -335,16 +300,13 @@ if(BUILD_FAIRMQ)
|
||||
##################
|
||||
# link libraries #
|
||||
##################
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(NANOMSG_DEPS nanomsg msgpackc-cxx)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(OFI_DEPS
|
||||
asiofi::asiofi
|
||||
Boost::container
|
||||
)
|
||||
endif()
|
||||
set(optional_deps ${NANOMSG_DEPS} ${OFI_DEPS})
|
||||
set(optional_deps ${OFI_DEPS})
|
||||
if(optional_deps)
|
||||
list(REMOVE_DUPLICATES optional_deps)
|
||||
endif()
|
||||
@@ -367,7 +329,7 @@ if(BUILD_FAIRMQ)
|
||||
|
||||
PRIVATE # only libFairMQ links against private dependencies
|
||||
libzmq
|
||||
${NANOMSG_DEPS}
|
||||
PicoSHA2
|
||||
${OFI_DEPS}
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES
|
||||
@@ -394,39 +356,47 @@ if(BUILD_FAIRMQ)
|
||||
###############
|
||||
# executables #
|
||||
###############
|
||||
add_executable(fairmq-bsampler run/runBenchmarkSampler.cxx)
|
||||
add_executable(fairmq-bsampler devices/runBenchmarkSampler.cxx)
|
||||
target_link_libraries(fairmq-bsampler FairMQ)
|
||||
|
||||
add_executable(fairmq-merger run/runMerger.cxx)
|
||||
add_executable(fairmq-merger devices/runMerger.cxx)
|
||||
target_link_libraries(fairmq-merger FairMQ)
|
||||
|
||||
add_executable(fairmq-multiplier run/runMultiplier.cxx)
|
||||
add_executable(fairmq-multiplier devices/runMultiplier.cxx)
|
||||
target_link_libraries(fairmq-multiplier FairMQ)
|
||||
|
||||
add_executable(fairmq-proxy run/runProxy.cxx)
|
||||
add_executable(fairmq-proxy devices/runProxy.cxx)
|
||||
target_link_libraries(fairmq-proxy FairMQ)
|
||||
|
||||
add_executable(fairmq-sink run/runSink.cxx)
|
||||
add_executable(fairmq-sink devices/runSink.cxx)
|
||||
target_link_libraries(fairmq-sink FairMQ)
|
||||
|
||||
add_executable(fairmq-splitter run/runSplitter.cxx)
|
||||
add_executable(fairmq-splitter devices/runSplitter.cxx)
|
||||
target_link_libraries(fairmq-splitter FairMQ)
|
||||
|
||||
add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx)
|
||||
target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
if(FAIRMQ_DEBUG_MODE)
|
||||
target_compile_definitions(fairmq-shmmonitor PUBLIC FAIRMQ_DEBUG_MODE)
|
||||
endif()
|
||||
target_link_libraries(fairmq-shmmonitor PUBLIC
|
||||
Threads::Threads
|
||||
$<$<PLATFORM_ID:Linux>:rt>
|
||||
Boost::boost
|
||||
Boost::date_time
|
||||
Boost::program_options
|
||||
FairLogger::FairLogger
|
||||
PicoSHA2
|
||||
)
|
||||
target_include_directories(fairmq-shmmonitor PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
add_executable(fairmq-uuid-gen run/runUuidGenerator.cxx)
|
||||
target_link_libraries(fairmq-uuid-gen FairMQ)
|
||||
add_executable(fairmq-uuid-gen tools/runUuidGenerator.cxx)
|
||||
target_link_libraries(fairmq-uuid-gen PUBLIC
|
||||
Boost::program_options
|
||||
Tools
|
||||
)
|
||||
|
||||
|
||||
###########
|
||||
@@ -467,3 +437,13 @@ endif()
|
||||
if(BUILD_SDK)
|
||||
add_subdirectory(sdk)
|
||||
endif()
|
||||
|
||||
####################
|
||||
# external plugins #
|
||||
####################
|
||||
if(BUILD_DDS_PLUGIN)
|
||||
add_subdirectory(plugins/DDS)
|
||||
endif()
|
||||
if(BUILD_PMIX_PLUGIN)
|
||||
add_subdirectory(plugins/PMIx)
|
||||
endif()
|
||||
|
21
fairmq/Device.h
Normal file
21
fairmq/Device.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_MQ_DEVICE_H
|
||||
#define FAIR_MQ_DEVICE_H
|
||||
|
||||
#include <FairMQDevice.h>
|
||||
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using Device = ::FairMQDevice;
|
||||
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_DEVICE_H */
|
@@ -1,5 +1,5 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
@@ -8,10 +8,14 @@
|
||||
|
||||
#include "DeviceRunner.h"
|
||||
|
||||
#include <exception>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
#include <fairmq/tools/Version.h>
|
||||
#include <fairmq/Version.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
@@ -52,7 +56,13 @@ bool DeviceRunner::HandleGeneralOptions(const fair::mq::ProgOptions& config, boo
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
} else {
|
||||
fair::Logger::SetConsoleColor(color);
|
||||
fair::Logger::SetConsoleSeverity(severity);
|
||||
auto envFairMQSeverity = getenv("FAIRMQ_SEVERITY");
|
||||
if (envFairMQSeverity) {
|
||||
severity = envFairMQSeverity;
|
||||
}
|
||||
if (severity != "") {
|
||||
fair::Logger::SetConsoleSeverity(severity);
|
||||
}
|
||||
}
|
||||
|
||||
if (printLogo) {
|
||||
@@ -75,7 +85,7 @@ void DeviceRunner::SubscribeForConfigChange()
|
||||
fair::Logger::SetConsoleColor(val);
|
||||
}
|
||||
});
|
||||
fConfig.Subscribe<string>("device-runner", [&](const std::string& key, const std::string val) {
|
||||
fConfig.Subscribe<string>("device-runner", [&](const std::string& key, const std::string& val) {
|
||||
if (key == "severity") {
|
||||
fair::Logger::SetConsoleSeverity(val);
|
||||
} else if (key == "file-severity") {
|
||||
@@ -150,8 +160,8 @@ auto DeviceRunner::Run() -> int
|
||||
|
||||
// Handle --version
|
||||
if (fConfig.Count("version")) {
|
||||
cout << "FairMQ version: " << FAIRMQ_GIT_VERSION << endl;
|
||||
cout << "User device version: " << fDevice->GetVersion() << endl;
|
||||
LOGV(info, verylow) << "FairMQ version: " << FAIRMQ_GIT_VERSION;
|
||||
LOGV(info, verylow) << "User device version: " << fDevice->GetVersion();
|
||||
fDevice->ChangeState(fair::mq::Transition::End);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
@@ -9,19 +9,18 @@
|
||||
#ifndef FAIR_MQ_DEVICERUNNER_H
|
||||
#define FAIR_MQ_DEVICERUNNER_H
|
||||
|
||||
#include <fairmq/Device.h>
|
||||
#include <fairmq/EventManager.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <fairmq/ProgOptions.h>
|
||||
#include <FairMQDevice.h>
|
||||
#include <FairMQLogger.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fair {
|
||||
namespace mq {
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
/**
|
||||
* @class DeviceRunner DeviceRunner.h <fairmq/DeviceRunner.h>
|
||||
@@ -74,7 +73,7 @@ class DeviceRunner
|
||||
|
||||
std::vector<std::string> fRawCmdLineArgs;
|
||||
fair::mq::ProgOptions fConfig;
|
||||
std::unique_ptr<FairMQDevice> fDevice;
|
||||
std::unique_ptr<Device> fDevice;
|
||||
PluginManager fPluginManager;
|
||||
const bool fPrintLogo;
|
||||
|
||||
@@ -89,7 +88,6 @@ struct ModifyRawCmdLineArgs : Event<DeviceRunner&> {};
|
||||
struct InstantiateDevice : Event<DeviceRunner&> {};
|
||||
} /* namespace hooks */
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_DEVICERUNNER_H */
|
||||
|
@@ -21,9 +21,7 @@
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
// Inherit from this base event type to create custom event types
|
||||
@@ -137,7 +135,6 @@ class EventManager
|
||||
}
|
||||
}; /* class EventManager */
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_EVENTMANAGER_H */
|
||||
|
@@ -7,11 +7,15 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
#include <fairmq/tools/Strings.h>
|
||||
#include <fairmq/Properties.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp> // join/split
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <random>
|
||||
@@ -20,7 +24,7 @@ using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
template<typename T>
|
||||
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound) noexcept
|
||||
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound)
|
||||
{
|
||||
if (m.count(k)) {
|
||||
return boost::any_cast<T>(m.at(k));
|
||||
@@ -77,31 +81,30 @@ FairMQChannel::FairMQChannel(const string& name, const string& type, const strin
|
||||
, fPortRangeMin(DefaultPortRangeMin)
|
||||
, fPortRangeMax(DefaultPortRangeMax)
|
||||
, fAutoBind(DefaultAutoBind)
|
||||
, fIsValid(false)
|
||||
, fValid(false)
|
||||
, fMultipart(false)
|
||||
, fModified(true)
|
||||
, fReset(false)
|
||||
, fMtx()
|
||||
{}
|
||||
{
|
||||
// LOG(warn) << "Constructing channel '" << fName << "'";
|
||||
}
|
||||
|
||||
FairMQChannel::FairMQChannel(const string& name, int index, const fair::mq::Properties& properties)
|
||||
: FairMQChannel(tools::ToString(name, "[", index, "]"), "unspecified", "unspecified", "unspecified", nullptr)
|
||||
{
|
||||
string prefix(tools::ToString("chans.", name, ".", index, "."));
|
||||
|
||||
fType = GetPropertyOrDefault(properties, string(prefix + "type"), fType);
|
||||
fMethod = GetPropertyOrDefault(properties, string(prefix + "method"), fMethod);
|
||||
fAddress = GetPropertyOrDefault(properties, string(prefix + "address"), fAddress);
|
||||
fTransportType = TransportTypes.at(GetPropertyOrDefault(properties, string(prefix + "transport"), TransportNames.at(fTransportType)));
|
||||
fSndBufSize = GetPropertyOrDefault(properties, string(prefix + "sndBufSize"), fSndBufSize);
|
||||
fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), fRcvBufSize);
|
||||
fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), fSndKernelSize);
|
||||
fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), fRcvKernelSize);
|
||||
fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), fLinger);
|
||||
fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), fRateLogging);
|
||||
fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), fPortRangeMin);
|
||||
fPortRangeMax = GetPropertyOrDefault(properties, string(prefix + "portRangeMax"), fPortRangeMax);
|
||||
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), fAutoBind);
|
||||
fType = GetPropertyOrDefault(properties, string(prefix + "type"), std::string(DefaultType));
|
||||
fMethod = GetPropertyOrDefault(properties, string(prefix + "method"), std::string(DefaultMethod));
|
||||
fAddress = GetPropertyOrDefault(properties, string(prefix + "address"), std::string(DefaultAddress));
|
||||
fTransportType = TransportType(GetPropertyOrDefault(properties, string(prefix + "transport"), std::string(DefaultTransportName)));
|
||||
fSndBufSize = GetPropertyOrDefault(properties, string(prefix + "sndBufSize"), DefaultSndBufSize);
|
||||
fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), DefaultRcvBufSize);
|
||||
fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), DefaultSndKernelSize);
|
||||
fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), DefaultRcvKernelSize);
|
||||
fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), DefaultLinger);
|
||||
fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), DefaultRateLogging);
|
||||
fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), DefaultPortRangeMin);
|
||||
fPortRangeMax = GetPropertyOrDefault(properties, string(prefix + "portRangeMax"), DefaultPortRangeMax);
|
||||
fAutoBind = GetPropertyOrDefault(properties, string(prefix + "autoBind"), DefaultAutoBind);
|
||||
}
|
||||
|
||||
FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
||||
@@ -125,14 +128,16 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan, const string& newName)
|
||||
, fPortRangeMin(chan.fPortRangeMin)
|
||||
, fPortRangeMax(chan.fPortRangeMax)
|
||||
, fAutoBind(chan.fAutoBind)
|
||||
, fIsValid(false)
|
||||
, fValid(false)
|
||||
, fMultipart(chan.fMultipart)
|
||||
, fModified(chan.fModified)
|
||||
, fReset(false)
|
||||
{}
|
||||
|
||||
FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
{
|
||||
if (this == &chan) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
fTransportFactory = nullptr;
|
||||
fTransportType = chan.fTransportType;
|
||||
fSocket = nullptr;
|
||||
@@ -149,349 +154,18 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
fPortRangeMin = chan.fPortRangeMin;
|
||||
fPortRangeMax = chan.fPortRangeMax;
|
||||
fAutoBind = chan.fAutoBind;
|
||||
fIsValid = false;
|
||||
fValid = false;
|
||||
fMultipart = chan.fMultipart;
|
||||
fModified = chan.fModified;
|
||||
fReset = false;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FairMQSocket & FairMQChannel::GetSocket() const
|
||||
{
|
||||
assert(fSocket);
|
||||
return *fSocket;
|
||||
}
|
||||
|
||||
string FairMQChannel::GetName() const
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fName;
|
||||
}
|
||||
|
||||
string FairMQChannel::GetPrefix() const
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
string prefix = fName;
|
||||
prefix = prefix.erase(fName.rfind('['));
|
||||
return prefix;
|
||||
}
|
||||
|
||||
string FairMQChannel::GetIndex() const
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
string indexStr = fName;
|
||||
indexStr.erase(indexStr.rfind(']'));
|
||||
indexStr.erase(0, indexStr.rfind('[') + 1);
|
||||
return indexStr;
|
||||
}
|
||||
|
||||
string FairMQChannel::GetType() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fType;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetType: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetMethod() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fMethod;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetMethod: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetAddress() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fAddress;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetAddress: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetTransportName() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return TransportNames.at(fTransportType);
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetTransportName: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
Transport FairMQChannel::GetTransportType() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fTransportType;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetTransportType: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
|
||||
int FairMQChannel::GetSndBufSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fSndBufSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetSndBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRcvBufSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRcvBufSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRcvBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetSndKernelSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fSndKernelSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetSndKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRcvKernelSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRcvKernelSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRcvKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetLinger() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fLinger;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetLinger: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRateLogging() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRateLogging;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRateLogging: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetPortRangeMin() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fPortRangeMin;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMin: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetPortRangeMax() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fPortRangeMax;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMax: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::GetAutoBind() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fAutoBind;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetAutoBind: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateType(const string& type)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fType = type;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateType: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateMethod(const string& method)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fMethod = method;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateMethod: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateAddress(const string& address)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fAddress = address;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateAddress: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateTransport(const string& transport)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fTransportType = TransportTypes.at(transport);
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateTransport: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateSndBufSize(const int sndBufSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fSndBufSize = sndBufSize;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateSndBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRcvBufSize(const int rcvBufSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fRcvBufSize = rcvBufSize;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateRcvBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateSndKernelSize(const int sndKernelSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fSndKernelSize = sndKernelSize;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateSndKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRcvKernelSize(const int rcvKernelSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fRcvKernelSize = rcvKernelSize;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateRcvKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateLinger(const int duration)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fLinger = duration;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateLinger: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRateLogging(const int rateLogging)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fRateLogging = rateLogging;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateRateLogging: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdatePortRangeMin(const int minPort)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fPortRangeMin = minPort;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdatePortRangeMin: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdatePortRangeMax(const int maxPort)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fPortRangeMax = maxPort;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdatePortRangeMax: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateAutoBind(const bool autobind)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fAutoBind = autobind;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateAutoBind: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
auto FairMQChannel::SetModified(const bool modified) -> void
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fModified = modified;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::SetModified: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateName(const string& name)
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fName = name;
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateName: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::IsValid() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fIsValid;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::IsValid: " << e.what();
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::Validate()
|
||||
try {
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
stringstream ss;
|
||||
ss << "Validating channel '" << fName << "'... ";
|
||||
|
||||
if (fIsValid) {
|
||||
if (fValid) {
|
||||
ss << "ALREADY VALID";
|
||||
LOG(debug) << ss.str();
|
||||
return true;
|
||||
@@ -524,7 +198,7 @@ try {
|
||||
} else {
|
||||
vector<string> endpoints;
|
||||
boost::algorithm::split(endpoints, fAddress, boost::algorithm::is_any_of(";"));
|
||||
for (const auto endpoint : endpoints) {
|
||||
for (const auto& endpoint : endpoints) {
|
||||
string address;
|
||||
if (endpoint[0] == '@' || endpoint[0] == '+' || endpoint[0] == '>') {
|
||||
address = endpoint.substr(1);
|
||||
@@ -626,7 +300,7 @@ try {
|
||||
throw ChannelConfigurationError(tools::ToString("invalid socket rate logging interval (cannot be negative): '", fRateLogging, "'"));
|
||||
}
|
||||
|
||||
fIsValid = true;
|
||||
fValid = true;
|
||||
ss << "VALID";
|
||||
LOG(debug) << ss.str();
|
||||
return true;
|
||||
@@ -637,8 +311,6 @@ try {
|
||||
|
||||
void FairMQChannel::Init()
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
|
||||
fSocket = fTransportFactory->CreateSocket(fType, fName);
|
||||
|
||||
// set linger duration (how long socket should wait for outstanding transfers before shutdown)
|
||||
@@ -659,19 +331,22 @@ void FairMQChannel::Init()
|
||||
|
||||
bool FairMQChannel::ConnectEndpoint(const string& endpoint)
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
|
||||
return fSocket->Connect(endpoint);
|
||||
}
|
||||
|
||||
bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
|
||||
// try to bind to the configured port. If it fails, try random one (if AutoBind is on).
|
||||
if (fSocket->Bind(endpoint)) {
|
||||
return true;
|
||||
} else {
|
||||
// auto-bind only implemented for TCP
|
||||
size_t protocolPos = endpoint.find(':');
|
||||
string protocol = endpoint.substr(0, protocolPos);
|
||||
if (protocol != "tcp") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fAutoBind) {
|
||||
// number of attempts when choosing a random port
|
||||
int numAttempts = 0;
|
||||
@@ -701,10 +376,3 @@ bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FairMQChannel::ResetChannel()
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
// TODO: implement channel resetting
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <FairMQUnmanagedRegion.h>
|
||||
#include <FairMQSocket.h>
|
||||
#include <fairmq/Transports.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <FairMQParts.h>
|
||||
#include <fairmq/Properties.h>
|
||||
#include <FairMQMessage.h>
|
||||
@@ -24,9 +23,14 @@
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <utility> // std::move
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // int64_t
|
||||
|
||||
/**
|
||||
* @class FairMQChannel FairMQChannel.h <FairMQChannel.h>
|
||||
* @brief Wrapper class for FairMQSocket and related methods
|
||||
*
|
||||
* The class is not thread-safe.
|
||||
*/
|
||||
class FairMQChannel
|
||||
{
|
||||
friend class FairMQDevice;
|
||||
@@ -68,23 +72,20 @@ class FairMQChannel
|
||||
FairMQChannel(const FairMQChannel&, const std::string& name);
|
||||
|
||||
/// Move constructor
|
||||
FairMQChannel(FairMQChannel&&) = delete;
|
||||
// FairMQChannel(FairMQChannel&&) = delete;
|
||||
|
||||
/// Assignment operator
|
||||
FairMQChannel& operator=(const FairMQChannel&);
|
||||
|
||||
/// Move assignment operator
|
||||
FairMQChannel& operator=(FairMQChannel&&) = delete;
|
||||
// FairMQChannel& operator=(FairMQChannel&&) = delete;
|
||||
|
||||
/// Destructor
|
||||
virtual ~FairMQChannel()
|
||||
{
|
||||
// LOG(debug) << "Destroying channel " << fName;
|
||||
}
|
||||
virtual ~FairMQChannel() { /* LOG(warn) << "Destroying channel '" << fName << "'"; */ }
|
||||
|
||||
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
FairMQSocket& GetSocket() const;
|
||||
FairMQSocket& GetSocket() const { assert(fSocket); return *fSocket; }
|
||||
|
||||
bool Bind(const std::string& address)
|
||||
{
|
||||
@@ -102,139 +103,142 @@ class FairMQChannel
|
||||
|
||||
/// Get channel name
|
||||
/// @return Returns full channel name (e.g. "data[0]")
|
||||
std::string GetChannelName() const __attribute__((deprecated("Use GetName()"))) { return GetName(); }
|
||||
std::string GetName() const ;
|
||||
std::string GetName() const { return fName; }
|
||||
|
||||
/// Get channel prefix
|
||||
/// @return Returns channel prefix (e.g. "data" in "data[0]")
|
||||
std::string GetChannelPrefix() const __attribute__((deprecated("Use GetPrefix()"))) { return GetPrefix(); }
|
||||
std::string GetPrefix() const;
|
||||
std::string GetPrefix() const
|
||||
{
|
||||
std::string prefix = fName;
|
||||
prefix = prefix.erase(fName.rfind('['));
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/// Get channel index
|
||||
/// @return Returns channel index (e.g. 0 in "data[0]")
|
||||
std::string GetChannelIndex() const __attribute__((deprecated("Use GetIndex()"))) { return GetIndex(); }
|
||||
std::string GetIndex() const;
|
||||
std::string GetIndex() const
|
||||
{
|
||||
std::string indexStr = fName;
|
||||
indexStr.erase(indexStr.rfind(']'));
|
||||
indexStr.erase(0, indexStr.rfind('[') + 1);
|
||||
return indexStr;
|
||||
}
|
||||
|
||||
/// Get socket type
|
||||
/// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||
std::string GetType() const;
|
||||
std::string GetType() const { return fType; }
|
||||
|
||||
/// Get socket method
|
||||
/// @return Returns socket method (bind/connect)
|
||||
std::string GetMethod() const;
|
||||
std::string GetMethod() const { return fMethod; }
|
||||
|
||||
/// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||
/// @return Returns socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||
std::string GetAddress() const;
|
||||
std::string GetAddress() const { return fAddress; }
|
||||
|
||||
/// Get channel transport name ("default", "zeromq", "nanomsg" or "shmem")
|
||||
/// @return Returns channel transport name (e.g. "default", "zeromq", "nanomsg" or "shmem")
|
||||
std::string GetTransportName() const;
|
||||
/// Get channel transport name ("default", "zeromq" or "shmem")
|
||||
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
|
||||
std::string GetTransportName() const { return fair::mq::TransportName(fTransportType); }
|
||||
|
||||
/// Get channel transport type
|
||||
/// @return Returns channel transport type
|
||||
fair::mq::Transport GetTransportType() const;
|
||||
fair::mq::Transport GetTransportType() const { return fTransportType; }
|
||||
|
||||
/// Get socket send buffer size (in number of messages)
|
||||
/// @return Returns socket send buffer size (in number of messages)
|
||||
int GetSndBufSize() const;
|
||||
int GetSndBufSize() const { return fSndBufSize; }
|
||||
|
||||
/// Get socket receive buffer size (in number of messages)
|
||||
/// @return Returns socket receive buffer size (in number of messages)
|
||||
int GetRcvBufSize() const;
|
||||
int GetRcvBufSize() const { return fRcvBufSize; }
|
||||
|
||||
/// Get socket kernel transmit send buffer size (in bytes)
|
||||
/// @return Returns socket kernel transmit send buffer size (in bytes)
|
||||
int GetSndKernelSize() const;
|
||||
int GetSndKernelSize() const { return fSndKernelSize; }
|
||||
|
||||
/// Get socket kernel transmit receive buffer size (in bytes)
|
||||
/// @return Returns socket kernel transmit receive buffer size (in bytes)
|
||||
int GetRcvKernelSize() const;
|
||||
int GetRcvKernelSize() const { return fRcvKernelSize; }
|
||||
|
||||
/// Get linger duration (in milliseconds)
|
||||
/// @return Returns linger duration (in milliseconds)
|
||||
int GetLinger() const;
|
||||
int GetLinger() const { return fLinger; }
|
||||
|
||||
/// Get socket rate logging interval (in seconds)
|
||||
/// @return Returns socket rate logging interval (in seconds)
|
||||
int GetRateLogging() const;
|
||||
int GetRateLogging() const { return fRateLogging; }
|
||||
|
||||
/// Get start of the port range for automatic binding
|
||||
/// @return start of the port range
|
||||
int GetPortRangeMin() const;
|
||||
int GetPortRangeMin() const { return fPortRangeMin; }
|
||||
|
||||
/// Get end of the port range for automatic binding
|
||||
/// @return end of the port range
|
||||
int GetPortRangeMax() const;
|
||||
int GetPortRangeMax() const { return fPortRangeMax; }
|
||||
|
||||
/// Set automatic binding (pick random port if bind fails)
|
||||
/// @return true/false, true if automatic binding is enabled
|
||||
bool GetAutoBind() const;
|
||||
|
||||
/// Set socket type
|
||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||
void UpdateType(const std::string& type);
|
||||
|
||||
/// Set socket method
|
||||
/// @param method Socket method (bind/connect)
|
||||
void UpdateMethod(const std::string& method);
|
||||
|
||||
/// Set socket address
|
||||
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||
void UpdateAddress(const std::string& address);
|
||||
|
||||
/// Set channel transport
|
||||
/// @param transport transport string ("default", "zeromq", "nanomsg" or "shmem")
|
||||
void UpdateTransport(const std::string& transport);
|
||||
|
||||
/// Set socket send buffer size
|
||||
/// @param sndBufSize Socket send buffer size (in number of messages)
|
||||
void UpdateSndBufSize(const int sndBufSize);
|
||||
|
||||
/// Set socket receive buffer size
|
||||
/// @param rcvBufSize Socket receive buffer size (in number of messages)
|
||||
void UpdateRcvBufSize(const int rcvBufSize);
|
||||
|
||||
/// Set socket kernel transmit send buffer size (in bytes)
|
||||
/// @param sndKernelSize Socket send buffer size (in bytes)
|
||||
void UpdateSndKernelSize(const int sndKernelSize);
|
||||
|
||||
/// Set socket kernel transmit receive buffer size (in bytes)
|
||||
/// @param rcvKernelSize Socket receive buffer size (in bytes)
|
||||
void UpdateRcvKernelSize(const int rcvKernelSize);
|
||||
|
||||
/// Set linger duration (in milliseconds)
|
||||
/// @param duration linger duration (in milliseconds)
|
||||
void UpdateLinger(const int duration);
|
||||
|
||||
/// Set socket rate logging interval (in seconds)
|
||||
/// @param rateLogging Socket rate logging interval (in seconds)
|
||||
void UpdateRateLogging(const int rateLogging);
|
||||
|
||||
/// Set start of the port range for automatic binding
|
||||
/// @param minPort start of the port range
|
||||
void UpdatePortRangeMin(const int minPort);
|
||||
|
||||
/// Set end of the port range for automatic binding
|
||||
/// @param maxPort end of the port range
|
||||
void UpdatePortRangeMax(const int maxPort);
|
||||
|
||||
/// Set automatic binding (pick random port if bind fails)
|
||||
/// @param autobind true/false, true to enable automatic binding
|
||||
void UpdateAutoBind(const bool autobind);
|
||||
bool GetAutoBind() const { return fAutoBind; }
|
||||
|
||||
/// Set channel name
|
||||
/// @param name Arbitrary channel name
|
||||
void UpdateChannelName(const std::string& name) __attribute__((deprecated("Use UpdateName()"))) { UpdateName(name); }
|
||||
void UpdateName(const std::string& name);
|
||||
void UpdateName(const std::string& name) { fName = name; Invalidate(); }
|
||||
|
||||
/// Set socket type
|
||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||
void UpdateType(const std::string& type) { fType = type; Invalidate(); }
|
||||
|
||||
/// Set socket method
|
||||
/// @param method Socket method (bind/connect)
|
||||
void UpdateMethod(const std::string& method) { fMethod = method; Invalidate(); }
|
||||
|
||||
/// Set socket address
|
||||
/// @param Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||
void UpdateAddress(const std::string& address) { fAddress = address; Invalidate(); }
|
||||
|
||||
/// Set channel transport
|
||||
/// @param transport transport string ("default", "zeromq" or "shmem")
|
||||
void UpdateTransport(const std::string& transport) { fTransportType = fair::mq::TransportType(transport); Invalidate(); }
|
||||
|
||||
/// Set socket send buffer size
|
||||
/// @param sndBufSize Socket send buffer size (in number of messages)
|
||||
void UpdateSndBufSize(const int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); }
|
||||
|
||||
/// Set socket receive buffer size
|
||||
/// @param rcvBufSize Socket receive buffer size (in number of messages)
|
||||
void UpdateRcvBufSize(const int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); }
|
||||
|
||||
/// Set socket kernel transmit send buffer size (in bytes)
|
||||
/// @param sndKernelSize Socket send buffer size (in bytes)
|
||||
void UpdateSndKernelSize(const int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); }
|
||||
|
||||
/// Set socket kernel transmit receive buffer size (in bytes)
|
||||
/// @param rcvKernelSize Socket receive buffer size (in bytes)
|
||||
void UpdateRcvKernelSize(const int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); }
|
||||
|
||||
/// Set linger duration (in milliseconds)
|
||||
/// @param duration linger duration (in milliseconds)
|
||||
void UpdateLinger(const int duration) { fLinger = duration; Invalidate(); }
|
||||
|
||||
/// Set socket rate logging interval (in seconds)
|
||||
/// @param rateLogging Socket rate logging interval (in seconds)
|
||||
void UpdateRateLogging(const int rateLogging) { fRateLogging = rateLogging; Invalidate(); }
|
||||
|
||||
/// Set start of the port range for automatic binding
|
||||
/// @param minPort start of the port range
|
||||
void UpdatePortRangeMin(const int minPort) { fPortRangeMin = minPort; Invalidate(); }
|
||||
|
||||
/// Set end of the port range for automatic binding
|
||||
/// @param maxPort end of the port range
|
||||
void UpdatePortRangeMax(const int maxPort) { fPortRangeMax = maxPort; Invalidate(); }
|
||||
|
||||
/// Set automatic binding (pick random port if bind fails)
|
||||
/// @param autobind true/false, true to enable automatic binding
|
||||
void UpdateAutoBind(const bool autobind) { fAutoBind = autobind; Invalidate(); }
|
||||
|
||||
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
|
||||
/// @return true if channel settings are valid, false otherwise.
|
||||
bool IsValid() const;
|
||||
|
||||
/// Validates channel configuration
|
||||
/// @return true if channel settings are valid, false otherwise.
|
||||
bool ValidateChannel() __attribute__((deprecated("Use Validate()"))) { return Validate(); }
|
||||
bool IsValid() const { return fValid; }
|
||||
|
||||
/// Validates channel configuration
|
||||
/// @return true if channel settings are valid, false otherwise.
|
||||
@@ -246,14 +250,14 @@ class FairMQChannel
|
||||
|
||||
bool BindEndpoint(std::string& endpoint);
|
||||
|
||||
/// Resets the channel (requires validation to be used again).
|
||||
void ResetChannel();
|
||||
/// invalidates the channel (requires validation to be used again).
|
||||
void Invalidate() { fValid = false; }
|
||||
|
||||
/// Sends a message to the socket queue.
|
||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
|
||||
int Send(FairMQMessagePtr& msg, int sndTimeoutInMs = -1)
|
||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Send(FairMQMessagePtr& msg, int sndTimeoutInMs = -1)
|
||||
{
|
||||
CheckSendCompatibility(msg);
|
||||
return fSocket->Send(msg, sndTimeoutInMs);
|
||||
@@ -262,8 +266,8 @@ class FairMQChannel
|
||||
/// Receives a message from the socket queue.
|
||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
|
||||
int Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs = -1)
|
||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs = -1)
|
||||
{
|
||||
CheckReceiveCompatibility(msg);
|
||||
return fSocket->Receive(msg, rcvTimeoutInMs);
|
||||
@@ -272,7 +276,7 @@ class FairMQChannel
|
||||
/// Send a vector of messages
|
||||
/// @param msgVec message vector reference
|
||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Send(std::vector<FairMQMessagePtr>& msgVec, int sndTimeoutInMs = -1)
|
||||
{
|
||||
CheckSendCompatibility(msgVec);
|
||||
@@ -282,7 +286,7 @@ class FairMQChannel
|
||||
/// Receive a vector of messages
|
||||
/// @param msgVec message vector reference
|
||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Receive(std::vector<FairMQMessagePtr>& msgVec, int rcvTimeoutInMs = -1)
|
||||
{
|
||||
CheckReceiveCompatibility(msgVec);
|
||||
@@ -292,7 +296,7 @@ class FairMQChannel
|
||||
/// Send FairMQParts
|
||||
/// @param parts FairMQParts reference
|
||||
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Send(FairMQParts& parts, int sndTimeoutInMs = -1)
|
||||
{
|
||||
return Send(parts.fParts, sndTimeoutInMs);
|
||||
@@ -301,7 +305,7 @@ class FairMQChannel
|
||||
/// Receive FairMQParts
|
||||
/// @param parts FairMQParts reference
|
||||
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Receive(FairMQParts& parts, int rcvTimeoutInMs = -1)
|
||||
{
|
||||
return Receive(parts.fParts, rcvTimeoutInMs);
|
||||
@@ -312,10 +316,7 @@ class FairMQChannel
|
||||
unsigned long GetMessagesTx() const { return fSocket->GetMessagesTx(); }
|
||||
unsigned long GetMessagesRx() const { return fSocket->GetMessagesRx(); }
|
||||
|
||||
auto Transport() -> FairMQTransportFactory*
|
||||
{
|
||||
return fTransportFactory.get();
|
||||
};
|
||||
auto Transport() -> FairMQTransportFactory* { return fTransportFactory.get(); };
|
||||
|
||||
template<typename... Args>
|
||||
FairMQMessagePtr NewMessage(Args&&... args)
|
||||
@@ -335,9 +336,10 @@ class FairMQChannel
|
||||
return Transport()->NewStaticMessage(data);
|
||||
}
|
||||
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
|
||||
template<typename... Args>
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
||||
{
|
||||
return Transport()->CreateUnmanagedRegion(size, callback, path, flags);
|
||||
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::DEFAULT;
|
||||
@@ -375,13 +377,9 @@ class FairMQChannel
|
||||
int fPortRangeMax;
|
||||
bool fAutoBind;
|
||||
|
||||
bool fIsValid;
|
||||
bool fValid;
|
||||
|
||||
bool fMultipart;
|
||||
bool fModified;
|
||||
bool fReset;
|
||||
|
||||
mutable std::mutex fMtx;
|
||||
|
||||
void CheckSendCompatibility(FairMQMessagePtr& msg)
|
||||
{
|
||||
@@ -438,8 +436,6 @@ class FairMQChannel
|
||||
fTransportFactory = factory;
|
||||
fTransportType = factory->GetType();
|
||||
}
|
||||
|
||||
auto SetModified(const bool modified) -> void;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQCHANNEL_H_ */
|
||||
|
@@ -24,34 +24,6 @@
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
static map<Transition, State> backwardsCompatibilityWaitForEndOfStateHelper =
|
||||
{
|
||||
{ Transition::InitDevice, State::InitializingDevice },
|
||||
{ Transition::CompleteInit, State::Initialized },
|
||||
{ Transition::Bind, State::Bound },
|
||||
{ Transition::Connect, State::DeviceReady },
|
||||
{ Transition::InitTask, State::Ready },
|
||||
{ Transition::Run, State::Ready },
|
||||
{ Transition::Stop, State::Ready },
|
||||
{ Transition::ResetTask, State::DeviceReady },
|
||||
{ Transition::ResetDevice, State::Idle }
|
||||
};
|
||||
|
||||
static map<int, Transition> backwardsCompatibilityChangeStateHelper =
|
||||
{
|
||||
{ FairMQDevice::Event::INIT_DEVICE, Transition::InitDevice },
|
||||
{ FairMQDevice::Event::internal_DEVICE_READY, Transition::Auto },
|
||||
{ FairMQDevice::Event::INIT_TASK, Transition::InitTask },
|
||||
{ FairMQDevice::Event::internal_READY, Transition::Auto },
|
||||
{ FairMQDevice::Event::RUN, Transition::Run },
|
||||
{ FairMQDevice::Event::STOP, Transition::Stop },
|
||||
{ FairMQDevice::Event::RESET_TASK, Transition::ResetTask },
|
||||
{ FairMQDevice::Event::RESET_DEVICE, Transition::ResetDevice },
|
||||
{ FairMQDevice::Event::internal_IDLE, Transition::Auto },
|
||||
{ FairMQDevice::Event::END, Transition::End },
|
||||
{ FairMQDevice::Event::ERROR_FOUND, Transition::ErrorFound }
|
||||
};
|
||||
|
||||
constexpr const char* FairMQDevice::DefaultId;
|
||||
constexpr int FairMQDevice::DefaultIOThreads;
|
||||
constexpr const char* FairMQDevice::DefaultTransportName;
|
||||
@@ -103,7 +75,7 @@ FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
|
||||
: fTransportFactory(nullptr)
|
||||
, fTransports()
|
||||
, fChannels()
|
||||
, fInternalConfig(config ? nullptr : tools::make_unique<ProgOptions>())
|
||||
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
|
||||
, fConfig(config ? config : fInternalConfig.get())
|
||||
, fId(DefaultId)
|
||||
, fDefaultTransportType(DefaultTransportType)
|
||||
@@ -244,16 +216,6 @@ void FairMQDevice::TransitionTo(const fair::mq::State s)
|
||||
}
|
||||
}
|
||||
|
||||
bool FairMQDevice::ChangeState(const int transition)
|
||||
{
|
||||
return ChangeState(backwardsCompatibilityChangeStateHelper.at(transition));
|
||||
}
|
||||
|
||||
void FairMQDevice::WaitForEndOfState(Transition transition)
|
||||
{
|
||||
WaitForState(backwardsCompatibilityWaitForEndOfStateHelper.at(transition));
|
||||
}
|
||||
|
||||
void FairMQDevice::InitWrapper()
|
||||
{
|
||||
// run initialization once CompleteInit transition is requested
|
||||
@@ -299,10 +261,15 @@ void FairMQDevice::InitWrapper()
|
||||
// if binding address is not specified, try getting it from the configured network interface
|
||||
if (subChannel.fAddress == "unspecified" || subChannel.fAddress == "") {
|
||||
// if the configured network interface is default, get its name from the default route
|
||||
if (networkInterface == "default") {
|
||||
networkInterface = tools::getDefaultRouteNetworkInterface();
|
||||
try {
|
||||
if (networkInterface == "default") {
|
||||
networkInterface = tools::getDefaultRouteNetworkInterface();
|
||||
}
|
||||
subChannel.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
|
||||
} catch(const tools::DefaultRouteDetectionError& e) {
|
||||
LOG(debug) << "binding on tcp://*:1";
|
||||
subChannel.fAddress = "tcp://*:1";
|
||||
}
|
||||
subChannel.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
|
||||
}
|
||||
// fill the uninitialized list
|
||||
fUninitializedBindingChannels.push_back(&subChannel);
|
||||
@@ -385,7 +352,6 @@ void FairMQDevice::AttachChannels(vector<FairMQChannel*>& chans)
|
||||
if ((*itr)->Validate()) {
|
||||
(*itr)->Init();
|
||||
if (AttachChannel(**itr)) {
|
||||
(*itr)->SetModified(false);
|
||||
// remove the channel from the uninitialized container
|
||||
itr = chans.erase(itr);
|
||||
} else {
|
||||
@@ -520,7 +486,6 @@ void FairMQDevice::RunWrapper()
|
||||
}
|
||||
|
||||
PostRun();
|
||||
|
||||
} catch (const out_of_range& oor) {
|
||||
LOG(error) << "out of range: " << oor.what();
|
||||
LOG(error) << "incorrect/incomplete channel configuration?";
|
||||
@@ -538,17 +503,12 @@ void FairMQDevice::HandleSingleChannelInput()
|
||||
{
|
||||
bool proceed = true;
|
||||
|
||||
if (fMsgInputs.size() > 0)
|
||||
{
|
||||
while (!NewStatePending() && proceed)
|
||||
{
|
||||
if (fMsgInputs.size() > 0) {
|
||||
while (!NewStatePending() && proceed) {
|
||||
proceed = HandleMsgInput(fInputChannelKeys.at(0), fMsgInputs.begin()->second, 0);
|
||||
}
|
||||
}
|
||||
else if (fMultipartInputs.size() > 0)
|
||||
{
|
||||
while (!NewStatePending() && proceed)
|
||||
{
|
||||
} else if (fMultipartInputs.size() > 0) {
|
||||
while (!NewStatePending() && proceed) {
|
||||
proceed = HandleMultipartInput(fInputChannelKeys.at(0), fMultipartInputs.begin()->second, 0);
|
||||
}
|
||||
}
|
||||
@@ -558,75 +518,55 @@ void FairMQDevice::HandleMultipleChannelInput()
|
||||
{
|
||||
// check if more than one transport is used
|
||||
fMultitransportInputs.clear();
|
||||
for (const auto& k : fInputChannelKeys)
|
||||
{
|
||||
for (const auto& k : fInputChannelKeys) {
|
||||
fair::mq::Transport t = fChannels.at(k).at(0).fTransportType;
|
||||
if (fMultitransportInputs.find(t) == fMultitransportInputs.end())
|
||||
{
|
||||
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
|
||||
fMultitransportInputs.insert(pair<fair::mq::Transport, vector<string>>(t, vector<string>()));
|
||||
fMultitransportInputs.at(t).push_back(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fMultitransportInputs.at(t).push_back(k);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& mi : fMsgInputs)
|
||||
{
|
||||
for (auto& i : fChannels.at(mi.first))
|
||||
{
|
||||
for (const auto& mi : fMsgInputs) {
|
||||
for (auto& i : fChannels.at(mi.first)) {
|
||||
i.fMultipart = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& mi : fMultipartInputs)
|
||||
{
|
||||
for (auto& i : fChannels.at(mi.first))
|
||||
{
|
||||
for (const auto& mi : fMultipartInputs) {
|
||||
for (auto& i : fChannels.at(mi.first)) {
|
||||
i.fMultipart = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if more than one transport is used, handle poll of each in a separate thread
|
||||
if (fMultitransportInputs.size() > 1)
|
||||
{
|
||||
if (fMultitransportInputs.size() > 1) {
|
||||
HandleMultipleTransportInput();
|
||||
}
|
||||
else // otherwise poll directly
|
||||
{
|
||||
} else { // otherwise poll directly
|
||||
bool proceed = true;
|
||||
|
||||
FairMQPollerPtr poller(fChannels.at(fInputChannelKeys.at(0)).at(0).fTransportFactory->CreatePoller(fChannels, fInputChannelKeys));
|
||||
|
||||
while (!NewStatePending() && proceed)
|
||||
{
|
||||
while (!NewStatePending() && proceed) {
|
||||
poller->Poll(200);
|
||||
|
||||
// check which inputs are ready and call their data handlers if they are.
|
||||
for (const auto& ch : fInputChannelKeys)
|
||||
{
|
||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i)
|
||||
{
|
||||
if (poller->CheckInput(ch, i))
|
||||
{
|
||||
if (fChannels.at(ch).at(i).fMultipart)
|
||||
{
|
||||
for (const auto& ch : fInputChannelKeys) {
|
||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
|
||||
if (poller->CheckInput(ch, i)) {
|
||||
if (fChannels.at(ch).at(i).fMultipart) {
|
||||
proceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
proceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
||||
}
|
||||
|
||||
if (!proceed)
|
||||
{
|
||||
if (!proceed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!proceed)
|
||||
{
|
||||
if (!proceed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -640,64 +580,49 @@ void FairMQDevice::HandleMultipleTransportInput()
|
||||
|
||||
fMultitransportProceed = true;
|
||||
|
||||
for (const auto& i : fMultitransportInputs)
|
||||
{
|
||||
for (const auto& i : fMultitransportInputs) {
|
||||
threads.emplace_back(thread(&FairMQDevice::PollForTransport, this, fTransports.at(i.first).get(), i.second));
|
||||
}
|
||||
|
||||
for (thread& t : threads)
|
||||
{
|
||||
for (thread& t : threads) {
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQDevice::PollForTransport(const FairMQTransportFactory* factory, const vector<string>& channelKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
FairMQPollerPtr poller(factory->CreatePoller(fChannels, channelKeys));
|
||||
|
||||
while (!NewStatePending() && fMultitransportProceed)
|
||||
{
|
||||
while (!NewStatePending() && fMultitransportProceed) {
|
||||
poller->Poll(500);
|
||||
|
||||
for (const auto& ch : channelKeys)
|
||||
{
|
||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i)
|
||||
{
|
||||
if (poller->CheckInput(ch, i))
|
||||
{
|
||||
for (const auto& ch : channelKeys) {
|
||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
|
||||
if (poller->CheckInput(ch, i)) {
|
||||
lock_guard<mutex> lock(fMultitransportMutex);
|
||||
|
||||
if (!fMultitransportProceed)
|
||||
{
|
||||
if (!fMultitransportProceed) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (fChannels.at(ch).at(i).fMultipart)
|
||||
{
|
||||
if (fChannels.at(ch).at(i).fMultipart) {
|
||||
fMultitransportProceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fMultitransportProceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
||||
}
|
||||
|
||||
if (!fMultitransportProceed)
|
||||
{
|
||||
if (!fMultitransportProceed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fMultitransportProceed)
|
||||
{
|
||||
if (!fMultitransportProceed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "FairMQDevice::PollForTransport() failed: " << e.what() << ", going to ERROR state.";
|
||||
throw runtime_error(tools::ToString("FairMQDevice::PollForTransport() failed: ", e.what(), ", going to ERROR state."));
|
||||
}
|
||||
@@ -707,12 +632,9 @@ bool FairMQDevice::HandleMsgInput(const string& chName, const InputMsgCallback&
|
||||
{
|
||||
unique_ptr<FairMQMessage> input(fChannels.at(chName).at(i).fTransportFactory->CreateMessage());
|
||||
|
||||
if (Receive(input, chName, i) >= 0)
|
||||
{
|
||||
if (Receive(input, chName, i) >= 0) {
|
||||
return callback(input, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -721,12 +643,9 @@ bool FairMQDevice::HandleMultipartInput(const string& chName, const InputMultipa
|
||||
{
|
||||
FairMQParts input;
|
||||
|
||||
if (Receive(input, chName, i) >= 0)
|
||||
{
|
||||
return callback(input, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Receive(input, chName, i) >= 0) {
|
||||
return callback(input, i);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -9,24 +9,23 @@
|
||||
#ifndef FAIRMQDEVICE_H_
|
||||
#define FAIRMQDEVICE_H_
|
||||
|
||||
#include <StateMachine.h>
|
||||
#include <FairMQTransportFactory.h>
|
||||
#include <fairmq/Transports.h>
|
||||
#include <fairmq/StateQueue.h>
|
||||
|
||||
#include <FairMQChannel.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <FairMQMessage.h>
|
||||
#include <FairMQParts.h>
|
||||
#include <FairMQTransportFactory.h>
|
||||
#include <FairMQUnmanagedRegion.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <fairmq/ProgOptions.h>
|
||||
#include <fairmq/StateMachine.h>
|
||||
#include <fairmq/StateQueue.h>
|
||||
#include <fairmq/Transports.h>
|
||||
#include <fairmq/tools/Version.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory> // unique_ptr
|
||||
#include <algorithm> // find
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
@@ -35,58 +34,21 @@
|
||||
#include <cstddef>
|
||||
#include <utility> // pair
|
||||
|
||||
#include <fairmq/tools/Version.h>
|
||||
|
||||
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
|
||||
using InputMsgCallback = std::function<bool(FairMQMessagePtr&, int)>;
|
||||
using InputMultipartCallback = std::function<bool(FairMQParts&, int)>;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
struct OngoingTransition : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
}
|
||||
}
|
||||
|
||||
class FairMQDevice
|
||||
{
|
||||
friend class FairMQChannel;
|
||||
|
||||
public:
|
||||
// backwards-compatibility enum for old state machine interface, todo: delete this
|
||||
enum Event
|
||||
{
|
||||
INIT_DEVICE,
|
||||
internal_DEVICE_READY,
|
||||
INIT_TASK,
|
||||
internal_READY,
|
||||
RUN,
|
||||
STOP,
|
||||
RESET_TASK,
|
||||
RESET_DEVICE,
|
||||
internal_IDLE,
|
||||
END,
|
||||
ERROR_FOUND
|
||||
};
|
||||
|
||||
// backwards-compatibility enum for old state machine interface, todo: delete this
|
||||
enum State
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
IDLE,
|
||||
INITIALIZING_DEVICE,
|
||||
DEVICE_READY,
|
||||
INITIALIZING_TASK,
|
||||
READY,
|
||||
RUNNING,
|
||||
RESETTING_TASK,
|
||||
RESETTING_DEVICE,
|
||||
EXITING
|
||||
};
|
||||
|
||||
/// Default constructor
|
||||
FairMQDevice();
|
||||
/// Constructor with external fair::mq::ProgOptions
|
||||
@@ -129,8 +91,8 @@ class FairMQDevice
|
||||
/// @param chan channel name
|
||||
/// @param i channel index
|
||||
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
|
||||
int Send(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
|
||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Send(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
|
||||
{
|
||||
return GetChannel(channel, index).Send(msg, sndTimeoutInMs);
|
||||
}
|
||||
@@ -140,8 +102,8 @@ class FairMQDevice
|
||||
/// @param chan channel name
|
||||
/// @param i channel index
|
||||
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
|
||||
int Receive(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
|
||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Receive(FairMQMessagePtr& msg, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
|
||||
{
|
||||
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
|
||||
}
|
||||
@@ -151,7 +113,7 @@ class FairMQDevice
|
||||
/// @param chan channel name
|
||||
/// @param i channel index
|
||||
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Send(FairMQParts& parts, const std::string& channel, const int index = 0, int sndTimeoutInMs = -1)
|
||||
{
|
||||
return GetChannel(channel, index).Send(parts.fParts, sndTimeoutInMs);
|
||||
@@ -162,7 +124,7 @@ class FairMQDevice
|
||||
/// @param chan channel name
|
||||
/// @param i channel index
|
||||
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
|
||||
/// @return Number of bytes that have been received. -2 if reading from the queue was not possible or timed out. -1 if there was an error.
|
||||
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
|
||||
int64_t Receive(FairMQParts& parts, const std::string& channel, const int index = 0, int rcvTimeoutInMs = -1)
|
||||
{
|
||||
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
|
||||
@@ -217,15 +179,17 @@ class FairMQDevice
|
||||
}
|
||||
|
||||
// creates unamanaged region with the default device transport
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr)
|
||||
template<typename... Args>
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(Args&&... args)
|
||||
{
|
||||
return Transport()->CreateUnmanagedRegion(size, callback);
|
||||
return Transport()->CreateUnmanagedRegion(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// creates unmanaged region with the transport of the specified channel
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
|
||||
template<typename... Args>
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, Args&&... args)
|
||||
{
|
||||
return GetChannel(channel, index).NewUnmanagedRegion(size, callback, path, flags);
|
||||
return GetChannel(channel, index).NewUnmanagedRegion(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ...Ts>
|
||||
@@ -272,7 +236,7 @@ class FairMQDevice
|
||||
}
|
||||
|
||||
/// Adds a transport to the device if it doesn't exist
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
/// @param transport Transport string ("zeromq"/"shmem")
|
||||
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
|
||||
|
||||
/// Assigns config to the device
|
||||
@@ -361,10 +325,10 @@ class FairMQDevice
|
||||
void PrintRegisteredChannels()
|
||||
{
|
||||
if (fChannelRegistry.size() < 1) {
|
||||
std::cout << "no channels registered." << std::endl;
|
||||
LOGV(info, verylow) << "no channels registered.";
|
||||
} else {
|
||||
for (const auto& c : fChannelRegistry) {
|
||||
std::cout << c.first << ":" << c.second.first << ":" << c.second.second << std::endl;
|
||||
LOGV(info, verylow) << c.first << ":" << c.second.first << ":" << c.second.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,7 +351,7 @@ class FairMQDevice
|
||||
int GetInitTimeoutInS() const { return fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout); }
|
||||
|
||||
/// Sets the default transport for the device
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
/// @param transport Transport string ("zeromq"/"shmem")
|
||||
void SetTransport(const std::string& transport) { fConfig->SetProperty("transport", transport); }
|
||||
/// Gets the default transport name
|
||||
std::string GetTransportName() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
|
||||
@@ -448,8 +412,6 @@ class FairMQDevice
|
||||
/// Called in the RUNNING state once after executing the Run()/ConditionalRun() method
|
||||
virtual void PostRun() {}
|
||||
|
||||
virtual void Pause() __attribute__((deprecated("PAUSE state is removed. This method is never called. To pause Run, go to READY with STOP transition and back to RUNNING with RUN to resume."))) {}
|
||||
|
||||
/// Resets the user task (to be overloaded in child classes)
|
||||
virtual void ResetTask() {}
|
||||
|
||||
@@ -457,36 +419,64 @@ class FairMQDevice
|
||||
virtual void Reset() {}
|
||||
|
||||
public:
|
||||
/// @brief Request a device state transition
|
||||
/// @param transition state transition
|
||||
///
|
||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
|
||||
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
|
||||
/// @brief Request a device state transition
|
||||
/// @param transition state transition
|
||||
///
|
||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
|
||||
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::GetTransition(transition)); }
|
||||
|
||||
bool ChangeState(const int transition) __attribute__((deprecated("Use ChangeState(const fair::mq::Transition transition).")));
|
||||
|
||||
void WaitForEndOfState(const fair::mq::Transition transition) __attribute__((deprecated("Use WaitForState(fair::mq::State expectedState).")));
|
||||
void WaitForEndOfState(const std::string& transition) __attribute__((deprecated("Use WaitForState(fair::mq::State expectedState)."))) { WaitForState(transition); }
|
||||
|
||||
/// @brief waits for the next state (any) to occur
|
||||
fair::mq::State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
||||
/// @brief waits for the specified state to occur
|
||||
/// @param state state to wait for
|
||||
void WaitForState(fair::mq::State state) { fStateQueue.WaitForState(state); }
|
||||
/// @brief waits for the specified state to occur
|
||||
/// @param state state to wait for
|
||||
void WaitForState(const std::string& state) { WaitForState(fair::mq::GetState(state)); }
|
||||
|
||||
void TransitionTo(const fair::mq::State state);
|
||||
|
||||
/// @brief Subscribe with a callback to state changes
|
||||
/// @param key id to identify your subscription
|
||||
/// @param callback callback (called with the new state as the parameter)
|
||||
///
|
||||
/// The callback is called at the beginning of a new state.
|
||||
/// The callback is called from the thread the state is running in.
|
||||
void SubscribeToStateChange(const std::string& key, std::function<void(const fair::mq::State)> callback) { fStateMachine.SubscribeToStateChange(key, callback); }
|
||||
/// @brief Unsubscribe from state changes
|
||||
/// @param key id (that was used when subscribing)
|
||||
void UnsubscribeFromStateChange(const std::string& key) { fStateMachine.UnsubscribeFromStateChange(key); }
|
||||
|
||||
/// @brief Subscribe with a callback to incoming state transitions
|
||||
/// @param key id to identify your subscription
|
||||
/// @param callback callback (called with the incoming transition as the parameter)
|
||||
/// The callback is called when new transition is initiated.
|
||||
/// The callback is called from the thread that initiates the transition (via ChangeState).
|
||||
void SubscribeToNewTransition(const std::string& key, std::function<void(const fair::mq::Transition)> callback) { fStateMachine.SubscribeToNewTransition(key, callback); }
|
||||
/// @brief Unsubscribe from state transitions
|
||||
/// @param key id (that was used when subscribing)
|
||||
void UnsubscribeFromNewTransition(const std::string& key) { fStateMachine.UnsubscribeFromNewTransition(key); }
|
||||
|
||||
bool CheckCurrentState(const int /* state */) const __attribute__((deprecated("Use NewStatePending()."))) { return !fStateMachine.NewStatePending(); }
|
||||
bool CheckCurrentState(const std::string& /* state */) const __attribute__((deprecated("Use NewStatePending()."))) { return !fStateMachine.NewStatePending(); }
|
||||
|
||||
/// Returns true is a new state has been requested, signaling the current handler to stop.
|
||||
/// @brief Returns true if a new state has been requested, signaling the current handler to stop.
|
||||
bool NewStatePending() const { return fStateMachine.NewStatePending(); }
|
||||
|
||||
/// @brief Returns the current state
|
||||
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
||||
/// @brief Returns the name of the current state as a string
|
||||
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
||||
|
||||
/// @brief Returns name of the given state as a string
|
||||
/// @param state state
|
||||
static std::string GetStateName(const fair::mq::State state) { return fair::mq::GetStateName(state); }
|
||||
/// @brief Returns name of the given transition as a string
|
||||
/// @param transition transition
|
||||
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::GetTransitionName(transition); }
|
||||
|
||||
static constexpr const char* DefaultId = "";
|
||||
|
@@ -11,19 +11,34 @@
|
||||
|
||||
#include <cstddef> // for size_t
|
||||
#include <memory> // unique_ptr
|
||||
#include <stdexcept>
|
||||
|
||||
#include <fairmq/Transports.h>
|
||||
|
||||
using fairmq_free_fn = void(void* data, void* hint);
|
||||
class FairMQTransportFactory;
|
||||
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
struct Alignment
|
||||
{
|
||||
size_t alignment;
|
||||
explicit operator size_t() const { return alignment; }
|
||||
};
|
||||
|
||||
} // namespace fair::mq
|
||||
|
||||
class FairMQMessage
|
||||
{
|
||||
public:
|
||||
FairMQMessage() = default;
|
||||
FairMQMessage(FairMQTransportFactory* factory):fTransport{factory} {}
|
||||
FairMQMessage(FairMQTransportFactory* factory) : fTransport(factory) {}
|
||||
|
||||
virtual void Rebuild() = 0;
|
||||
virtual void Rebuild(fair::mq::Alignment alignment) = 0;
|
||||
virtual void Rebuild(const size_t size) = 0;
|
||||
virtual void Rebuild(const size_t size, fair::mq::Alignment alignment) = 0;
|
||||
virtual void Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
||||
|
||||
virtual void* GetData() const = 0;
|
||||
@@ -33,7 +48,7 @@ class FairMQMessage
|
||||
|
||||
virtual fair::mq::Transport GetType() const = 0;
|
||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
||||
//void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
||||
|
||||
virtual void Copy(const FairMQMessage& msg) = 0;
|
||||
|
||||
@@ -45,16 +60,14 @@ class FairMQMessage
|
||||
|
||||
using FairMQMessagePtr = std::unique_ptr<FairMQMessage>;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using Message = FairMQMessage;
|
||||
using MessagePtr = FairMQMessagePtr;
|
||||
struct MessageError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
struct MessageBadAlloc : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQMESSAGE_H_ */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
@@ -9,8 +9,9 @@
|
||||
#ifndef FAIRMQPOLLER_H_
|
||||
#define FAIRMQPOLLER_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
class FairMQPoller
|
||||
{
|
||||
@@ -26,16 +27,13 @@ class FairMQPoller
|
||||
|
||||
using FairMQPollerPtr = std::unique_ptr<FairMQPoller>;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using PollerPtr = std::unique_ptr<FairMQPoller>;
|
||||
|
||||
using Poller = FairMQPoller;
|
||||
using PollerPtr = FairMQPollerPtr;
|
||||
struct PollerError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQPOLLER_H_ */
|
||||
|
@@ -9,26 +9,42 @@
|
||||
#ifndef FAIRMQSOCKET_H_
|
||||
#define FAIRMQSOCKET_H_
|
||||
|
||||
#include "FairMQMessage.h"
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "FairMQMessage.h"
|
||||
class FairMQTransportFactory;
|
||||
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
enum class TransferCode : int
|
||||
{
|
||||
success = 0,
|
||||
error = -1,
|
||||
timeout = -2,
|
||||
interrupted = -3
|
||||
};
|
||||
|
||||
} // namespace fair::mq
|
||||
|
||||
class FairMQSocket
|
||||
{
|
||||
public:
|
||||
FairMQSocket() {}
|
||||
FairMQSocket(FairMQTransportFactory* fac): fTransport(fac) {}
|
||||
FairMQSocket(FairMQTransportFactory* fac) : fTransport(fac) {}
|
||||
|
||||
virtual std::string GetId() = 0;
|
||||
virtual std::string GetId() const = 0;
|
||||
|
||||
virtual bool Bind(const std::string& address) = 0;
|
||||
virtual bool Connect(const std::string& address) = 0;
|
||||
|
||||
virtual int Send(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
||||
virtual int Receive(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
||||
virtual int64_t Send(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
||||
virtual int64_t Receive(FairMQMessagePtr& msg, int timeout = -1) = 0;
|
||||
virtual int64_t Send(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
|
||||
virtual int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int timeout = -1) = 0;
|
||||
|
||||
@@ -37,6 +53,10 @@ class FairMQSocket
|
||||
virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0;
|
||||
virtual void GetOption(const std::string& option, void* value, size_t* valueSize) = 0;
|
||||
|
||||
/// If the backend supports it, fills the unsigned integer @a events with the ZMQ_EVENTS value
|
||||
/// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in
|
||||
/// the future.
|
||||
virtual void Events(uint32_t* events) = 0;
|
||||
virtual void SetLinger(const int value) = 0;
|
||||
virtual int GetLinger() const = 0;
|
||||
virtual void SetSndBufSize(const int value) = 0;
|
||||
@@ -54,7 +74,7 @@ class FairMQSocket
|
||||
virtual unsigned long GetMessagesRx() const = 0;
|
||||
|
||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
||||
void SetTransport(FairMQTransportFactory* transport) { fTransport=transport; }
|
||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
||||
|
||||
virtual ~FairMQSocket() {};
|
||||
|
||||
@@ -64,16 +84,13 @@ class FairMQSocket
|
||||
|
||||
using FairMQSocketPtr = std::unique_ptr<FairMQSocket>;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using Socket = FairMQSocket;
|
||||
using SocketPtr = FairMQSocketPtr;
|
||||
struct SocketError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQSOCKET_H_ */
|
||||
|
@@ -7,69 +7,58 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <FairMQTransportFactory.h>
|
||||
#include <zeromq/FairMQTransportFactoryZMQ.h>
|
||||
#include <shmem/FairMQTransportFactorySHM.h>
|
||||
#ifdef BUILD_NANOMSG_TRANSPORT
|
||||
#include <nanomsg/FairMQTransportFactoryNN.h>
|
||||
#endif /* BUILD_NANOMSG_TRANSPORT */
|
||||
#include <fairmq/shmem/TransportFactory.h>
|
||||
#include <fairmq/zeromq/TransportFactory.h>
|
||||
#ifdef BUILD_OFI_TRANSPORT
|
||||
#include <fairmq/ofi/TransportFactory.h>
|
||||
#endif
|
||||
#include <FairMQLogger.h>
|
||||
#include <fairmq/tools/Unique.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
FairMQTransportFactory::FairMQTransportFactory(const std::string& id)
|
||||
using namespace std;
|
||||
|
||||
FairMQTransportFactory::FairMQTransportFactory(const string& id)
|
||||
: fkId(id)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
auto FairMQTransportFactory::CreateTransportFactory(const std::string& type, const std::string& id, const fair::mq::ProgOptions* config) -> std::shared_ptr<FairMQTransportFactory>
|
||||
auto FairMQTransportFactory::CreateTransportFactory(const string& type,
|
||||
const string& id,
|
||||
const fair::mq::ProgOptions* config)
|
||||
-> shared_ptr<FairMQTransportFactory>
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
auto finalId = id;
|
||||
|
||||
// Generate uuid if empty
|
||||
if (finalId == "")
|
||||
{
|
||||
if (finalId == "") {
|
||||
finalId = fair::mq::tools::Uuid();
|
||||
}
|
||||
|
||||
if (type == "zeromq")
|
||||
{
|
||||
return make_shared<FairMQTransportFactoryZMQ>(finalId, config);
|
||||
if (type == "zeromq") {
|
||||
return make_shared<fair::mq::zmq::TransportFactory>(finalId, config);
|
||||
} else if (type == "shmem") {
|
||||
return make_shared<fair::mq::shmem::TransportFactory>(finalId, config);
|
||||
}
|
||||
else if (type == "shmem")
|
||||
{
|
||||
return make_shared<FairMQTransportFactorySHM>(finalId, config);
|
||||
}
|
||||
#ifdef BUILD_NANOMSG_TRANSPORT
|
||||
else if (type == "nanomsg")
|
||||
{
|
||||
return make_shared<FairMQTransportFactoryNN>(finalId, config);
|
||||
}
|
||||
#endif /* BUILD_NANOMSG_TRANSPORT */
|
||||
#ifdef BUILD_OFI_TRANSPORT
|
||||
else if (type == "ofi")
|
||||
{
|
||||
else if (type == "ofi") {
|
||||
return make_shared<fair::mq::ofi::TransportFactory>(finalId, config);
|
||||
}
|
||||
#endif /* BUILD_OFI_TRANSPORT */
|
||||
else
|
||||
{
|
||||
LOG(error) << "Unavailable transport requested: " << "\"" << type << "\"" << ". Available are: "
|
||||
<< "\"zeromq\""
|
||||
else {
|
||||
LOG(error) << "Unavailable transport requested: "
|
||||
<< "\"" << type << "\""
|
||||
<< ". Available are: "
|
||||
<< "\"zeromq\","
|
||||
<< "\"shmem\""
|
||||
#ifdef BUILD_NANOMSG_TRANSPORT
|
||||
<< ", \"nanomsg\""
|
||||
#endif /* BUILD_NANOMSG_TRANSPORT */
|
||||
#ifdef BUILD_OFI_TRANSPORT
|
||||
<< ", and \"ofi\""
|
||||
#endif /* BUILD_OFI_TRANSPORT */
|
||||
<< ". Exiting.";
|
||||
exit(EXIT_FAILURE);
|
||||
throw fair::mq::TransportFactoryError(fair::mq::tools::ToString("Unavailable transport requested: ", type));
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#ifndef FAIRMQTRANSPORTFACTORY_H_
|
||||
#define FAIRMQTRANSPORTFACTORY_H_
|
||||
|
||||
#include <FairMQLogger.h>
|
||||
#include <FairMQMessage.h>
|
||||
#include <FairMQPoller.h>
|
||||
#include <FairMQSocket.h>
|
||||
@@ -18,14 +17,14 @@
|
||||
#include <fairmq/Transports.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <memory> // shared_ptr
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
class FairMQChannel;
|
||||
namespace fair { namespace mq { class ProgOptions; } }
|
||||
namespace fair::mq { class ProgOptions; }
|
||||
|
||||
class FairMQTransportFactory
|
||||
{
|
||||
@@ -47,13 +46,22 @@ class FairMQTransportFactory
|
||||
fair::mq::ChannelResource* GetMemoryResource() { return &fMemoryResource; }
|
||||
operator fair::mq::ChannelResource*() { return &fMemoryResource; }
|
||||
|
||||
/// @brief Create empty FairMQMessage
|
||||
/// @brief Create empty FairMQMessage (for receiving)
|
||||
/// @return pointer to FairMQMessage
|
||||
virtual FairMQMessagePtr CreateMessage() = 0;
|
||||
/// @brief Create empty FairMQMessage (for receiving), align received buffer to specified alignment
|
||||
/// @param alignment alignment to align received buffer to
|
||||
/// @return pointer to FairMQMessage
|
||||
virtual FairMQMessagePtr CreateMessage(fair::mq::Alignment alignment) = 0;
|
||||
/// @brief Create new FairMQMessage of specified size
|
||||
/// @param size message size
|
||||
/// @return pointer to FairMQMessage
|
||||
virtual FairMQMessagePtr CreateMessage(const size_t size) = 0;
|
||||
/// @brief Create new FairMQMessage of specified size and alignment
|
||||
/// @param size message size
|
||||
/// @param alignment message alignment
|
||||
/// @return pointer to FairMQMessage
|
||||
virtual FairMQMessagePtr CreateMessage(const size_t size, fair::mq::Alignment alignment) = 0;
|
||||
/// @brief Create new FairMQMessage with user provided buffer and size
|
||||
/// @param data pointer to user provided buffer
|
||||
/// @param size size of the user provided buffer
|
||||
@@ -61,20 +69,51 @@ class FairMQTransportFactory
|
||||
/// @param obj optional helper pointer that can be used in the callback
|
||||
/// @return pointer to FairMQMessage
|
||||
virtual FairMQMessagePtr CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) = 0;
|
||||
|
||||
/// @brief create a message with the buffer located within the corresponding unmanaged region
|
||||
/// @param unmanagedRegion the unmanaged region that this message buffer belongs to
|
||||
/// @param data message buffer (must be within the region - checked at runtime by the transport)
|
||||
/// @param size size of the message
|
||||
/// @param hint optional parameter, returned to the user in the FairMQRegionCallback
|
||||
virtual FairMQMessagePtr CreateMessage(FairMQUnmanagedRegionPtr& unmanagedRegion, void* data, const size_t size, void* hint = 0) = 0;
|
||||
|
||||
/// Create a socket
|
||||
/// @brief Create a socket
|
||||
virtual FairMQSocketPtr CreateSocket(const std::string& type, const std::string& name) = 0;
|
||||
|
||||
/// Create a poller for a single channel (all subchannels)
|
||||
/// @brief Create a poller for a single channel (all subchannels)
|
||||
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel>& channels) const = 0;
|
||||
/// Create a poller for specific channels
|
||||
/// @brief Create a poller for specific channels
|
||||
virtual FairMQPollerPtr CreatePoller(const std::vector<FairMQChannel*>& channels) const = 0;
|
||||
/// Create a poller for specific channels (all subchannels)
|
||||
/// @brief Create a poller for specific channels (all subchannels)
|
||||
virtual FairMQPollerPtr CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const = 0;
|
||||
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) const = 0;
|
||||
/// @brief Create new UnmanagedRegion
|
||||
/// @param size size of the region
|
||||
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
|
||||
/// @param path optional parameter to pass to the underlying transport
|
||||
/// @param flags optional parameter to pass to the underlying transport
|
||||
/// @return pointer to UnmanagedRegion
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
|
||||
/// @brief Create new UnmanagedRegion
|
||||
/// @param size size of the region
|
||||
/// @param userFlags flags to be stored with the region, have no effect on the transport, but can be retrieved from the region by the user
|
||||
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
|
||||
/// @param path optional parameter to pass to the underlying transport
|
||||
/// @param flags optional parameter to pass to the underlying transport
|
||||
/// @return pointer to UnmanagedRegion
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, const int64_t userFlags, FairMQRegionBulkCallback callback = nullptr, const std::string& path = "", int flags = 0) = 0;
|
||||
|
||||
/// @brief Subscribe to region events (creation, destruction, ...)
|
||||
/// @param callback the callback that is called when a region event occurs
|
||||
virtual void SubscribeToRegionEvents(FairMQRegionEventCallback callback) = 0;
|
||||
/// @brief Check if there is an active subscription to region events
|
||||
/// @return true/false
|
||||
virtual bool SubscribedToRegionEvents() = 0;
|
||||
/// @brief Unsubscribe from region events
|
||||
virtual void UnsubscribeFromRegionEvents() = 0;
|
||||
|
||||
virtual std::vector<FairMQRegionInfo> GetRegionInfo() = 0;
|
||||
|
||||
/// Get transport type
|
||||
virtual fair::mq::Transport GetType() const = 0;
|
||||
@@ -132,14 +171,12 @@ class FairMQTransportFactory
|
||||
}
|
||||
};
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using TransportFactory = FairMQTransportFactory;
|
||||
struct TransportFactoryError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQTRANSPORTFACTORY_H_ */
|
||||
|
@@ -10,30 +10,112 @@
|
||||
#define FAIRMQUNMANAGEDREGION_H_
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint32_t
|
||||
#include <memory> // std::unique_ptr
|
||||
#include <functional> // std::function
|
||||
#include <ostream> // std::ostream
|
||||
#include <vector>
|
||||
|
||||
class FairMQTransportFactory;
|
||||
|
||||
enum class FairMQRegionEvent : int
|
||||
{
|
||||
created,
|
||||
destroyed,
|
||||
local_only
|
||||
};
|
||||
|
||||
struct FairMQRegionInfo
|
||||
{
|
||||
FairMQRegionInfo()
|
||||
: managed(true)
|
||||
, id(0)
|
||||
, ptr(nullptr)
|
||||
, size(0)
|
||||
, flags(0)
|
||||
, event(FairMQRegionEvent::created)
|
||||
{}
|
||||
|
||||
FairMQRegionInfo(bool _managed, uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
|
||||
: managed(_managed)
|
||||
, id(_id)
|
||||
, ptr(_ptr)
|
||||
, size(_size)
|
||||
, flags(_flags)
|
||||
, event(_event)
|
||||
{}
|
||||
|
||||
bool managed; // managed/unmanaged
|
||||
uint64_t id; // id of the region
|
||||
void* ptr; // pointer to the start of the region
|
||||
size_t size; // region size
|
||||
int64_t flags; // custom flags set by the creator
|
||||
FairMQRegionEvent event;
|
||||
};
|
||||
|
||||
struct FairMQRegionBlock {
|
||||
void* ptr;
|
||||
size_t size;
|
||||
void* hint;
|
||||
|
||||
FairMQRegionBlock(void* p, size_t s, void* h)
|
||||
: ptr(p), size(s), hint(h)
|
||||
{}
|
||||
};
|
||||
|
||||
using FairMQRegionCallback = std::function<void(void*, size_t, void*)>;
|
||||
using FairMQRegionBulkCallback = std::function<void(const std::vector<FairMQRegionBlock>&)>;
|
||||
using FairMQRegionEventCallback = std::function<void(FairMQRegionInfo)>;
|
||||
|
||||
class FairMQUnmanagedRegion
|
||||
{
|
||||
public:
|
||||
FairMQUnmanagedRegion() {}
|
||||
FairMQUnmanagedRegion(FairMQTransportFactory* factory) : fTransport(factory) {}
|
||||
|
||||
virtual void* GetData() const = 0;
|
||||
virtual size_t GetSize() const = 0;
|
||||
virtual uint16_t GetId() const = 0;
|
||||
virtual void SetLinger(uint32_t linger) = 0;
|
||||
virtual uint32_t GetLinger() const = 0;
|
||||
|
||||
FairMQTransportFactory* GetTransport() { return fTransport; }
|
||||
void SetTransport(FairMQTransportFactory* transport) { fTransport = transport; }
|
||||
|
||||
virtual ~FairMQUnmanagedRegion() {};
|
||||
|
||||
private:
|
||||
FairMQTransportFactory* fTransport{nullptr};
|
||||
};
|
||||
|
||||
using FairMQUnmanagedRegionPtr = std::unique_ptr<FairMQUnmanagedRegion>;
|
||||
|
||||
namespace fair
|
||||
inline std::ostream& operator<<(std::ostream& os, const FairMQRegionEvent& event)
|
||||
{
|
||||
namespace mq
|
||||
switch (event) {
|
||||
case FairMQRegionEvent::created:
|
||||
return os << "created";
|
||||
case FairMQRegionEvent::destroyed:
|
||||
return os << "destroyed";
|
||||
case FairMQRegionEvent::local_only:
|
||||
return os << "local_only";
|
||||
default:
|
||||
return os << "unrecognized event";
|
||||
}
|
||||
}
|
||||
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using UnmanagedRegionPtr = std::unique_ptr<FairMQUnmanagedRegion>;
|
||||
using RegionCallback = FairMQRegionCallback;
|
||||
using RegionBulkCallback = FairMQRegionBulkCallback;
|
||||
using RegionEventCallback = FairMQRegionEventCallback;
|
||||
using RegionEvent = FairMQRegionEvent;
|
||||
using RegionInfo = FairMQRegionInfo;
|
||||
using RegionBlock = FairMQRegionBlock;
|
||||
using UnmanagedRegion = FairMQUnmanagedRegion;
|
||||
using UnmanagedRegionPtr = FairMQUnmanagedRegionPtr;
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQUNMANAGEDREGION_H_ */
|
||||
|
@@ -12,25 +12,25 @@
|
||||
* Created on May 14, 2015, 5:01 PM
|
||||
*/
|
||||
|
||||
#include <fairmq/PropertyOutput.h>
|
||||
#include "JSONParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <fairmq/Tools.h>
|
||||
#include "FairMQChannel.h"
|
||||
#include <fairmq/PropertyOutput.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/any.hpp>
|
||||
|
||||
#include <ios>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
using namespace fair::mq::tools;
|
||||
using namespace boost::property_tree;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
fair::mq::Properties PtreeParser(const ptree& pt, const string& id)
|
||||
@@ -183,5 +183,4 @@ void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties
|
||||
}
|
||||
|
||||
} // helper namespace
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
@@ -15,19 +15,13 @@
|
||||
#ifndef FAIR_MQ_JSONPARSER_H
|
||||
#define FAIR_MQ_JSONPARSER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <exception>
|
||||
|
||||
#include <fairmq/Properties.h>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include "FairMQChannel.h"
|
||||
#include <fairmq/Properties.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
struct ParserError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
@@ -45,7 +39,6 @@ void SubChannelParser(const boost::property_tree::ptree& tree, fair::mq::Propert
|
||||
|
||||
} // helper namespace
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_JSONPARSER_H */
|
||||
|
@@ -15,8 +15,8 @@
|
||||
#include <fairmq/FairMQTransportFactory.h>
|
||||
#include <fairmq/MemoryResources.h>
|
||||
|
||||
namespace fair {
|
||||
namespace mq {
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using BytePmrAllocator = pmr::polymorphic_allocator<fair::mq::byte>;
|
||||
|
||||
@@ -60,7 +60,6 @@ FairMQMessagePtr getMessage(ContainerT &&container_, FairMQMemoryResource *targe
|
||||
container.data(),
|
||||
containerSizeBytes);
|
||||
return message;
|
||||
};
|
||||
}
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
@@ -15,8 +15,7 @@
|
||||
#include <fairmq/FairMQTransportFactory.h>
|
||||
#include <fairmq/MemoryResources.h>
|
||||
|
||||
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t /*alignment*/)
|
||||
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
return setMessage(factory->CreateMessage(bytes));
|
||||
};
|
||||
|
||||
return setMessage(factory->CreateMessage(bytes, fair::mq::Alignment{alignment}));
|
||||
}
|
||||
|
@@ -15,18 +15,19 @@
|
||||
#ifndef FAIR_MQ_MEMORY_RESOURCES_H
|
||||
#define FAIR_MQ_MEMORY_RESOURCES_H
|
||||
|
||||
#include <fairmq/FairMQMessage.h>
|
||||
#include <FairMQMessage.h>
|
||||
class FairMQTransportFactory;
|
||||
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/pmr/memory_resource.hpp>
|
||||
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
|
||||
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace fair {
|
||||
namespace mq {
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using byte = unsigned char;
|
||||
namespace pmr = boost::container::pmr;
|
||||
@@ -106,7 +107,6 @@ class ChannelResource : public FairMQMemoryResource
|
||||
};
|
||||
};
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_MEMORY_RESOURCES_H */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2017-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
@@ -8,15 +8,20 @@
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
fair::mq::Plugin::Plugin(const string name, const Version version, const string maintainer, const string homepage, PluginServices* pluginServices)
|
||||
: fkName{name}
|
||||
fair::mq::Plugin::Plugin(string name,
|
||||
Version version,
|
||||
string maintainer,
|
||||
string homepage,
|
||||
PluginServices* pluginServices)
|
||||
: fkName(std::move(name))
|
||||
, fkVersion(version)
|
||||
, fkMaintainer{maintainer}
|
||||
, fkHomepage{homepage}
|
||||
, fPluginServices{pluginServices}
|
||||
, fkMaintainer(std::move(maintainer))
|
||||
, fkHomepage(std::move(homepage))
|
||||
, fPluginServices(pluginServices)
|
||||
{
|
||||
LOG(debug) << "Loaded plugin: " << *this;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2017-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
@@ -9,7 +9,6 @@
|
||||
#ifndef FAIR_MQ_PLUGIN_H
|
||||
#define FAIR_MQ_PLUGIN_H
|
||||
|
||||
#include <fairmq/tools/CppSTL.h>
|
||||
#include <fairmq/tools/Version.h>
|
||||
#include <fairmq/PluginServices.h>
|
||||
|
||||
@@ -25,9 +24,7 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -44,7 +41,11 @@ class Plugin
|
||||
using Version = tools::Version;
|
||||
|
||||
Plugin() = delete;
|
||||
Plugin(const std::string name, const Version version, const std::string maintainer, const std::string homepage, PluginServices* pluginServices);
|
||||
Plugin(std::string name,
|
||||
Version version,
|
||||
std::string maintainer,
|
||||
std::string homepage,
|
||||
PluginServices* pluginServices);
|
||||
|
||||
Plugin(const Plugin&) = delete;
|
||||
Plugin operator=(const Plugin&) = delete;
|
||||
@@ -60,10 +61,10 @@ class Plugin
|
||||
friend auto operator!=(const Plugin& lhs, const Plugin& rhs) -> bool { return !(lhs == rhs); }
|
||||
friend auto operator<<(std::ostream& os, const Plugin& p) -> std::ostream&
|
||||
{
|
||||
return os << "'" << p.GetName() << "', "
|
||||
<< "version '" << p.GetVersion() << "', "
|
||||
return os << "'" << p.GetName() << "', "
|
||||
<< "version '" << p.GetVersion() << "', "
|
||||
<< "maintainer '" << p.GetMaintainer() << "', "
|
||||
<< "homepage '" << p.GetHomepage() << "'";
|
||||
<< "homepage '" << p.GetHomepage() << "'";
|
||||
}
|
||||
static auto NoProgramOptions() -> ProgOptions { return boost::none; }
|
||||
|
||||
@@ -80,7 +81,6 @@ class Plugin
|
||||
auto StealDeviceControl() -> void { fPluginServices->StealDeviceControl(fkName); };
|
||||
auto ReleaseDeviceControl() -> void { fPluginServices->ReleaseDeviceControl(fkName); };
|
||||
auto ChangeDeviceState(const DeviceStateTransition next) -> bool { return fPluginServices->ChangeDeviceState(fkName, next); }
|
||||
void TransitionDeviceStateTo(const DeviceState state) { return fPluginServices->TransitionDeviceStateTo(fkName, state); }
|
||||
auto SubscribeToDeviceStateChange(std::function<void(DeviceState)> callback) -> void { fPluginServices->SubscribeToDeviceStateChange(fkName, callback); }
|
||||
auto UnsubscribeFromDeviceStateChange() -> void { fPluginServices->UnsubscribeFromDeviceStateChange(fkName); }
|
||||
|
||||
@@ -131,13 +131,12 @@ class Plugin
|
||||
PluginServices* fPluginServices;
|
||||
}; /* class Plugin */
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#define REGISTER_FAIRMQ_PLUGIN(KLASS, NAME, VERSION, MAINTAINER, HOMEPAGE, PROGOPTIONS) \
|
||||
static auto Make_##NAME##_Plugin(fair::mq::PluginServices* pluginServices) -> std::unique_ptr<fair::mq::Plugin> \
|
||||
{ \
|
||||
return fair::mq::tools::make_unique<KLASS>(std::string{#NAME}, VERSION, std::string{MAINTAINER}, std::string{HOMEPAGE}, pluginServices); \
|
||||
return std::make_unique<KLASS>(std::string{#NAME}, VERSION, std::string{MAINTAINER}, std::string{HOMEPAGE}, pluginServices); \
|
||||
} \
|
||||
BOOST_DLL_ALIAS(Make_##NAME##_Plugin, make_##NAME##_plugin) \
|
||||
BOOST_DLL_ALIAS(PROGOPTIONS, get_##NAME##_plugin_progoptions)
|
||||
|
@@ -28,6 +28,8 @@ using boost::optional;
|
||||
|
||||
const std::string fair::mq::PluginManager::fgkLibPrefix = "FairMQPlugin_";
|
||||
|
||||
std::vector<boost::dll::shared_library> fair::mq::PluginManager::fgDLLKeepAlive = std::vector<boost::dll::shared_library>();
|
||||
|
||||
fair::mq::PluginManager::PluginManager()
|
||||
: fSearchPaths{}
|
||||
, fPluginFactories()
|
||||
|
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
#include <fairmq/PluginServices.h>
|
||||
#include <fairmq/tools/CppSTL.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
@@ -31,9 +30,7 @@
|
||||
#include <vector>
|
||||
#include <utility> // forward
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -80,7 +77,7 @@ class PluginManager
|
||||
auto ForEachPluginProgOptions(std::function<void (boost::program_options::options_description)> func) const -> void { for(const auto& pair : fPluginProgOptions) { func(pair.second); } }
|
||||
|
||||
template<typename... Args>
|
||||
auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); };
|
||||
auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = std::make_unique<PluginServices>(std::forward<Args>(args)...); }
|
||||
|
||||
auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
|
||||
|
||||
@@ -97,6 +94,7 @@ class PluginManager
|
||||
using fair::mq::tools::ToString;
|
||||
|
||||
auto lib = shared_library{std::forward<Args>(args)...};
|
||||
fgDLLKeepAlive.push_back(lib);
|
||||
|
||||
fPluginFactories[pluginName] = import_alias<PluginFactory>(
|
||||
shared_library{lib},
|
||||
@@ -117,6 +115,7 @@ class PluginManager
|
||||
|
||||
static const std::string fgkLibPrefix;
|
||||
std::vector<boost::filesystem::path> fSearchPaths;
|
||||
static std::vector<boost::dll::shared_library> fgDLLKeepAlive;
|
||||
std::map<std::string, std::function<PluginFactory>> fPluginFactories;
|
||||
std::unique_ptr<PluginServices> fPluginServices;
|
||||
std::map<std::string, std::unique_ptr<Plugin>> fPlugins;
|
||||
@@ -124,7 +123,6 @@ class PluginManager
|
||||
std::map<std::string, boost::program_options::options_description> fPluginProgOptions;
|
||||
}; /* class PluginManager */
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_PLUGINMANAGER_H */
|
||||
|
@@ -28,22 +28,6 @@ auto PluginServices::ChangeDeviceState(const string& controller, const DeviceSta
|
||||
}
|
||||
}
|
||||
|
||||
void PluginServices::TransitionDeviceStateTo(const std::string& controller, DeviceState state)
|
||||
{
|
||||
lock_guard<mutex> lock{fDeviceControllerMutex};
|
||||
|
||||
if (!fDeviceController) fDeviceController = controller;
|
||||
|
||||
if (fDeviceController == controller) {
|
||||
fDevice.TransitionTo(state);
|
||||
} else {
|
||||
throw DeviceControlError{tools::ToString(
|
||||
"Plugin '", controller, "' is not allowed to change device states. ",
|
||||
"Currently, plugin '", *fDeviceController, "' has taken control."
|
||||
)};
|
||||
}
|
||||
}
|
||||
|
||||
auto PluginServices::TakeDeviceControl(const string& controller) -> void
|
||||
{
|
||||
lock_guard<mutex> lock{fDeviceControllerMutex};
|
||||
|
@@ -17,17 +17,16 @@
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/optional/optional_io.hpp>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <condition_variable>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -124,8 +123,6 @@ class PluginServices
|
||||
/// If the device control role has not been taken yet, calling this function will take over control implicitely.
|
||||
auto ChangeDeviceState(const std::string& controller, const DeviceStateTransition next) -> bool;
|
||||
|
||||
void TransitionDeviceStateTo(const std::string& controller, DeviceState state);
|
||||
|
||||
/// @brief Subscribe with a callback to device state changes
|
||||
/// @param subscriber id
|
||||
/// @param callback
|
||||
@@ -282,7 +279,6 @@ class PluginServices
|
||||
std::condition_variable fReleaseDeviceControlCondition;
|
||||
}; /* class PluginServices */
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_PLUGINSERVICES_H */
|
||||
|
@@ -39,9 +39,7 @@ struct ValInfo
|
||||
string origin;
|
||||
};
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
ValInfo ConvertVarValToValInfo(const po::variable_value& v)
|
||||
@@ -62,7 +60,7 @@ ValInfo ConvertVarValToValInfo(const po::variable_value& v)
|
||||
} catch (out_of_range& oor) {
|
||||
return {string("[unidentified_type]"), string("[unidentified_type]"), origin};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
string ConvertVarValToString(const po::variable_value& v)
|
||||
{
|
||||
@@ -79,7 +77,7 @@ ProgOptions::ProgOptions()
|
||||
fAllOptions.add_options()
|
||||
("help,h", "Print help")
|
||||
("version,v", "Print version")
|
||||
("severity", po::value<string>()->default_value("debug"), "Log severity level (console): trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("severity", po::value<string>()->default_value(""), "Log severity level (console): trace, debug, info, state, warn, error, fatal, nolog.")
|
||||
("file-severity", po::value<string>()->default_value("debug"), "Log severity level (file): trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level: veryhigh, high, medium, low")
|
||||
("color", po::value<bool >()->default_value(true), "Log color (true/false)")
|
||||
@@ -117,16 +115,24 @@ void ProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUn
|
||||
// clear the container because it was filled with default values and subsequent calls to store() do not overwrite the existing values
|
||||
fVarMap.clear();
|
||||
|
||||
if (allowUnregistered) {
|
||||
po::command_line_parser parser(argc, argv);
|
||||
parser.options(fAllOptions).allow_unregistered();
|
||||
po::parsed_options parsed = parser.run();
|
||||
fUnregisteredOptions = po::collect_unrecognized(parsed.options, po::include_positional);
|
||||
|
||||
po::store(parsed, fVarMap);
|
||||
} else {
|
||||
po::store(po::parse_command_line(argc, argv, fAllOptions), fVarMap);
|
||||
po::command_line_parser parser(argc, argv);
|
||||
|
||||
parser.options(fAllOptions);
|
||||
|
||||
if (allowUnregistered) {
|
||||
parser.allow_unregistered();
|
||||
}
|
||||
|
||||
using namespace po::command_line_style;
|
||||
style_t style = style_t(allow_short | short_allow_adjacent | short_allow_next | allow_long | long_allow_adjacent | long_allow_next | allow_sticky | allow_dash_for_short);
|
||||
parser.style(style);
|
||||
|
||||
po::parsed_options parsed = parser.run();
|
||||
|
||||
fUnregisteredOptions = po::collect_unrecognized(parsed.options, po::include_positional);
|
||||
|
||||
po::store(parsed, fVarMap);
|
||||
}
|
||||
|
||||
void ProgOptions::Notify()
|
||||
@@ -441,6 +447,4 @@ void ProgOptions::PrintOptionsRaw() const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
@@ -26,9 +26,7 @@
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
struct PropertyNotFoundError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
@@ -270,7 +268,6 @@ class ProgOptions
|
||||
mutable std::mutex fMtx;
|
||||
};
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIR_MQ_PROGOPTIONS_H */
|
||||
|
@@ -9,13 +9,10 @@
|
||||
#ifndef FAIR_MQ_PROGOPTIONSFWD_H
|
||||
#define FAIR_MQ_PROGOPTIONSFWD_H
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
class ProgOptions;
|
||||
}
|
||||
}
|
||||
|
||||
using FairMQProgOptions = fair::mq::ProgOptions;
|
||||
|
||||
|
@@ -7,17 +7,13 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/Properties.h>
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq::tools;
|
||||
using boost::any_cast;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
template<class T>
|
||||
@@ -76,9 +72,11 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
|
||||
{ type_index(typeid(const char*)), [](const Property& p) { return pair<string, string>{ string(any_cast<const char*>(p)), "string" }; } },
|
||||
{ type_index(typeid(string)), [](const Property& p) { return pair<string, string>{ any_cast<string>(p), "string" }; } },
|
||||
{ type_index(typeid(int)), [](const Property& p) { return getString<int>(p, "int"); } },
|
||||
{ type_index(typeid(short)), [](const Property& p) { return getString<short>(p, "short"); } },
|
||||
{ type_index(typeid(long)), [](const Property& p) { return getString<long>(p, "long"); } },
|
||||
{ type_index(typeid(long long)), [](const Property& p) { return getString<long long>(p, "long long"); } },
|
||||
{ type_index(typeid(unsigned)), [](const Property& p) { return getString<unsigned>(p, "unsigned"); } },
|
||||
{ type_index(typeid(unsigned short)), [](const Property& p) { return getString<unsigned short>(p, "unsigned short"); } },
|
||||
{ type_index(typeid(unsigned long)), [](const Property& p) { return getString<unsigned long>(p, "unsigned long"); } },
|
||||
{ type_index(typeid(unsigned long long)), [](const Property& p) { return getString<unsigned long long>(p, "unsigned long long"); } },
|
||||
{ type_index(typeid(float)), [](const Property& p) { return getStringPair<float>(p, "float"); } },
|
||||
@@ -92,9 +90,11 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
|
||||
{ type_index(typeid(vector<unsigned char>)), [](const Property& p) { return getStringPair<vector<unsigned char>>(p, "vector<unsigned char>"); } },
|
||||
{ type_index(typeid(vector<string>)), [](const Property& p) { return getStringPair<vector<string>>(p, "vector<string>"); } },
|
||||
{ type_index(typeid(vector<int>)), [](const Property& p) { return getStringPair<vector<int>>(p, "vector<int>"); } },
|
||||
{ type_index(typeid(vector<short>)), [](const Property& p) { return getStringPair<vector<short>>(p, "vector<short>"); } },
|
||||
{ type_index(typeid(vector<long>)), [](const Property& p) { return getStringPair<vector<long>>(p, "vector<long>"); } },
|
||||
{ type_index(typeid(vector<long long>)), [](const Property& p) { return getStringPair<vector<long long>>(p, "vector<long long>"); } },
|
||||
{ type_index(typeid(vector<unsigned>)), [](const Property& p) { return getStringPair<vector<unsigned>>(p, "vector<unsigned>"); } },
|
||||
{ type_index(typeid(vector<unsigned short>)), [](const Property& p) { return getStringPair<vector<unsigned short>>(p, "vector<unsigned short>"); } },
|
||||
{ type_index(typeid(vector<unsigned long>)), [](const Property& p) { return getStringPair<vector<unsigned long>>(p, "vector<unsigned long>"); } },
|
||||
{ type_index(typeid(vector<unsigned long long>)), [](const Property& p) { return getStringPair<vector<unsigned long long>>(p, "vector<unsigned long long>"); } },
|
||||
{ type_index(typeid(vector<float>)), [](const Property& p) { return getStringPair<vector<float>>(p, "vector<float>"); } },
|
||||
@@ -110,9 +110,11 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
|
||||
{ type_index(typeid(const char*)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, string>(k, string(any_cast<const char*>(p))); } },
|
||||
{ type_index(typeid(string)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, string>(k, any_cast<string>(p)); } },
|
||||
{ type_index(typeid(int)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, int>(k, any_cast<int>(p)); } },
|
||||
{ type_index(typeid(short)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, short>(k, any_cast<short>(p)); } },
|
||||
{ type_index(typeid(long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long>(k, any_cast<long>(p)); } },
|
||||
{ type_index(typeid(long long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long long>(k, any_cast<long long>(p)); } },
|
||||
{ type_index(typeid(unsigned)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned>(k, any_cast<unsigned>(p)); } },
|
||||
{ type_index(typeid(unsigned short)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned short>(k, any_cast<unsigned short>(p)); } },
|
||||
{ type_index(typeid(unsigned long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned long>(k, any_cast<unsigned long>(p)); } },
|
||||
{ type_index(typeid(unsigned long long)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, unsigned long long>(k, any_cast<unsigned long long>(p)); } },
|
||||
{ type_index(typeid(float)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, float>(k, any_cast<float>(p)); } },
|
||||
@@ -126,9 +128,11 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
|
||||
{ type_index(typeid(vector<unsigned char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned char>>(k, any_cast<vector<unsigned char>>(p)); } },
|
||||
{ type_index(typeid(vector<string>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<string>>(k, any_cast<vector<string>>(p)); } },
|
||||
{ type_index(typeid(vector<int>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<int>>(k, any_cast<vector<int>>(p)); } },
|
||||
{ type_index(typeid(vector<short>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<short>>(k, any_cast<vector<short>>(p)); } },
|
||||
{ type_index(typeid(vector<long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long>>(k, any_cast<vector<long>>(p)); } },
|
||||
{ type_index(typeid(vector<long long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long long>>(k, any_cast<vector<long long>>(p)); } },
|
||||
{ type_index(typeid(vector<unsigned>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned>>(k, any_cast<vector<unsigned>>(p)); } },
|
||||
{ type_index(typeid(vector<unsigned short>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned short>>(k, any_cast<vector<unsigned short>>(p)); } },
|
||||
{ type_index(typeid(vector<unsigned long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned long>>(k, any_cast<vector<unsigned long>>(p)); } },
|
||||
{ type_index(typeid(vector<unsigned long long>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned long long>>(k, any_cast<vector<unsigned long long>>(p)); } },
|
||||
{ type_index(typeid(vector<float>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<float>>(k, any_cast<vector<float>>(p)); } },
|
||||
@@ -137,5 +141,4 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
|
||||
{ type_index(typeid(vector<boost::filesystem::path>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<boost::filesystem::path>>(k, any_cast<vector<boost::filesystem::path>>(p)); } },
|
||||
};
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
@@ -16,14 +16,13 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <utility> // pair
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
using Property = boost::any;
|
||||
@@ -71,7 +70,6 @@ class PropertyHelper
|
||||
static std::unordered_map<std::type_index, std::function<std::pair<std::string, std::string>(const Property&)>> fTypeInfos;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FAIR_MQ_PROPERTIES_H */
|
||||
|
@@ -7,7 +7,8 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/StateMachine.h>
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
// Increase maximum number of boost::msm states (default is 10)
|
||||
// This #define has to be before any msm header includes
|
||||
@@ -34,9 +35,7 @@ using namespace boost::msm::front;
|
||||
using namespace boost::msm::back;
|
||||
namespace bmpl = boost::mpl;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
namespace fsm
|
||||
{
|
||||
@@ -79,7 +78,9 @@ struct Machine_ : public state_machine_def<Machine_>
|
||||
{
|
||||
public:
|
||||
Machine_()
|
||||
: fLastTransitionResult(true)
|
||||
: fState(State::Ok)
|
||||
, fNewState(State::Ok)
|
||||
, fLastTransitionResult(true)
|
||||
, fNewStatePending(false)
|
||||
{}
|
||||
|
||||
@@ -236,8 +237,7 @@ struct Machine_ : public state_machine_def<Machine_>
|
||||
using FairMQFSM = state_machine<Machine_>;
|
||||
|
||||
} // namespace fsm
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
||||
using namespace fair::mq::fsm;
|
||||
using namespace fair::mq;
|
||||
|
@@ -11,16 +11,12 @@
|
||||
|
||||
#include <fairmq/States.h>
|
||||
|
||||
#include <fairlogger/Logger.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
namespace fair::mq
|
||||
{
|
||||
|
||||
class StateMachine
|
||||
@@ -58,7 +54,6 @@ class StateMachine
|
||||
std::shared_ptr<void> fFsm;
|
||||
};
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
} // namespace fair::mq
|
||||
|
||||
#endif /* FAIRMQSTATEMACHINE_H_ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user