mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-16 10:01:47 +00:00
Compare commits
199 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f31be6d7a1 | ||
|
5607d47664 | ||
|
0f4595b8c1 | ||
|
b0b271d1f4 | ||
|
073f5e5c0e | ||
|
f6e3183f45 | ||
|
71325828f6 | ||
|
9d30ff25c2 | ||
|
2ac8f98178 | ||
|
2c6f436858 | ||
|
dd191551ca | ||
|
88dbcbe4fd | ||
|
85a3a254d4 | ||
|
c34d1f0946 | ||
|
160ee9d064 | ||
|
040931fba7 | ||
|
0d46ffe010 | ||
|
72a8e9b33c | ||
|
caeee626a3 | ||
|
e1134321dd | ||
|
5fc1c47e2a | ||
|
2f69526c04 | ||
|
7502f4b424 | ||
|
1c1509af3e | ||
|
a53e95b5f6 | ||
|
ea9ad64664 | ||
|
b9720e5269 | ||
|
343605899f | ||
|
d64169a163 | ||
|
37c8041997 | ||
|
d8d293302d | ||
|
9544d9665b | ||
|
47d9e282d4 | ||
|
23423a86d9 | ||
|
dc72262af1 | ||
|
44bfbe02ed | ||
|
924320a0ac | ||
|
e3890a4033 | ||
|
fa394194e8 | ||
|
79bcb40c04 | ||
|
54719da645 | ||
|
4b78c472b1 | ||
|
92112c812f | ||
|
870d0deae1 | ||
|
acbf57d6f3 | ||
|
2973ce0352 | ||
|
e1b6b804bd | ||
|
456b65871a | ||
|
3f5374820a | ||
|
8a2c7fb601 | ||
|
c1a17c97b8 | ||
|
ac8825c8de | ||
|
1c49dde668 | ||
|
5d6184cd1a | ||
|
0e5f648d2b | ||
|
8057b8ae33 | ||
|
da28b85497 | ||
|
33b5a2a342 | ||
|
5b47df3014 | ||
|
fd77f2b729 | ||
|
6275f4d267 | ||
|
d09be4ab79 | ||
|
246e99a577 | ||
|
0d182dc18f | ||
|
46e0796e77 | ||
|
1055f035ff | ||
|
7a0d348bd4 | ||
|
3cd6d8cfca | ||
|
0f50abf3d9 | ||
|
75a3a80ac1 | ||
|
25539e99f2 | ||
|
f73a6d71ed | ||
|
73af0ed78b | ||
|
1dec059104 | ||
|
88ff5d8fc0 | ||
|
d6d9312e53 | ||
|
2208fe91e8 | ||
|
8d12b908b6 | ||
|
02b20c320c | ||
|
be06a5629e | ||
|
eaa8f5cbdd | ||
|
7f0237d97d | ||
|
2fc93994d1 | ||
|
8feffe70ba | ||
|
31edf948de | ||
|
7cacf471b9 | ||
|
7316b0e7f2 | ||
|
1fa82f5f22 | ||
|
1bb77bf47b | ||
|
07fe02a0a0 | ||
|
9cbccface7 | ||
|
7b773cde51 | ||
|
fd282fa950 | ||
|
008be36125 | ||
|
93eb599df7 | ||
|
98aeb16dc7 | ||
|
6c07920fc6 | ||
|
b54df715ea | ||
|
ce1f507a24 | ||
|
f7cdf5ee23 | ||
|
6208cbb508 | ||
|
377eaf2bb8 | ||
|
363576496d | ||
|
5ab328b01f | ||
|
ac8cd19915 | ||
|
5d535163f1 | ||
|
dc55272317 | ||
|
388b1be056 | ||
|
d70a203449 | ||
|
a93840b240 | ||
|
bc98ab1eed | ||
|
de4fca177e | ||
|
7d1ee82c6b | ||
|
be022cfab8 | ||
|
8789664cfd | ||
|
cf26dd6aa7 | ||
|
18dc536f3d | ||
|
499ffcd300 | ||
|
a65f0e6777 | ||
|
b58f6ede74 | ||
|
8aad6c062b | ||
|
152c8431c6 | ||
|
5a7bf68c8c | ||
|
7aa95fcd93 | ||
|
a9b4788756 | ||
|
eb9dcdd1f9 | ||
|
3f655e330b | ||
|
e6149b7c38 | ||
|
b5da31498d | ||
|
44da054e78 | ||
|
53be96d93c | ||
|
cfcdd666bf | ||
|
90496c89fe | ||
|
1a93da5be0 | ||
|
99ed61a58b | ||
|
a98965031f | ||
|
fd682c3392 | ||
|
2c4a6674d2 | ||
|
7002dcbca3 | ||
|
790de84bbc | ||
|
e3d39f39f2 | ||
|
6e353d78b1 | ||
|
f515eb1100 | ||
|
4487b81de8 | ||
|
8bb6a9518a | ||
|
857ef0c9d3 | ||
|
63c02657c1 | ||
|
5256e7c580 | ||
|
74d301a16f | ||
|
1c7da53386 | ||
|
07f7142ae2 | ||
|
ff581985f3 | ||
|
5e8a442342 | ||
|
0b43bec9a7 | ||
|
afadb2a078 | ||
|
7c185ac4a5 | ||
|
a60edc43dc | ||
|
d4f96db69c | ||
|
b53691c8ad | ||
|
14980d7486 | ||
|
d966a0a991 | ||
|
66c01f2cda | ||
|
2150257c1d | ||
|
8be2fd33f4 | ||
|
26fe5e2bd8 | ||
|
48e04b636b | ||
|
937c9e8921 | ||
|
5c943bbedb | ||
|
418d42b060 | ||
|
4af0393c11 | ||
|
12f05355d3 | ||
|
69268eecfb | ||
|
4351b98d85 | ||
|
051f064c60 | ||
|
caffbf2ebf | ||
|
daed714146 | ||
|
4cefb9fb5b | ||
|
7486249c1e | ||
|
7c13503e22 | ||
|
3db32b03d4 | ||
|
7bea2bc0e6 | ||
|
5271d4236e | ||
|
4281d7b27e | ||
|
7c9744760e | ||
|
b905f517cc | ||
|
c515cbb3bf | ||
|
cba6d19781 | ||
|
bf8ec968e7 | ||
|
fbb003b50f | ||
|
4ce378b6b8 | ||
|
29313bbec3 | ||
|
fe241fe9ee | ||
|
5646d531f3 | ||
|
f46803a8b6 | ||
|
3538d9f410 | ||
|
73ccefa4cb | ||
|
0e35f1cb22 | ||
|
a8c76accdc | ||
|
3da5f4d5db |
3
.clang-tidy
Normal file
3
.clang-tidy
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
Checks: '*,-google-*,-fuchsia-*,-cert-*,-llvm-header-guard,-readability-named-parameter,-misc-non-private-member-variables-in-classes,-*-magic-numbers,-llvm-include-order,-hicpp-no-array-decay,-performance-unnecessary-value-param,-cppcoreguidelines-pro-bounds-array-to-pointer-decay'
|
||||
HeaderFilterRegex: '/(fairmq/)'
|
@@ -1,2 +1,3 @@
|
||||
comment:
|
||||
layout: "diff, files"
|
||||
behavior: once
|
||||
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "extern/googletest"]
|
||||
path = extern/googletest
|
||||
url = https://github.com/google/googletest
|
||||
[submodule "extern/asio"]
|
||||
path = extern/asio
|
||||
url = https://github.com/chriskohlhoff/asio
|
14
CMakeGraphVizOptions.cmake
Normal file
14
CMakeGraphVizOptions.cmake
Normal file
@@ -0,0 +1,14 @@
|
||||
set(GRAPHVIZ_GRAPH_TYPE digraph)
|
||||
set(GRAPHVIZ_GRAPH_NAME FairMQ)
|
||||
set(GRAPHVIZ_EXECUTABLES ON)
|
||||
set(GRAPHVIZ_STATIC_LIBS OFF)
|
||||
set(GRAPHVIZ_SHARED_LIBS ON)
|
||||
set(GRAPHVIZ_MODULE_LIBS OFF)
|
||||
set(GRAPHVIZ_GENERATE_PER_TARGET OFF)
|
||||
set(GRAPHVIZ_GENERATE_DEPENDERS OFF)
|
||||
set(GRAPHVIZ_IGNORE_TARGETS
|
||||
"fairmq-ex.*"
|
||||
"testsuite_.*"
|
||||
"testhelper_.*"
|
||||
"FairMQPlugin_test_dummy"
|
||||
)
|
163
CMakeLists.txt
163
CMakeLists.txt
@@ -6,8 +6,8 @@
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||
cmake_policy(VERSION 3.10...3.14)
|
||||
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
|
||||
cmake_policy(VERSION 3.11...3.15)
|
||||
|
||||
# Project ######################################################################
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
@@ -18,7 +18,7 @@ get_git_version()
|
||||
project(FairMQ VERSION ${PROJECT_VERSION} LANGUAGES CXX)
|
||||
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
if(BUILD_OFI_TRANSPORT OR BUILD_SDK)
|
||||
set(PROJECT_MIN_CXX_STANDARD 14)
|
||||
else()
|
||||
set(PROJECT_MIN_CXX_STANDARD 11)
|
||||
@@ -31,16 +31,28 @@ include(CTest)
|
||||
|
||||
|
||||
# Build options ################################################################
|
||||
include(CMakeDependentOption)
|
||||
option(BUILD_FAIRMQ "Build FairMQ library and devices." ON)
|
||||
cmake_dependent_option(BUILD_TESTING "Build tests." OFF "BUILD_FAIRMQ" OFF)
|
||||
cmake_dependent_option(BUILD_NANOMSG_TRANSPORT "Build nanomsg transport." OFF "BUILD_FAIRMQ" OFF)
|
||||
cmake_dependent_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport." OFF "BUILD_FAIRMQ" OFF)
|
||||
cmake_dependent_option(BUILD_DDS_PLUGIN "Build DDS plugin." OFF "BUILD_FAIRMQ" OFF)
|
||||
cmake_dependent_option(BUILD_PMIX_PLUGIN "Build PMIx plugin." OFF "BUILD_FAIRMQ" OFF)
|
||||
cmake_dependent_option(BUILD_EXAMPLES "Build FairMQ examples." ON "BUILD_FAIRMQ" OFF)
|
||||
option(BUILD_DOCS "Build FairMQ documentation." OFF)
|
||||
option(FAST_BUILD "Fast production build. Not recommended for development." OFF)
|
||||
fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
|
||||
DEFAULT ON)
|
||||
fairmq_build_option(BUILD_TESTING "Build tests."
|
||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_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)
|
||||
################################################################################
|
||||
|
||||
|
||||
@@ -73,9 +85,19 @@ if(BUILD_NANOMSG_TRANSPORT)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_DDS_PLUGIN)
|
||||
if(BUILD_SDK)
|
||||
set(required_dds_version 2.5.100)
|
||||
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 2.4
|
||||
VERSION ${required_dds_version}
|
||||
)
|
||||
set(DDS_Boost_COMPONENTS system log log_setup)
|
||||
set(DDS_Boost_VERSION 1.67)
|
||||
@@ -87,11 +109,18 @@ if(BUILD_PMIX_PLUGIN)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ)
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
find_package2(PUBLIC FairLogger REQUIRED
|
||||
VERSION 1.2.0
|
||||
)
|
||||
|
||||
foreach(dep IN LISTS FairLogger_PACKAGE_DEPENDENCIES)
|
||||
if(NOT dep STREQUAL "Boost")
|
||||
find_package2(PUBLIC ${dep} REQUIRED VERSION ${FairLogger_${dep}_VERSION})
|
||||
set(PROJECT_${dep}_VERSION ${FairLogger_${dep}_VERSION})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT DEFINED Boost_NO_BOOST_CMAKE AND CMAKE_VERSION VERSION_LESS 3.15)
|
||||
# Since Boost 1.70 a CMake package is shipped by default. Unfortunately, it has a number
|
||||
# of problems that are only fixed in Boost 1.71 or CMake 3.15. By default we skip the
|
||||
@@ -99,7 +128,7 @@ if(BUILD_FAIRMQ)
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
endif()
|
||||
find_package2(PUBLIC Boost REQUIRED
|
||||
VERSION 1.64
|
||||
VERSION 1.66
|
||||
|
||||
COMPONENTS
|
||||
container
|
||||
@@ -113,15 +142,35 @@ if(BUILD_FAIRMQ)
|
||||
DDS
|
||||
FairLogger
|
||||
)
|
||||
|
||||
# Normalize Boost version
|
||||
if(CMAKE_VERSION VERSION_LESS 3.15)
|
||||
set(Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_SDK)
|
||||
find_package2(BUNDLED asio
|
||||
VERSION 1.13.0
|
||||
)
|
||||
if(NOT asio_FOUND)
|
||||
build_bundled(asio extern/asio)
|
||||
find_package2(PRIVATE asio REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ)
|
||||
find_package2(PRIVATE ZeroMQ REQUIRED
|
||||
VERSION 4.1.5
|
||||
VERSION 4.1.4
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
find_package2(PRIVATE GTest REQUIRED
|
||||
VERSION 1.7.0
|
||||
)
|
||||
find_package2(PRIVATE GTest VERSION 1.7.0)
|
||||
if(NOT GTest_FOUND)
|
||||
build_bundled(GTest extern/googletest)
|
||||
find_package2(PRIVATE GTest REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_DOCS)
|
||||
@@ -135,12 +184,7 @@ endif()
|
||||
|
||||
|
||||
# Targets ######################################################################
|
||||
if(BUILD_FAIRMQ)
|
||||
configure_file(${PROJECT_NAME_LOWER}/Version.h.in
|
||||
${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
@ONLY
|
||||
)
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
add_subdirectory(fairmq)
|
||||
endif()
|
||||
|
||||
@@ -189,15 +233,17 @@ endif()
|
||||
if(BUILD_DOCS)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS docs)
|
||||
endif()
|
||||
if(BUILD_SDK)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk)
|
||||
endif()
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
||||
# Installation #################################################################
|
||||
if(BUILD_FAIRMQ)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
||||
)
|
||||
|
||||
install(FILES cmake/FindZeroMQ.cmake
|
||||
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
||||
)
|
||||
@@ -207,6 +253,22 @@ if(BUILD_DOCS)
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}/docs
|
||||
)
|
||||
endif()
|
||||
if(BUILD_SDK)
|
||||
install(FILES cmake/Findasio.cmake
|
||||
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
||||
)
|
||||
if(asio_BUNDLED)
|
||||
install(TARGETS bundled_asio_headers EXPORT ${PROJECT_EXPORT_SET})
|
||||
install(DIRECTORY "${asio_BUILD_INCLUDE_DIR}/asio"
|
||||
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
|
||||
PATTERN "Makefile.am" EXCLUDE
|
||||
PATTERN ".gitignore" EXCLUDE
|
||||
)
|
||||
install(FILES "${asio_BUILD_INCLUDE_DIR}/asio.hpp"
|
||||
DESTINATION ${asio_INSTALL_INCLUDE_DIR}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install_cmake_package()
|
||||
################################################################################
|
||||
@@ -242,16 +304,8 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}DEPENDENCY FOUND VERSION PREFIX${CR}")
|
||||
foreach(dep IN LISTS PROJECT_PACKAGE_DEPENDENCIES)
|
||||
if(${dep}_VERSION)
|
||||
if(${dep} STREQUAL Boost)
|
||||
if(Boost_VERSION_MAJOR)
|
||||
set(version_str "${BGreen}${${dep}_VERSION_MAJOR}.${${dep}_VERSION_MINOR}${CR}")
|
||||
else()
|
||||
set(version_str "${BGreen}${${dep}_MAJOR_VERSION}.${${dep}_MINOR_VERSION}${CR}")
|
||||
endif()
|
||||
else()
|
||||
if(${dep}_VERSION AND NOT ${dep}_VERSION STREQUAL "..")
|
||||
set(version_str "${BGreen}${${dep}_VERSION}${CR}")
|
||||
endif()
|
||||
else()
|
||||
set(version_str "${BYellow}unknown${CR}")
|
||||
endif()
|
||||
@@ -283,8 +337,7 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
get_target_property(nn_include nanomsg INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${nn_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL DDS)
|
||||
get_target_property(dds_include DDS::dds_intercom_lib INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${dds_include}/.. ABSOLUTE)
|
||||
set(prefix "${DDS_INSTALL_PREFIX}")
|
||||
elseif(${dep} STREQUAL Boost)
|
||||
if(TARGET Boost::headers)
|
||||
get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
@@ -296,10 +349,22 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
get_target_property(doxygen_bin Doxygen::doxygen INTERFACE_LOCATION)
|
||||
get_filename_component(prefix ${doxygen_bin} DIRECTORY)
|
||||
get_filename_component(prefix ${prefix}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL fmt)
|
||||
get_target_property(fmt_include fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_filename_component(prefix ${fmt_include}/.. ABSOLUTE)
|
||||
elseif(${dep} STREQUAL Flatbuffers)
|
||||
if(TARGET flatbuffers::flatbuffers)
|
||||
get_target_property(flatbuffers_include flatbuffers::flatbuffers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
else()
|
||||
get_target_property(flatbuffers_include flatbuffers::flatbuffers_shared INTERFACE_INCLUDE_DIRECTORIES)
|
||||
endif()
|
||||
get_filename_component(prefix ${flatbuffers_include}/.. ABSOLUTE)
|
||||
else()
|
||||
get_filename_component(prefix ${${dep}_INCLUDE_DIR}/.. ABSOLUTE)
|
||||
endif()
|
||||
if(NOT ${dep}_BUNDLED)
|
||||
message(STATUS " ${BWhite}${dep_padded}${CR}${version_padded}${prefix}")
|
||||
endif()
|
||||
unset(version_str)
|
||||
unset(version_padded)
|
||||
unset(version_req_str)
|
||||
@@ -355,6 +420,18 @@ else()
|
||||
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
|
||||
if(BUILD_SDK)
|
||||
set(sdk_summary "${BGreen}YES${CR} EXPERIMENTAL (required C++14) (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
|
||||
else()
|
||||
set(sdk_summary "${BRed} NO${CR} EXPERIMENTAL (required C++14) (default, enable with ${BMagenta}-DBUILD_SDK=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}sdk${CR} ${sdk_summary}")
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
set(sdk_commands_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_SDK_COMMANDS=OFF${CR})")
|
||||
else()
|
||||
set(sdk_commands_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_SDK_COMMANDS=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}sdk_commands${CR} ${sdk_commands_summary}")
|
||||
message(STATUS " ")
|
||||
if(RUN_STATIC_ANALYSIS)
|
||||
list(LENGTH PROJECT_STATIC_ANALYSERS size)
|
||||
@@ -376,6 +453,8 @@ if(RUN_STATIC_ANALYSIS)
|
||||
else()
|
||||
set(static_ana_summary "${BRed}OFF${CR} (default, enable with ${BMagenta}-DRUN_STATIC_ANALYSIS=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX}${CR} (change with ${BMagenta}-DCMAKE_INSTALL_PREFIX=...${CR})")
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}")
|
||||
message(STATUS " ")
|
||||
################################################################################
|
||||
|
69
COPYRIGHT
69
COPYRIGHT
@@ -4,9 +4,9 @@ Upstream-Contact: Mohammad Al-Turany <m.al-turany@gsi.de>
|
||||
Source: https://github.com/FairRootGroup/FairMQ
|
||||
|
||||
Files: *
|
||||
Copyright: 2012-2018, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
Copyright: 2012-2018, [see AUTHORS file]
|
||||
Copyright: 2012-2018, [see CONTRIBUTORS file]
|
||||
Copyright: 2012-2019, GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
Copyright: 2012-2019, [see AUTHORS file]
|
||||
Copyright: 2012-2019, [see CONTRIBUTORS file]
|
||||
Comment: The copyright of individual contributors is documented in the
|
||||
Git history.
|
||||
License: LGPL-3.0-only
|
||||
@@ -15,6 +15,14 @@ Files: cmake/cotire.cmake
|
||||
Copyright: 2012-2018 Sascha Kratky
|
||||
License: COTIRE
|
||||
|
||||
Files: extern/googletest
|
||||
Copyright: 2008, Google Inc.
|
||||
License: GOOGLE
|
||||
|
||||
Files: extern/asio
|
||||
Copyright: 2003-2019, Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
License: BSL-1.0
|
||||
|
||||
License: LGPL-3.0-only
|
||||
[see LICENSE file]
|
||||
|
||||
@@ -39,3 +47,58 @@ License: COTIRE
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
License: GOOGLE
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: BSL-1.0
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
@@ -29,6 +29,8 @@ 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}")
|
||||
|
||||
@@ -42,6 +44,7 @@ If($ENV{ctest_model} MATCHES Profile)
|
||||
If(GCOV_COMMAND)
|
||||
Message("Found GCOV: ${GCOV_COMMAND}")
|
||||
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
|
||||
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
|
||||
EndIf(GCOV_COMMAND)
|
||||
EndIf()
|
||||
|
||||
@@ -59,17 +62,9 @@ Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
|
||||
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
# PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
PARALLEL_LEVEL 1
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
RETURN_VALUE _ctest_test_ret_val
|
||||
)
|
||||
If("$ENV{do_codecov_upload}")
|
||||
ForEach(i RANGE 4)
|
||||
# Gather statistics to catch time sensitive branches
|
||||
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
)
|
||||
EndForEach()
|
||||
EndIf()
|
||||
|
||||
If(GCOV_COMMAND)
|
||||
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS coverage)
|
||||
|
16
Jenkinsfile
vendored
16
Jenkinsfile
vendored
@@ -22,11 +22,11 @@ def jobMatrix(String prefix, List specs, Closure callback) {
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc8/) {
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/8" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
@@ -49,6 +49,10 @@ def jobMatrix(String prefix, List specs, Closure callback) {
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
|
||||
} catch (e) {
|
||||
def tarball = "${prefix}_${label}_dds_logs.tar.gz"
|
||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
|
||||
archiveArtifacts tarball
|
||||
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
|
||||
throw e
|
||||
@@ -65,16 +69,16 @@ pipeline{
|
||||
stage("Run CI Matrix") {
|
||||
steps{
|
||||
script {
|
||||
def build_jobs = jobMatrix('alfa-ci/build', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
|
||||
def build_jobs = jobMatrix('build', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
sh './Dart.sh alfa_ci Dart.cfg'
|
||||
}
|
||||
|
||||
def profile_jobs = jobMatrix('alfa-ci/codecov', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
|
||||
def profile_jobs = jobMatrix('codecov', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
withCredentials([string(credentialsId: 'fairmq_codecov_token', variable: 'CODECOV_TOKEN')]) {
|
||||
sh './Dart.sh codecov Dart.cfg'
|
||||
|
@@ -21,11 +21,11 @@ def buildMatrix(List specs, Closure callback) {
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc8/) {
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/8" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
@@ -46,6 +46,10 @@ def buildMatrix(List specs, Closure callback) {
|
||||
|
||||
deleteDir()
|
||||
} catch (e) {
|
||||
def tarball = "${label}_dds_logs.tar.gz"
|
||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test/ .DDS/"
|
||||
archiveArtifacts tarball
|
||||
|
||||
deleteDir()
|
||||
throw e
|
||||
}
|
||||
@@ -63,7 +67,7 @@ pipeline{
|
||||
steps{
|
||||
script {
|
||||
parallel(buildMatrix([
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc8.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
|
63
README.md
63
README.md
@@ -33,25 +33,21 @@ configuration and control services.
|
||||
FairMQ has been developed in the context of its mother project [FairRoot](https://github.com/FairRootGroup/FairRoot) -
|
||||
a simulation, reconstruction and analysis framework.
|
||||
|
||||
## Dependencies
|
||||
|
||||
* PUBLIC: [**Boost**](https://www.boost.org/), [**FairLogger**](https://github.com/FairRootGroup/FairLogger)
|
||||
* BUILD: [CMake](https://cmake.org/), [GTest](https://github.com/google/googletest), [Doxygen](http://www.doxygen.org/)
|
||||
* PRIVATE: [ZeroMQ](http://zeromq.org/), [Msgpack](https://msgpack.org/index.html), [nanomsg](http://nanomsg.org/),
|
||||
[asiofi](https://github.com/FairRootGroup/asiofi), [DDS](http://dds.gsi.de), [PMIx](https://pmix.org/)
|
||||
|
||||
Supported platforms: Linux and MacOS.
|
||||
|
||||
## Installation from Source
|
||||
|
||||
Recommended:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/FairRootGroup/FairMQ fairmq
|
||||
mkdir fairmq_build && cd fairmq_build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=./fairmq_install ../fairmq
|
||||
cmake --build . --target install
|
||||
git clone https://github.com/FairRootGroup/FairMQ fairmq_source
|
||||
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=fairmq_install
|
||||
cmake --build fairmq_build
|
||||
cd fairmq_build; ctest -j4; cd ..
|
||||
cmake --build fairmq_build --target install
|
||||
```
|
||||
|
||||
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `MSGPACK`, `NANOMSG`, `OFI`, `PMIX`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
|
||||
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
|
||||
|
||||
If dependencies are not installed in standard system directories, you can hint the installation location via `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...`. `{DEPENDENCY}` can be `GTEST`, `BOOST`, `FAIRLOGGER`, `ZEROMQ`, `MSGPACK`, `NANOMSG`, `OFI`, `PMIX`, `ASIO`, `ASIOFI` or `DDS` (`*_ROOT` variables can also be environment variables).
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -70,30 +66,50 @@ find_package(FairMQ)
|
||||
|
||||
`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ`.
|
||||
|
||||
In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies, too.
|
||||
In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies:
|
||||
|
||||
```cmake
|
||||
find_package(FairMQ)
|
||||
if(FairMQ_FOUND)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_Boost_COMPONENTS})
|
||||
foreach(dep IN LISTS FairMQ_PACKAGE_DEPENDENCIES)
|
||||
if(FairMQ_${dep}_COMPONENTS)
|
||||
find_package(${dep} ${FairMQ_${dep}_VERSION} COMPONENTS ${FairMQ_${dep}_COMPONENTS})
|
||||
else()
|
||||
find_package(${dep} ${FairMQ_${dep}_VERSION})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
```
|
||||
|
||||
Of course, feel free to customize the above commands to your needs.
|
||||
If your project shares a dependency with FairMQ or if you want to omit a certain dependency, you may want to customize the above example code to your needs.
|
||||
|
||||
Optionally, you can require certain FairMQ package components and a minimum version:
|
||||
|
||||
```cmake
|
||||
find_package(FairMQ 1.1.0 COMPONENTS nanomsg_transport dds_plugin)
|
||||
if(FairMQ_FOUND)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_Boost_COMPONENTS})
|
||||
endif()
|
||||
```
|
||||
|
||||
When building FairMQ, CMake will print a summary table of all available package components.
|
||||
|
||||
## Dependencies
|
||||
|
||||
* [asio](https://github.com/chriskohlhoff/asio) (optionally bundled)
|
||||
* [asiofi](https://github.com/FairRootGroup/asiofi)
|
||||
* [Boost](https://www.boost.org/)
|
||||
* [CMake](https://cmake.org/)
|
||||
* [DDS](http://dds.gsi.de)
|
||||
* [Doxygen](http://www.doxygen.org/)
|
||||
* [FairLogger](https://github.com/FairRootGroup/FairLogger)
|
||||
* [GTest](https://github.com/google/googletest) (optionally bundled)
|
||||
* [Msgpack](https://msgpack.org/index.html)
|
||||
* [nanomsg](http://nanomsg.org/)
|
||||
* [PMIx](https://pmix.org/)
|
||||
* [ZeroMQ](http://zeromq.org/)
|
||||
|
||||
Which dependencies are required depends on which components are built.
|
||||
|
||||
Supported platforms: Linux and MacOS.
|
||||
|
||||
## CMake options
|
||||
|
||||
On command line:
|
||||
@@ -106,7 +122,7 @@ On command line:
|
||||
* `-DBUILD_DDS_PLUGIN=ON` enables building of the DDS plugin.
|
||||
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
|
||||
* `-DBUILD_DOCS=ON` enables building of API docs.
|
||||
* You can hint non-system installations for dependent packages, see the #Installation section above
|
||||
* You can hint non-system installations for dependent packages, see the #installation-from-source section above
|
||||
|
||||
After the `find_package(FairMQ)` call the following CMake variables are defined:
|
||||
|
||||
@@ -165,4 +181,5 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
|
||||
3. [Provided Plugins](docs/Plugins.md#73-provided-plugins)
|
||||
1. [DDS](docs/Plugins.md#731-dds)
|
||||
2. [PMIx](docs/Plugins.md#732-pmix)
|
||||
8. [Controller SDK](docs/SDK.md)
|
||||
|
||||
|
@@ -13,12 +13,12 @@ set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
set(@PROJECT_NAME@_GIT_VERSION @PROJECT_GIT_VERSION@)
|
||||
set(@PROJECT_NAME@_GIT_DATE @PROJECT_GIT_DATE@)
|
||||
|
||||
set_and_check(@PROJECT_NAME@_PREFIX @PACKAGE_CMAKE_INSTALL_PREFIX@)
|
||||
set_and_check(@PROJECT_NAME@_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_BINDIR@)
|
||||
set_and_check(@PROJECT_NAME@_INCDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@)
|
||||
set_and_check(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR@)
|
||||
set_and_check(@PROJECT_NAME@_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_DATADIR@)
|
||||
set_and_check(@PROJECT_NAME@_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_CMAKEMODDIR@)
|
||||
set(@PROJECT_NAME@_PREFIX @PACKAGE_CMAKE_INSTALL_PREFIX@)
|
||||
set(@PROJECT_NAME@_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_BINDIR@)
|
||||
set(@PROJECT_NAME@_INCDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@)
|
||||
set(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR@)
|
||||
set(@PROJECT_NAME@_DATADIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_DATADIR@)
|
||||
set(@PROJECT_NAME@_CMAKEMODDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_CMAKEMODDIR@)
|
||||
|
||||
set(@PROJECT_NAME@_CXX_STANDARD_REQUIRED @CMAKE_CXX_STANDARD_REQUIRED@)
|
||||
set(@PROJECT_NAME@_CXX_STANDARD @CMAKE_CXX_STANDARD@)
|
||||
@@ -36,4 +36,6 @@ set(CMAKE_MODULE_PATH ${@PROJECT_NAME@_CMAKEMODDIR} ${CMAKE_MODULE_PATH})
|
||||
### Import targets
|
||||
include(@PACKAGE_CMAKE_INSTALL_PREFIX@/@PACKAGE_INSTALL_DESTINATION@/@PROJECT_EXPORT_SET@.cmake)
|
||||
|
||||
@BUNDLED_PACKAGES@
|
||||
|
||||
@PACKAGE_COMPONENTS@
|
||||
|
@@ -176,7 +176,7 @@ macro(set_fairmq_defaults)
|
||||
set(analyser "clang-tidy")
|
||||
find_program(${analyser}_FOUND "${analyser}")
|
||||
if(${analyser}_FOUND)
|
||||
set(CMAKE_CXX_CLANG_TIDY "${${analyser}_FOUND}" "-color")
|
||||
set(CMAKE_CXX_CLANG_TIDY "${${analyser}_FOUND}")
|
||||
endif()
|
||||
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
|
||||
|
||||
@@ -194,6 +194,13 @@ macro(set_fairmq_defaults)
|
||||
endif()
|
||||
list(APPEND PROJECT_STATIC_ANALYSERS "${analyser}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR STREQUAL Ninja AND ENABLE_CCACHE)
|
||||
find_program(CCACHE ccache)
|
||||
if(CCACHE)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(join VALUES GLUE OUTPUT)
|
||||
@@ -266,13 +273,30 @@ check_required_components(${PROJECT_NAME})
|
||||
set(PACKAGE_COMPONENTS ${PACKAGE_COMPONENTS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(generate_bundled_packages)
|
||||
if(asio_BUNDLED)
|
||||
set(BUNDLED_PACKAGES "\
|
||||
####### Expanded from @BUNDLED_PACKAGES@ by configure_package_config_file() #########
|
||||
|
||||
if(\"\${CMAKE_MAJOR_VERSION}.\${CMAKE_MINOR_VERSION}\" VERSION_LESS 3.11)
|
||||
message(FATAL_ERROR \"CMake >= 3.11 required\")
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME}::bundled_asio_headers PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(asio::headers ALIAS ${PROJECT_NAME}::bundled_asio_headers)
|
||||
set(asio_VERSION ${asio_VERSION})
|
||||
|
||||
")
|
||||
endif()
|
||||
set(BUNDLED_PACKAGES ${BUNDLED_PACKAGES} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Configure/Install CMake package
|
||||
macro(install_cmake_package)
|
||||
list(SORT PROJECT_PACKAGE_DEPENDENCIES)
|
||||
list(SORT PROJECT_INTERFACE_PACKAGE_DEPENDENCIES)
|
||||
include(CMakePackageConfigHelpers)
|
||||
set(PACKAGE_INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_GIT_VERSION}
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
|
||||
)
|
||||
if(BUILD_FAIRMQ)
|
||||
install(EXPORT ${PROJECT_EXPORT_SET}
|
||||
@@ -288,6 +312,7 @@ macro(install_cmake_package)
|
||||
)
|
||||
generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES}
|
||||
generate_package_components() # fills ${PACKAGE_COMPONENTS}
|
||||
generate_bundled_packages() # fills ${BUNDLED_PACKAGES}
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} PROJECT_BUILD_TYPE_UPPER)
|
||||
set(PROJECT_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${PROJECT_BUILD_TYPE_UPPER}})
|
||||
configure_package_config_file(
|
||||
@@ -312,10 +337,11 @@ endmacro()
|
||||
#
|
||||
# Wrapper around CMake's native find_package command to add some features and bookkeeping.
|
||||
#
|
||||
# The qualifier (PRIVATE|PUBLIC|INTERFACE) to the package to populate
|
||||
# The qualifier (PRIVATE|PUBLIC|INTERFACE|BUNDLED) to the package to populate
|
||||
# the variables PROJECT_[INTERFACE]_<pkgname>_([VERSION]|[COMPONENTS]|PACKAGE_DEPENDENCIES)
|
||||
# accordingly. This bookkeeping information is used to print our dependency found summary
|
||||
# table and to generate a part of our CMake package.
|
||||
# table and to generate a part of our CMake package. BUNDLED decays to PUBLIC if the variable
|
||||
# <pkgname>_BUNDLED is false and to PRIVATE otherwise.
|
||||
#
|
||||
# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables
|
||||
# <dep_pkgname>_<pkgname>_VERSION|COMPONENTS are looked up to and added to the native
|
||||
@@ -372,28 +398,149 @@ macro(find_package2 qualifier pkgname)
|
||||
find_package(${pkgname} ${__version__} QUIET ${ARGS_UNPARSED_ARGUMENTS})
|
||||
endif()
|
||||
|
||||
if(${qualifier} STREQUAL BUNDLED)
|
||||
if(${pkgname}_BUNDLED)
|
||||
set(__qualifier__ PRIVATE)
|
||||
else()
|
||||
set(__qualifier__ PUBLIC)
|
||||
endif()
|
||||
else()
|
||||
set(__qualifier__ ${qualifier})
|
||||
endif()
|
||||
|
||||
if(${pkgname}_FOUND)
|
||||
if(${qualifier} STREQUAL PRIVATE)
|
||||
if(${__qualifier__} STREQUAL PRIVATE)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${__components__})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL PUBLIC)
|
||||
elseif(${__qualifier__} STREQUAL PUBLIC)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${__components__})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL INTERFACE)
|
||||
elseif(${__qualifier__} STREQUAL INTERFACE)
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${__components__})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
unset(__qualifier__)
|
||||
unset(__version__)
|
||||
unset(__components__)
|
||||
unset(__required_versions__)
|
||||
set(CMAKE_PREFIX_PATH ${__old_cpp__})
|
||||
unset(__old_cpp__)
|
||||
endmacro()
|
||||
|
||||
macro(exec cmd)
|
||||
join("${ARGN}" " " args)
|
||||
file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n")
|
||||
|
||||
execute_process(COMMAND ${cmd} ${ARGN}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
OUTPUT_VARIABLE log
|
||||
ERROR_VARIABLE log
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
file(APPEND ${${package}_BUILD_LOGFILE} ${log})
|
||||
|
||||
if(res)
|
||||
message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(exec_source cmd)
|
||||
join("${ARGN}" " " args)
|
||||
file(APPEND ${${package}_BUILD_LOGFILE} ">>> ${cmd} ${args}\n")
|
||||
|
||||
execute_process(COMMAND ${cmd} ${ARGN}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE log
|
||||
ERROR_VARIABLE log
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
file(APPEND ${${package}_BUILD_LOGFILE} ${log})
|
||||
|
||||
if(res)
|
||||
message(FATAL_ERROR "${res} \nSee also \"${${package}_BUILD_LOGFILE}\"")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(build_bundled package bundle)
|
||||
message(STATUS "Building bundled ${package}")
|
||||
|
||||
set(${package}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${bundle})
|
||||
set(${package}_BINARY_DIR ${CMAKE_BINARY_DIR}/${bundle})
|
||||
file(MAKE_DIRECTORY ${${package}_BINARY_DIR})
|
||||
set(${package}_BUILD_LOGFILE ${${package}_BINARY_DIR}/build.log)
|
||||
file(REMOVE ${${package}_BUILD_LOGFILE})
|
||||
|
||||
if(Git_FOUND)
|
||||
exec_source(${GIT_EXECUTABLE} submodule update --init -- ${${package}_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(${package} STREQUAL GTest)
|
||||
set(${package}_INSTALL_DIR ${CMAKE_BINARY_DIR}/${bundle}_install)
|
||||
file(MAKE_DIRECTORY ${${package}_INSTALL_DIR})
|
||||
set(${package}_ROOT ${${package}_INSTALL_DIR})
|
||||
|
||||
exec(${CMAKE_COMMAND} -S ${${package}_SOURCE_DIR} -B ${${package}_BINARY_DIR} -G ${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${${package}_INSTALL_DIR} -DBUILD_GMOCK=OFF
|
||||
)
|
||||
exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR})
|
||||
exec(${CMAKE_COMMAND} --build ${${package}_BINARY_DIR} --target install)
|
||||
elseif(${package} STREQUAL asio)
|
||||
set(${package}_BUILD_INCLUDE_DIR ${${package}_SOURCE_DIR}/asio/include CACHE PATH "Bundled ${package} build-interface include dir")
|
||||
set(${package}_INSTALL_INCLUDE_DIR ${PROJECT_INSTALL_INCDIR}/bundled CACHE PATH "Bundled ${package} install-interface include dir")
|
||||
set(${package}_ROOT ${${package}_SOURCE_DIR}/asio)
|
||||
endif()
|
||||
|
||||
string(TOUPPER ${package} package_upper)
|
||||
set(${package_upper}_ROOT "${${package}_ROOT}" CACHE PATH "Bundled ${package} install prefix search hint")
|
||||
set(${package}_BUNDLED ON CACHE BOOL "Whether bundled ${package} was used")
|
||||
|
||||
message(STATUS "Building bundled ${package} - done")
|
||||
endfunction()
|
||||
|
||||
macro(fairmq_build_option option description)
|
||||
cmake_parse_arguments(ARGS "" "DEFAULT" "REQUIRES" ${ARGN})
|
||||
|
||||
if(ARGS_DEFAULT)
|
||||
set(__default__ ON)
|
||||
else()
|
||||
set(__default__ OFF)
|
||||
endif()
|
||||
|
||||
if(ARGS_REQUIRES)
|
||||
include(CMakeDependentOption)
|
||||
set(__requires__ ${ARGS_REQUIRES})
|
||||
foreach(d ${__requires__})
|
||||
string(REGEX REPLACE " +" ";" __requires_condition__ "${d}")
|
||||
if(${__requires_condition__})
|
||||
else()
|
||||
if(${option})
|
||||
message(WARNING "Cannot enable build option ${option}, depending option is not set: ${__requires_condition__}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(__requires__)
|
||||
endif()
|
||||
|
||||
if(__requires__)
|
||||
cmake_dependent_option(${option} ${description} ${__default__} "${__requires__}" OFF)
|
||||
else()
|
||||
option(${option} ${description} ${__default__})
|
||||
endif()
|
||||
|
||||
set(__default__)
|
||||
set(__requires__)
|
||||
set(__requires_condition__)
|
||||
set(ARGS_DEFAULT)
|
||||
set(ARGS_REQUIRES)
|
||||
set(option)
|
||||
set(description)
|
||||
endmacro()
|
||||
|
53
cmake/Findasio.cmake
Normal file
53
cmake/Findasio.cmake
Normal file
@@ -0,0 +1,53 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
find_path(asio_INCLUDE_DIR
|
||||
NAMES asio.hpp
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
if(asio_INCLUDE_DIR)
|
||||
find_file(asio_VERSION_HEADER "asio/version.hpp"
|
||||
${asio_INCLUDE_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
|
||||
if(asio_VERSION_HEADER)
|
||||
file(READ "${asio_VERSION_HEADER}" _asio_VERSION_HEADER_CONTENT)
|
||||
string(REGEX MATCH "#define ASIO_VERSION ([0-9]+)" _MATCH "${_asio_VERSION_HEADER_CONTENT}")
|
||||
set(asio_VERSION_MACRO ${CMAKE_MATCH_1})
|
||||
math(EXPR asio_VERSION_MAJOR "${asio_VERSION_MACRO} / 100000")
|
||||
math(EXPR asio_VERSION_MINOR "${asio_VERSION_MACRO} / 100 % 1000")
|
||||
math(EXPR asio_VERSION_PATCH "${asio_VERSION_MACRO} % 100")
|
||||
set(asio_VERSION "${asio_VERSION_MAJOR}.${asio_VERSION_MINOR}.${asio_VERSION_PATCH}")
|
||||
endif()
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(asio
|
||||
REQUIRED_VARS asio_INCLUDE_DIR
|
||||
VERSION_VAR asio_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
if(asio_FOUND AND asio_BUNDLED)
|
||||
add_library(bundled_asio_headers INTERFACE)
|
||||
target_include_directories(bundled_asio_headers INTERFACE
|
||||
$<BUILD_INTERFACE:${asio_BUILD_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:${asio_INSTALL_INCLUDE_DIR}>
|
||||
)
|
||||
add_library(asio::headers ALIAS bundled_asio_headers)
|
||||
endif()
|
||||
if(asio_FOUND AND NOT TARGET asio::headers)
|
||||
add_library(asio::headers INTERFACE IMPORTED)
|
||||
set_target_properties(asio::headers PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${asio_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
@@ -4,7 +4,37 @@
|
||||
|
||||
## 3.1 Device Configuration
|
||||
|
||||
Devices receive configuration primarily via provided command line options (that can be extended per device).
|
||||
Device Configuration is stored in configuration object - `fair::mq::ProgOptions`. It is accessible by the device, plugins or from DeviceRunner/main:
|
||||
|
||||
Plugins <---read/write---> ProgOptions <---read/write---> Device
|
||||
|
||||
Whenever a configuration property is set, it is set in ProgOptions. Device/Channels/User code read this value and apply it as necessary at different stages:
|
||||
- apply it immidiately
|
||||
- apply it in device/channels during InitializingDevice/Binding/Connecting states
|
||||
|
||||
Here is an overview of the device/channel options and when they are applied:
|
||||
|
||||
| Property | Applied in |
|
||||
| --- | --- |
|
||||
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `file-severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `verbosity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `color` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `log-to-file` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
||||
| `id` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `io-threads` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `transport` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `network-interface` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `init-timeout` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `max-run-time` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `shm-segment-size` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `shm-monitor` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `ofi-size-hint` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `rate` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `session` | at the end of `fair::mq::State::InitializingDevice` |
|
||||
| `chan.*` | at the end of `fair::mq::State::InitializingDevice` (channel addresses can be also applied during `fair::mq::State::Binding`/`fair::mq::State::Connecting`) |
|
||||
|
||||
## 3.2 Configuration options
|
||||
|
||||
## 3.2 Communication Channels Configuration
|
||||
|
||||
@@ -32,6 +62,14 @@ This parser reads channel configuration from a JSON file. Example:
|
||||
"address": "tcp://*:5555",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"sndKernelSize" : 0,
|
||||
"rcvKernelSize" : 0,
|
||||
"transport": "shmem",
|
||||
"linger": "500",
|
||||
"portRangeMin": "22000",
|
||||
"portRangeMax": "23000",
|
||||
"autoBind": false,
|
||||
"numSockets": 0,
|
||||
"rateLogging": 1
|
||||
}
|
||||
]
|
||||
@@ -48,9 +86,7 @@ This parser reads channel configuration from a JSON file. Example:
|
||||
"type": "pull",
|
||||
"method": "connect",
|
||||
"address": "tcp://localhost:5555",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
"transport": "shmem"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -48,6 +48,6 @@ Without the interactive mode, for example for a run in background, two other con
|
||||
|
||||
## 1.4 Multiple devices in the same process
|
||||
|
||||
Technically one can create two or more devices within the same process without any conflicts. However the configuration (FairMQProgOptions) currently assumes the supplied configuration values are for one device/process.
|
||||
Technically one can create two or more devices within the same process without any conflicts. However the configuration (fair::mq::ProgOptions) currently assumes the supplied configuration values are for one device/process.
|
||||
|
||||
← [Back](../README.md)
|
||||
|
34
docs/SDK.md
Normal file
34
docs/SDK.md
Normal file
@@ -0,0 +1,34 @@
|
||||
← [Back](../README.md)
|
||||
|
||||
# 8. Controller SDK
|
||||
|
||||
The FairMQ Controller Software Development Kit (`-DBUILD_SDK=ON`) contains a (as of today still experimental) set of C++ APIs that provide essential functionality to the implementer of a global controller.
|
||||
|
||||
The FairMQ core library only provides two local controllers - `static` (a fixed sequence of state transitions) and `interactive` (a read-eval-print-loop which reads keyboard commands from standard input). A local controller only knows how steer a single [FairMQ device](Device.md) - in fact, it runs in a thread within the device process.
|
||||
|
||||
A global controller has knowledge about the full topology of connected FairMQ devices. Its responsibility is to facilitate the lifecycle of a distributed FairMQ-based application (*executing a topology*), such as
|
||||
|
||||
* allocating/releasing compute resources from a resource management system,
|
||||
* launching/setting up the run-time environment and the FairMQ devices,
|
||||
* driving the device state machines in lock-step across the full topology,
|
||||
* pushing the device configuration,
|
||||
* monitoring (some aspects of the application's) operation,
|
||||
* and handling/reporting (some) error cases.
|
||||
|
||||
The low-level hook to integrate FairMQ devices with such a global contoller is the [plugin mechanism](Plugins.md) in the FairMQ core library. The FairMQ Controller SDK provides C++ APIs that communicate to the endpoints exposed by such a FairMQ plugin.
|
||||
|
||||
At the moment, the Controller SDK only supports [DDS](https://dds.gsi.de) as resource manager and run-time environment. A second implementation based on [PMIx](https://pmix.org/) (targeting its implementation in [Slurm](https://slurm.schedmd.com/documentation.html) and [OpenRTE](https://www-lb.open-mpi.org/papers/euro-pvmmpi-2005-orte/)) is in development.
|
||||
|
||||
The following section give a short overview on the APIs provided.
|
||||
|
||||
## RMS and run-time environment
|
||||
|
||||
The classes [`fair::mq::sdk::DDSEnvironment`](../fairmq/sdk/DDSEnvironment.h), [`fair::mq::sdk::DDSSession`](../fairmq/sdk/DDSSession.h), and [`fair::mq::sdk::DDSTopology`](../fairmq/sdk/DDSTopology.h) are thin wrappers of most of the synchronous APIs exposed by DDS ([`dds::tools_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1tools__api.html) and [`dds::topology_api`](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1topology__api.html)). E.g. they allow to [start a DDS session](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L26-L28), [allocate resources](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L34) and [launch a topology](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L39) from a C++ program.
|
||||
|
||||
## Driving the global state machine
|
||||
|
||||
The class [`fair::mq::sdk::Topology`](../fairmq/sdk/Topology.h) adds a FairMQ-specific view on an existing DDS session that is executing a topology of FairMQ devices. One can e.g. [initiate a state transition on all devices in the topology simultaneously](https://github.com/FairRootGroup/FairMQ/blob/077eb0ef691940d764cfd1852bf3981dc812ddbd/main.cpp#L48-L49). This topology transition completes once a topology-wide barrier is passed (all devices completed the transition). This effectively exposes the device state machine as a topology state machine. The implementation is based on remote procedure calls over the [DDS intercom service](http://dds.gsi.de/doc/api-docs/DDS/html/namespacedds_1_1intercom__api.html) between the controller and the DDS plugin shipped with FairMQ (`-DBUILD_DDS_PLUGIN=ON`).
|
||||
|
||||
For future versions of the SDK new APIs are planned to inspect and modify the device configurations and also operate only on subsets of a given topology.
|
||||
|
||||
← [Back](../README.md)
|
@@ -6,9 +6,6 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <thread> // this_thread::sleep_for
|
||||
#include <chrono>
|
||||
|
||||
#include "Sampler.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -26,8 +23,8 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
// Get the fText and fMaxIterations values from the command line options (via fConfig)
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
|
@@ -30,7 +30,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_1::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_1::Sink();
|
||||
}
|
||||
|
@@ -32,8 +32,8 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
// Get the fText and fMaxIterations values from the command line options (via fConfig)
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
|
@@ -30,7 +30,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Processor();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_1_n_1::Sink();
|
||||
}
|
||||
|
@@ -33,12 +33,11 @@ Sampler::Sampler()
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fNumDataChannels = fChannels.at("data").size();
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
{
|
||||
|
||||
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
|
||||
// Should only be used for small data because of the cost of an additional copy
|
||||
FairMQMessagePtr msg(NewSimpleMessage(fCounter++));
|
||||
|
@@ -27,7 +27,7 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_copypush::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_copypush::Sink();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2014-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
@@ -28,14 +28,29 @@ target_link_libraries(fairmq-ex-dds-sink PRIVATE ExampleDDSLib)
|
||||
|
||||
add_custom_target(ExampleDDS DEPENDS fairmq-ex-dds-sampler fairmq-ex-dds-processor fairmq-ex-dds-sink)
|
||||
|
||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(DDS_PLUGIN_LIB_DIR ${CMAKE_BINARY_DIR}/fairmq/plugins/DDS)
|
||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml @ONLY)
|
||||
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)
|
||||
set(DATA_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-hosts.cfg ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh @ONLY)
|
||||
|
||||
# test
|
||||
if(DDS_FOUND)
|
||||
add_test(NAME Example.DDS.localhost COMMAND ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh localhost)
|
||||
set_tests_properties(Example.DDS.localhost PROPERTIES
|
||||
TIMEOUT 15
|
||||
RUN_SERIAL true
|
||||
PASS_REGULAR_EXPRESSION "Example successful"
|
||||
)
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
@@ -50,10 +65,12 @@ install(
|
||||
)
|
||||
|
||||
# configure run script with different executable paths for build and for install directories
|
||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
||||
set(DDS_PLUGIN_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR})
|
||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||
set(BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
||||
set(DATA_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-dds-topology-infinite.xml ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology-infinite.xml_install @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-ex-dds-env.sh ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-dds.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install @ONLY)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-topology.xml_install
|
||||
@@ -61,7 +78,25 @@ install(
|
||||
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
|
||||
)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-dds-hosts.cfg
|
||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-ex-dds-env.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-ex-dds-env.sh
|
||||
)
|
||||
|
||||
install(
|
||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-dds.sh_install
|
||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
RENAME fairmq-start-ex-dds.sh
|
||||
)
|
||||
|
@@ -26,10 +26,14 @@ Sampler::Sampler()
|
||||
{
|
||||
}
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fIterations = fConfig->GetValue<uint64_t>("iterations");
|
||||
fCounter = 0;
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
|
||||
// Should only be used for small data because of the cost of an additional copy
|
||||
FairMQMessagePtr msg(NewSimpleMessage("Data"));
|
||||
@@ -38,11 +42,18 @@ bool Sampler::ConditionalRun()
|
||||
|
||||
// in case of error or transfer interruption, return false to go to IDLE state
|
||||
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
|
||||
if (Send(msg, "data1") < 0)
|
||||
{
|
||||
if (Send(msg, "data1") < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fIterations > 0) {
|
||||
++fCounter;
|
||||
if (fCounter >= fIterations) {
|
||||
LOG(info) << "Sent " << fCounter << " messages. Finished.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -25,9 +25,14 @@ class Sampler : public FairMQDevice
|
||||
public:
|
||||
Sampler();
|
||||
virtual ~Sampler();
|
||||
void InitTask() override;
|
||||
|
||||
protected:
|
||||
virtual bool ConditionalRun();
|
||||
bool ConditionalRun() override;
|
||||
|
||||
private:
|
||||
uint64_t fIterations;
|
||||
uint64_t fCounter;
|
||||
};
|
||||
|
||||
} // namespace example_dds
|
||||
|
@@ -25,11 +25,24 @@ Sink::Sink()
|
||||
OnData("data2", &Sink::HandleData);
|
||||
}
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fIterations = fConfig->GetValue<uint64_t>("iterations");
|
||||
fCounter = 0;
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data2", with a reference to the message and a sub-channel index (here 0)
|
||||
bool Sink::HandleData(FairMQMessagePtr& msg, int /*index*/)
|
||||
{
|
||||
LOG(info) << "Received: \"" << string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
|
||||
|
||||
if (fIterations > 0) {
|
||||
++fCounter;
|
||||
if (fCounter >= fIterations) {
|
||||
LOG(info) << "Received " << fCounter << " messages. Finished.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// return true if want to be called again (otherwise go to IDLE state)
|
||||
return true;
|
||||
}
|
||||
|
@@ -25,9 +25,14 @@ class Sink : public FairMQDevice
|
||||
public:
|
||||
Sink();
|
||||
virtual ~Sink();
|
||||
void InitTask() override;
|
||||
|
||||
protected:
|
||||
bool HandleData(FairMQMessagePtr&, int);
|
||||
|
||||
private:
|
||||
uint64_t fIterations;
|
||||
uint64_t fCounter;
|
||||
};
|
||||
|
||||
} // namespace example_dds
|
||||
|
@@ -1,7 +1,3 @@
|
||||
@bash_begin@
|
||||
# source setup.sh
|
||||
@bash_end@
|
||||
|
||||
sampler, username@localhost, , /path/to/dds-work/, 1
|
||||
processor, username@localhost, , /path/to/dds-work/, 10
|
||||
sink, username@localhost, , /path/to/dds-work/, 1
|
||||
sampler, 127.0.0.1, , /tmp/fairmq-ex-dds, 1
|
||||
processor, 127.0.0.1, , /tmp/fairmq-ex-dds, 10
|
||||
sink, 127.0.0.1, , /tmp/fairmq-ex-dds, 1
|
||||
|
52
examples/dds/ex-dds-topology-infinite.xml
Normal file
52
examples/dds/ex-dds-topology-infinite.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<topology name="ExampleDDS">
|
||||
|
||||
<property name="fmqchan_data1" />
|
||||
<property name="fmqchan_data2" />
|
||||
|
||||
<declrequirement name="SamplerWorker" type="wnname" value="sampler"/>
|
||||
<declrequirement name="ProcessorWorker" type="wnname" value="processor"/>
|
||||
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
|
||||
|
||||
<decltask name="Sampler">
|
||||
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind --rate 100 -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SamplerWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">fmqchan_data1</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Processor">
|
||||
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>ProcessorWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="read">fmqchan_data1</name>
|
||||
<name access="read">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Sink">
|
||||
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SinkWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<main name="main">
|
||||
<task>Sampler</task>
|
||||
<task>Sink</task>
|
||||
<group name="ProcessorGroup" n="10">
|
||||
<task>Processor</task>
|
||||
</group>
|
||||
</main>
|
||||
|
||||
</topology>
|
@@ -1,40 +1,43 @@
|
||||
<topology name="ExampleDDS">
|
||||
|
||||
<property name="data1" />
|
||||
<property name="data2" />
|
||||
<property name="fmqchan_data1" />
|
||||
<property name="fmqchan_data2" />
|
||||
|
||||
<declrequirement name="SamplerWorker" type="wnname" value="sampler"/>
|
||||
<declrequirement name="ProcessorWorker" type="wnname" value="processor"/>
|
||||
<declrequirement name="SinkWorker" type="wnname" value="sink"/>
|
||||
|
||||
<decltask name="Sampler">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-sampler --id sampler --color false --channel-config name=data1,type=push,method=bind -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-sampler --color false --channel-config name=data1,type=push,method=bind -P dds --iterations 10</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SamplerWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">data1</name>
|
||||
<name access="write">fmqchan_data1</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Processor">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-processor --id processor_%taskIndex% --config-key processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-processor --color false --channel-config name=data1,type=pull,method=connect name=data2,type=push,method=connect -P dds</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>ProcessorWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="read">data1</name>
|
||||
<name access="read">data2</name>
|
||||
<name access="read">fmqchan_data1</name>
|
||||
<name access="read">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
<decltask name="Sink">
|
||||
<exe reachable="true">@EX_BIN_DIR@/fairmq-ex-dds-sink --id sink --color false --channel-config name=data2,type=pull,method=bind -S "<@DDS_PLUGIN_LIB_DIR@/" -P dds</exe>
|
||||
<exe>fairmq-ex-dds-sink --color false --channel-config name=data2,type=pull,method=bind -P dds --iterations 10</exe>
|
||||
<env reachable="false">fairmq-ex-dds-env.sh</env>
|
||||
<requirements>
|
||||
<name>SinkWorker</name>
|
||||
</requirements>
|
||||
<properties>
|
||||
<name access="write">data2</name>
|
||||
<name access="write">fmqchan_data2</name>
|
||||
</properties>
|
||||
</decltask>
|
||||
|
||||
|
11
examples/dds/fairmq-ex-dds-env.sh
Executable file
11
examples/dds/fairmq-ex-dds-env.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/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
|
89
examples/dds/fairmq-start-ex-dds.sh.in
Executable file
89
examples/dds/fairmq-start-ex-dds.sh.in
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
# fairmq-start-ex-dds.sh [localhost] -> submit agents with localhost plugin
|
||||
# fairmq-start-ex-dds.sh ssh -> submit agents with ssh plugin
|
||||
|
||||
set -e
|
||||
|
||||
cleanup() {
|
||||
dds-session stop $1
|
||||
echo "CLEANUP PERFORMED"
|
||||
}
|
||||
|
||||
source @DDS_INSTALL_PREFIX@/DDS_env.sh
|
||||
export PATH=@BIN_DIR@:$PATH
|
||||
|
||||
plugin=${1:-localhost}
|
||||
|
||||
exec 5>&1
|
||||
output=$(dds-session start | tee >(cat - >&5))
|
||||
export DDS_SESSION_ID=$(echo ${output} | grep "DDS session ID: " | cut -d' ' -f4)
|
||||
echo "SESSION ID: ${DDS_SESSION_ID}"
|
||||
|
||||
trap "cleanup ${DDS_SESSION_ID}" EXIT
|
||||
|
||||
requiredNofSlots=12
|
||||
if [[ "$plugin" == "ssh" ]]; then
|
||||
dds-submit -r ${plugin} -c @DATA_DIR@/ex-dds-hosts.cfg
|
||||
else
|
||||
dds-submit -r ${plugin} --slots ${requiredNofSlots}
|
||||
fi
|
||||
echo "...waiting for ${requiredNofSlots} slots..."
|
||||
@WAIT_COMMAND@ ${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})"
|
||||
|
||||
# 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 ${requiredNofSlots}
|
||||
sleep 1
|
||||
|
||||
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 ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c i -w "INITIALIZING DEVICE" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c k -w "INITIALIZED" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c b -w "BOUND" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c x -w "DEVICE READY" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c j -w "READY" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c r
|
||||
sampler_and_sink="main/(Sampler|Sink)"
|
||||
# processors="main/ProcessorGroup/Processor"
|
||||
fairmq-dds-command-ui -p $sampler_and_sink -w "RUNNING->READY" -n 2
|
||||
echo "...$sampler_and_sink are READY, sending shutdown..."
|
||||
fairmq-dds-command-ui -c s -w "RUNNING->READY" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c t -w "DEVICE READY" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c d -w "IDLE" -n ${requiredNofSlots}
|
||||
fairmq-dds-command-ui -c q -w "EXITING" -n ${requiredNofSlots}
|
||||
echo "...waiting for ${requiredNofSlots} slots..."
|
||||
@WAIT_COMMAND@ ${requiredNofSlots}
|
||||
echo "------------------------"
|
||||
|
||||
# TODO Uncomment once DDS 2.6 is released
|
||||
# dds-info --active-topology
|
||||
dds-topology --stop
|
||||
# dds-info --active-topology
|
||||
|
||||
dds-agent-cmd getlog -a
|
||||
logDir="${wrkDir}/logs"
|
||||
for file in $(find "${logDir}" -name "*.tar.gz"); do tar -xf ${file} -C "${logDir}" ; done
|
||||
echo "AGENT LOG FILES IN: ${logDir}"
|
||||
|
||||
# This string is used by ctest to detect success
|
||||
echo "Example successful :)"
|
||||
|
||||
# Cleanup function is called by EXIT trap
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Processor();
|
||||
}
|
||||
|
@@ -11,11 +11,15 @@
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
|
||||
void addCustomOptions(bpo::options_description& /*options*/)
|
||||
void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()(
|
||||
"iterations,i",
|
||||
bpo::value<uint64_t>()->default_value(1000),
|
||||
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Sampler();
|
||||
}
|
||||
|
@@ -11,11 +11,15 @@
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
|
||||
void addCustomOptions(bpo::options_description& /*options*/)
|
||||
void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()(
|
||||
"iterations,i",
|
||||
bpo::value<uint64_t>()->default_value(1000),
|
||||
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_dds::Sink();
|
||||
}
|
||||
|
@@ -32,19 +32,19 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMA
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh)
|
||||
|
||||
add_test(NAME Example.Multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh zeromq)
|
||||
set_tests_properties(Example.Multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 5 parts")
|
||||
set_tests_properties(Example.Multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example.Multipart.nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh nanomsg)
|
||||
set_tests_properties(Example.Multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 5 parts")
|
||||
set_tests_properties(Example.Multipart.nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example.Multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh shmem)
|
||||
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 5 parts")
|
||||
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
add_test(NAME Example.Multipart.ofi COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh ofi)
|
||||
set_tests_properties(Example.Multipart.ofi PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 5 parts")
|
||||
set_tests_properties(Example.Multipart.ofi PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
@@ -31,7 +31,7 @@ Sampler::Sampler()
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler::ConditionalRun()
|
||||
@@ -40,8 +40,7 @@ bool Sampler::ConditionalRun()
|
||||
header.stopFlag = 0;
|
||||
|
||||
// Set stopFlag to 1 for last message.
|
||||
if (fMaxIterations > 0 && fNumIterations == fMaxIterations - 1)
|
||||
{
|
||||
if (fMaxIterations > 0 && fNumIterations == fMaxIterations - 1) {
|
||||
header.stopFlag = 1;
|
||||
}
|
||||
LOG(info) << "Sending header with stopFlag: " << header.stopFlag;
|
||||
@@ -60,13 +59,20 @@ bool Sampler::ConditionalRun()
|
||||
assert(auxData.Size() == 0);
|
||||
assert(parts.Size() == 5);
|
||||
|
||||
parts.AddPart(NewMessage());
|
||||
|
||||
assert(parts.Size() == 6);
|
||||
|
||||
parts.AddPart(NewMessage(100));
|
||||
|
||||
assert(parts.Size() == 7);
|
||||
|
||||
LOG(info) << "Sending body of size: " << parts.At(1)->GetSize();
|
||||
|
||||
Send(parts, "data");
|
||||
|
||||
// Go out of the sending loop if the stopFlag was sent.
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
|
||||
{
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
return false;
|
||||
}
|
||||
@@ -77,8 +83,4 @@ bool Sampler::ConditionalRun()
|
||||
return true;
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace example_multipart
|
||||
|
@@ -24,7 +24,7 @@ class Sampler : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
Sampler();
|
||||
virtual ~Sampler();
|
||||
virtual ~Sampler() {}
|
||||
|
||||
protected:
|
||||
virtual void InitTask();
|
||||
|
@@ -20,23 +20,28 @@ using namespace std;
|
||||
namespace example_multipart
|
||||
{
|
||||
|
||||
Sink::Sink()
|
||||
{
|
||||
OnData("data", &Sink::HandleData);
|
||||
}
|
||||
|
||||
bool Sink::HandleData(FairMQParts& parts, int /*index*/)
|
||||
{
|
||||
LOG(info) << "Received message with " << parts.Size() << " parts";
|
||||
|
||||
Header header;
|
||||
header.stopFlag = (static_cast<Header*>(parts.At(0)->GetData()))->stopFlag;
|
||||
|
||||
LOG(info) << "Received message with " << parts.Size() << " parts";
|
||||
LOG(info) << "Received part 1 (header) with stopFlag: " << header.stopFlag;
|
||||
LOG(info) << "Received part 2 of size: " << parts.At(1)->GetSize();
|
||||
assert(parts.At(1)->GetSize() == 1000);
|
||||
LOG(info) << "Received part 3 of size: " << parts.At(2)->GetSize();
|
||||
assert(parts.At(2)->GetSize() == 500);
|
||||
LOG(info) << "Received part 4 of size: " << parts.At(3)->GetSize();
|
||||
assert(parts.At(3)->GetSize() == 600);
|
||||
LOG(info) << "Received part 5 of size: " << parts.At(4)->GetSize();
|
||||
assert(parts.At(4)->GetSize() == 700);
|
||||
LOG(info) << "Received part 6 of size: " << parts.At(5)->GetSize();
|
||||
assert(parts.At(5)->GetSize() == 0);
|
||||
LOG(info) << "Received part 7 of size: " << parts.At(6)->GetSize();
|
||||
assert(parts.At(6)->GetSize() == 100);
|
||||
|
||||
LOG(info) << "Received header with stopFlag: " << header.stopFlag;
|
||||
LOG(info) << "Received body of size: " << parts.At(1)->GetSize();
|
||||
|
||||
if (header.stopFlag == 1)
|
||||
{
|
||||
if (header.stopFlag == 1) {
|
||||
LOG(info) << "stopFlag is 1, going IDLE";
|
||||
return false;
|
||||
}
|
||||
@@ -44,8 +49,4 @@ bool Sink::HandleData(FairMQParts& parts, int /*index*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
Sink::~Sink()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -23,8 +23,8 @@ namespace example_multipart
|
||||
class Sink : public FairMQDevice
|
||||
{
|
||||
public:
|
||||
Sink();
|
||||
virtual ~Sink();
|
||||
Sink() { OnData("data", &Sink::HandleData); }
|
||||
virtual ~Sink() {}
|
||||
|
||||
protected:
|
||||
bool HandleData(FairMQParts&, int);
|
||||
|
@@ -2,12 +2,24 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
||||
|
||||
SAMPLER="fairmq-ex-multipart-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --session $SESSION"
|
||||
SAMPLER+=" --channel-config name=data,type=push,method=connect,rateLogging=0,address=tcp://127.0.0.1:5555"
|
||||
xterm -geometry 80x23+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
|
||||
|
||||
SINK="fairmq-ex-multipart-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --session $SESSION"
|
||||
SINK+=" --channel-config name=data,type=pull,method=bind,rateLogging=0,address=tcp://127.0.0.1:5555"
|
||||
xterm -geometry 80x23+500+0 -hold -e @EX_BIN_DIR@/$SINK &
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(5), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multipart::Sampler();
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multipart::Sink();
|
||||
}
|
||||
|
@@ -33,8 +33,8 @@ Sampler::Sampler()
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Sampler::Run()
|
||||
|
@@ -31,7 +31,7 @@ Sink::Sink()
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sink::HandleBroadcast(FairMQMessagePtr& msg, int /*index*/)
|
||||
|
@@ -15,7 +15,7 @@ void addCustomOptions(bpo::options_description& /*options*/)
|
||||
{
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Broadcaster();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_channels::Sink();
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ Sampler1::Sampler1()
|
||||
|
||||
void Sampler1::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Sampler1::PreRun()
|
||||
|
@@ -21,7 +21,7 @@ Sampler2::Sampler2()
|
||||
|
||||
void Sampler2::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Sampler2::ConditionalRun()
|
||||
|
@@ -31,7 +31,7 @@ Sink::Sink()
|
||||
|
||||
void Sink::InitTask()
|
||||
{
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sampler1();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sampler2();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_multiple_transports::Sink();
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ class Builder : public FairMQDevice
|
||||
|
||||
void Init() override
|
||||
{
|
||||
fOutputChannelName = fConfig->GetValue<std::string>("output-name");
|
||||
fOutputChannelName = fConfig->GetProperty<std::string>("output-name");
|
||||
OnData("rb", &Builder::HandleData);
|
||||
}
|
||||
|
||||
|
@@ -31,8 +31,8 @@ class Readout : public FairMQDevice
|
||||
protected:
|
||||
void InitTask() override
|
||||
{
|
||||
fMsgSize = fConfig->GetValue<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("rb",
|
||||
0,
|
||||
|
@@ -25,7 +25,7 @@ class Receiver : public FairMQDevice
|
||||
void InitTask() override
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Run() override
|
||||
|
@@ -24,7 +24,7 @@ class Sender : public FairMQDevice
|
||||
|
||||
void Init() override
|
||||
{
|
||||
fInputChannelName = fConfig->GetValue<std::string>("input-name");
|
||||
fInputChannelName = fConfig->GetProperty<std::string>("input-name");
|
||||
OnData(fInputChannelName, &Sender::HandleData);
|
||||
}
|
||||
|
||||
|
@@ -31,10 +31,12 @@ SENDER="fairmq-ex-readout-sender"
|
||||
SENDER+=" --id sender1"
|
||||
SENDER+=" --input-name ps"
|
||||
SENDER+=" --channel-config name=ps,type=pair,method=bind,address=tcp://localhost:7779,transport=shmem"
|
||||
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=ofi"
|
||||
#SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=ofi"
|
||||
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=zeromq"
|
||||
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
||||
|
||||
RECEIVER="fairmq-ex-readout-receiver"
|
||||
RECEIVER+=" --id receiver1"
|
||||
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=ofi"
|
||||
#RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=ofi"
|
||||
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7780,transport=zeromq"
|
||||
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &
|
||||
|
@@ -25,10 +25,12 @@ SENDER="fairmq-ex-readout-sender"
|
||||
SENDER+=" --id sender1"
|
||||
SENDER+=" --input-name bs"
|
||||
SENDER+=" --channel-config name=bs,type=pair,method=bind,address=tcp://localhost:7778,transport=shmem"
|
||||
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=ofi"
|
||||
# SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=ofi"
|
||||
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=zeromq"
|
||||
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
||||
|
||||
RECEIVER="fairmq-ex-readout-receiver"
|
||||
RECEIVER+=" --id receiver1"
|
||||
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=ofi"
|
||||
# RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=ofi"
|
||||
RECEIVER+=" --channel-config name=sr,type=pair,method=bind,address=tcp://localhost:7779,transport=zeromq"
|
||||
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("output-name", bpo::value<std::string>()->default_value("bs"), "Output channel name");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_readout::Builder();
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ namespace bpo = boost::program_options;
|
||||
void addCustomOptions(bpo::options_description& /* options */)
|
||||
{}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_readout::Processor();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_readout::Readout();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_readout::Receiver();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("input-name", bpo::value<std::string>()->default_value("bs"), "Input channel name");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_readout::Sender();
|
||||
}
|
||||
|
@@ -32,16 +32,15 @@ Sampler::Sampler()
|
||||
|
||||
void Sampler::InitTask()
|
||||
{
|
||||
fMsgSize = fConfig->GetValue<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data",
|
||||
0,
|
||||
10000000,
|
||||
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
|
||||
--fNumUnackedMsgs;
|
||||
if (fMaxIterations > 0)
|
||||
{
|
||||
if (fMaxIterations > 0) {
|
||||
LOG(debug) << "Received ack";
|
||||
}
|
||||
}
|
||||
@@ -58,12 +57,14 @@ bool Sampler::ConditionalRun()
|
||||
nullptr // hint
|
||||
));
|
||||
|
||||
if (Send(msg, "data", 0) > 0)
|
||||
{
|
||||
// static_cast<char*>(fRegion->GetData())[3] = 97;
|
||||
// LOG(info) << "check: " << static_cast<char*>(fRegion->GetData())[3];
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
if (Send(msg, "data", 0) > 0) {
|
||||
++fNumUnackedMsgs;
|
||||
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
|
||||
{
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
return false;
|
||||
}
|
||||
@@ -75,8 +76,7 @@ bool Sampler::ConditionalRun()
|
||||
void Sampler::ResetTask()
|
||||
{
|
||||
// if not all messages acknowledged, wait for a bit. But only once, since receiver could be already dead.
|
||||
if (fNumUnackedMsgs != 0)
|
||||
{
|
||||
if (fNumUnackedMsgs != 0) {
|
||||
LOG(debug) << "waiting for all acknowledgements... (" << fNumUnackedMsgs << ")";
|
||||
this_thread::sleep_for(chrono::milliseconds(500));
|
||||
LOG(debug) << "done, still unacked: " << fNumUnackedMsgs;
|
||||
|
@@ -28,21 +28,22 @@ Sink::Sink()
|
||||
void Sink::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
void Sink::Run()
|
||||
{
|
||||
FairMQChannel& dataInChannel = fChannels.at("data").at(0);
|
||||
|
||||
while (!NewStatePending())
|
||||
{
|
||||
while (!NewStatePending()) {
|
||||
FairMQMessagePtr msg(dataInChannel.Transport()->CreateMessage());
|
||||
dataInChannel.Receive(msg);
|
||||
// void* ptr = msg->GetData();
|
||||
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations)
|
||||
{
|
||||
// void* ptr = msg->GetData();
|
||||
// char* cptr = static_cast<char*>(ptr);
|
||||
// LOG(info) << "check: " << cptr[3];
|
||||
|
||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
||||
break;
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_region::Sampler();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_region::Sink();
|
||||
}
|
||||
|
@@ -31,8 +31,8 @@ Client::Client()
|
||||
|
||||
void Client::InitTask()
|
||||
{
|
||||
fText = fConfig->GetValue<string>("text");
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fText = fConfig->GetProperty<string>("text");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Client::ConditionalRun()
|
||||
|
@@ -29,7 +29,7 @@ Server::Server()
|
||||
void Server::InitTask()
|
||||
{
|
||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||
fMaxIterations = fConfig->GetValue<uint64_t>("max-iterations");
|
||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||
}
|
||||
|
||||
bool Server::HandleData(FairMQMessagePtr& req, int /*index*/)
|
||||
|
@@ -18,7 +18,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_req_rep::Client();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ void addCustomOptions(bpo::options_description& options)
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||
}
|
||||
|
||||
FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/)
|
||||
FairMQDevicePtr getDevice(const fair::mq::ProgOptions& /*config*/)
|
||||
{
|
||||
return new example_req_rep::Server();
|
||||
}
|
||||
|
1
extern/asio
vendored
Submodule
1
extern/asio
vendored
Submodule
Submodule extern/asio added at 90f32660cd
17
extern/bundled_asio.cmake
vendored
Normal file
17
extern/bundled_asio.cmake
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
if(NOT TARGET asio::headers)
|
||||
if(Git_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive --depth 1 -- extern/asio
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
1
extern/googletest
vendored
Submodule
1
extern/googletest
vendored
Submodule
Submodule extern/googletest added at 90a443f9c2
@@ -16,11 +16,139 @@ if(BUILD_PMIX_PLUGIN)
|
||||
add_subdirectory(plugins/PMIx)
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
###########
|
||||
# Version #
|
||||
###########
|
||||
configure_file(Version.h.in
|
||||
${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
@ONLY
|
||||
)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME_LOWER}/Version.h
|
||||
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
||||
)
|
||||
|
||||
##########################
|
||||
# libFairMQ header files #
|
||||
##########################
|
||||
set(FAIRMQ_PUBLIC_HEADER_FILES
|
||||
#########
|
||||
# Tools #
|
||||
#########
|
||||
set(target Tools)
|
||||
|
||||
set(TOOLS_PUBLIC_HEADER_FILES
|
||||
tools/CppSTL.h
|
||||
tools/InstanceLimit.h
|
||||
tools/Network.h
|
||||
tools/Process.h
|
||||
tools/RateLimit.h
|
||||
tools/Semaphore.h
|
||||
tools/Strings.h
|
||||
tools/Unique.h
|
||||
tools/Version.h
|
||||
Tools.h
|
||||
)
|
||||
|
||||
set(TOOLS_SOURCE_FILES
|
||||
tools/Network.cxx
|
||||
tools/Process.cxx
|
||||
tools/Semaphore.cxx
|
||||
tools/Unique.cxx
|
||||
)
|
||||
|
||||
add_library(${target}
|
||||
${TOOLS_SOURCE_FILES}
|
||||
${TOOLS_PUBLIC_HEADER_FILES}
|
||||
)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
FairLogger::FairLogger
|
||||
PUBLIC
|
||||
Boost::boost
|
||||
)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
|
||||
OUTPUT_NAME FairMQ${target}
|
||||
)
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT ${PROJECT_EXPORT_SET}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
)
|
||||
foreach(HEADER ${TOOLS_PUBLIC_HEADER_FILES})
|
||||
get_filename_component(_path ${HEADER} DIRECTORY)
|
||||
file(TO_CMAKE_PATH ${PROJECT_INSTALL_INCDIR}/${_path} _destination)
|
||||
install(FILES ${HEADER}
|
||||
DESTINATION ${_destination}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
#################
|
||||
# State Machine #
|
||||
#################
|
||||
set(target StateMachine)
|
||||
|
||||
set(FSM_PUBLIC_HEADER_FILES
|
||||
StateMachine.h
|
||||
States.h
|
||||
StateQueue.h
|
||||
)
|
||||
|
||||
set(FSM_SOURCE_FILES
|
||||
StateMachine.cxx
|
||||
States.cxx
|
||||
)
|
||||
|
||||
add_library(${target}
|
||||
${FSM_SOURCE_FILES}
|
||||
${FSM_PUBLIC_HEADER_FILES}
|
||||
)
|
||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
target_link_libraries(${target}
|
||||
PUBLIC
|
||||
FairLogger::FairLogger
|
||||
|
||||
PRIVATE
|
||||
Boost::boost
|
||||
Tools
|
||||
)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
|
||||
OUTPUT_NAME FairMQ${target}
|
||||
)
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT ${PROJECT_EXPORT_SET}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
)
|
||||
foreach(HEADER ${FSM_PUBLIC_HEADER_FILES})
|
||||
get_filename_component(_path ${HEADER} DIRECTORY)
|
||||
file(TO_CMAKE_PATH ${PROJECT_INSTALL_INCDIR}/${_path} _destination)
|
||||
install(FILES ${HEADER}
|
||||
DESTINATION ${_destination}
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ)
|
||||
##########################
|
||||
# libFairMQ header files #
|
||||
##########################
|
||||
set(FAIRMQ_PUBLIC_HEADER_FILES
|
||||
DeviceRunner.h
|
||||
EventManager.h
|
||||
FairMQChannel.h
|
||||
@@ -31,38 +159,32 @@ set(FAIRMQ_PUBLIC_HEADER_FILES
|
||||
FairMQPoller.h
|
||||
FairMQUnmanagedRegion.h
|
||||
FairMQSocket.h
|
||||
StateMachine.h
|
||||
FairMQTransportFactory.h
|
||||
MemoryResources.h
|
||||
MemoryResourceTools.h
|
||||
Tools.h
|
||||
Transports.h
|
||||
options/FairMQProgOptions.h
|
||||
options/FairProgOptions.h
|
||||
JSONParser.h
|
||||
ProgOptionsFwd.h
|
||||
ProgOptions.h
|
||||
Properties.h
|
||||
PropertyOutput.h
|
||||
SuboptParser.h
|
||||
Plugin.h
|
||||
PluginManager.h
|
||||
PluginServices.h
|
||||
runFairMQDevice.h
|
||||
tools/CppSTL.h
|
||||
tools/Network.h
|
||||
tools/Process.h
|
||||
tools/RateLimit.h
|
||||
tools/Strings.h
|
||||
tools/Unique.h
|
||||
tools/Version.h
|
||||
)
|
||||
)
|
||||
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||
devices/FairMQBenchmarkSampler.h
|
||||
devices/FairMQMerger.h
|
||||
devices/FairMQMultiplier.h
|
||||
devices/FairMQProxy.h
|
||||
devices/FairMQSink.h
|
||||
devices/FairMQSplitter.h
|
||||
options/FairMQParser.h
|
||||
options/FairMQSuboptParser.h
|
||||
options/FairProgOptionsHelper.h
|
||||
plugins/Builtin.h
|
||||
plugins/config/Config.h
|
||||
plugins/Control.h
|
||||
shmem/FairMQMessageSHM.h
|
||||
shmem/FairMQPollerSHM.h
|
||||
@@ -77,9 +199,9 @@ set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||
zeromq/FairMQUnmanagedRegionZMQ.h
|
||||
zeromq/FairMQSocketZMQ.h
|
||||
zeromq/FairMQTransportFactoryZMQ.h
|
||||
)
|
||||
)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
nanomsg/FairMQMessageNN.h
|
||||
nanomsg/FairMQPollerNN.h
|
||||
@@ -87,9 +209,9 @@ if(BUILD_NANOMSG_TRANSPORT)
|
||||
nanomsg/FairMQSocketNN.h
|
||||
nanomsg/FairMQTransportFactoryNN.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
ofi/Context.h
|
||||
ofi/Message.h
|
||||
@@ -97,12 +219,12 @@ if(BUILD_OFI_TRANSPORT)
|
||||
ofi/Socket.h
|
||||
ofi/TransportFactory.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
##########################
|
||||
# libFairMQ source files #
|
||||
##########################
|
||||
set(FAIRMQ_SOURCE_FILES
|
||||
##########################
|
||||
# libFairMQ source files #
|
||||
##########################
|
||||
set(FAIRMQ_SOURCE_FILES
|
||||
DeviceRunner.cxx
|
||||
FairMQChannel.cxx
|
||||
FairMQDevice.cxx
|
||||
@@ -110,19 +232,20 @@ set(FAIRMQ_SOURCE_FILES
|
||||
FairMQMessage.cxx
|
||||
FairMQPoller.cxx
|
||||
FairMQSocket.cxx
|
||||
StateMachine.cxx
|
||||
FairMQTransportFactory.cxx
|
||||
devices/FairMQBenchmarkSampler.cxx
|
||||
devices/FairMQMerger.cxx
|
||||
devices/FairMQMultiplier.cxx
|
||||
devices/FairMQProxy.cxx
|
||||
devices/FairMQSplitter.cxx
|
||||
options/FairMQParser.cxx
|
||||
options/FairMQProgOptions.cxx
|
||||
options/FairMQSuboptParser.cxx
|
||||
Plugin.cxx
|
||||
PluginManager.cxx
|
||||
PluginServices.cxx
|
||||
ProgOptions.cxx
|
||||
JSONParser.cxx
|
||||
Properties.cxx
|
||||
SuboptParser.cxx
|
||||
plugins/config/Config.cxx
|
||||
plugins/Control.cxx
|
||||
shmem/FairMQMessageSHM.cxx
|
||||
shmem/FairMQPollerSHM.cxx
|
||||
@@ -131,18 +254,15 @@ set(FAIRMQ_SOURCE_FILES
|
||||
shmem/FairMQTransportFactorySHM.cxx
|
||||
shmem/Manager.cxx
|
||||
shmem/Region.cxx
|
||||
tools/Network.cxx
|
||||
tools/Process.cxx
|
||||
tools/Unique.cxx
|
||||
zeromq/FairMQMessageZMQ.cxx
|
||||
zeromq/FairMQPollerZMQ.cxx
|
||||
zeromq/FairMQUnmanagedRegionZMQ.cxx
|
||||
zeromq/FairMQSocketZMQ.cxx
|
||||
zeromq/FairMQTransportFactoryZMQ.cxx
|
||||
MemoryResources.cxx
|
||||
)
|
||||
)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
|
||||
nanomsg/FairMQMessageNN.cxx
|
||||
nanomsg/FairMQPollerNN.cxx
|
||||
@@ -150,9 +270,9 @@ if(BUILD_NANOMSG_TRANSPORT)
|
||||
nanomsg/FairMQSocketNN.cxx
|
||||
nanomsg/FairMQTransportFactoryNN.cxx
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
|
||||
ofi/Context.cxx
|
||||
ofi/Message.cxx
|
||||
@@ -160,78 +280,76 @@ if(BUILD_OFI_TRANSPORT)
|
||||
ofi/Socket.cxx
|
||||
ofi/TransportFactory.cxx
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
###################
|
||||
# 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}/options/startConfigExample.sh.in ${CMAKE_CURRENT_BINARY_DIR}/startConfigExample.sh)
|
||||
###################
|
||||
# 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)
|
||||
|
||||
|
||||
#################################
|
||||
# define libFairMQ build target #
|
||||
#################################
|
||||
if(FAST_BUILD)
|
||||
#################################
|
||||
# define libFairMQ build target #
|
||||
#################################
|
||||
if(FAST_BUILD)
|
||||
set(_target FairMQ_)
|
||||
else()
|
||||
else()
|
||||
set(_target FairMQ)
|
||||
endif()
|
||||
add_library(${_target}
|
||||
endif()
|
||||
add_library(${_target}
|
||||
${FAIRMQ_SOURCE_FILES}
|
||||
${FAIRMQ_PUBLIC_HEADER_FILES} # for IDE integration
|
||||
${FAIRMQ_PRIVATE_HEADER_FILES} # for IDE integration
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES LABELS coverage)
|
||||
if(FAST_BUILD)
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES LABELS coverage)
|
||||
if(FAST_BUILD)
|
||||
set_target_properties(${_target} PROPERTIES OUTPUT_NAME FairMQ)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
############################
|
||||
# preprocessor definitions #
|
||||
############################
|
||||
target_compile_definitions(${_target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
############################
|
||||
# preprocessor definitions #
|
||||
############################
|
||||
target_compile_definitions(${_target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
target_compile_definitions(${_target} PRIVATE BUILD_NANOMSG_TRANSPORT)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
target_compile_definitions(${_target} PRIVATE BUILD_OFI_TRANSPORT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
#######################
|
||||
# include directories #
|
||||
#######################
|
||||
target_include_directories(${_target}
|
||||
#######################
|
||||
# include directories #
|
||||
#######################
|
||||
target_include_directories(${_target}
|
||||
PUBLIC # consumers inherit public include directories
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
|
||||
$<INSTALL_INTERFACE:include/fairmq>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
)
|
||||
|
||||
##################
|
||||
# link libraries #
|
||||
##################
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
##################
|
||||
# link libraries #
|
||||
##################
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(NANOMSG_DEPS nanomsg msgpackc-cxx)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
endif()
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(OFI_DEPS
|
||||
asiofi::asiofi
|
||||
Boost::container
|
||||
)
|
||||
endif()
|
||||
set(optional_deps ${NANOMSG_DEPS} ${OFI_DEPS})
|
||||
if(optional_deps)
|
||||
endif()
|
||||
set(optional_deps ${NANOMSG_DEPS} ${OFI_DEPS})
|
||||
if(optional_deps)
|
||||
list(REMOVE_DUPLICATES optional_deps)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${_target}
|
||||
target_link_libraries(${_target}
|
||||
INTERFACE # only consumers link against interface dependencies
|
||||
Boost::container
|
||||
|
||||
@@ -244,22 +362,24 @@ target_link_libraries(${_target}
|
||||
Boost::filesystem
|
||||
Boost::regex
|
||||
FairLogger::FairLogger
|
||||
Tools
|
||||
StateMachine
|
||||
|
||||
PRIVATE # only libFairMQ links against private dependencies
|
||||
libzmq
|
||||
${NANOMSG_DEPS}
|
||||
${OFI_DEPS}
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES
|
||||
VERSION ${PROJECT_GIT_VERSION}
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
##############
|
||||
# fast build #
|
||||
##############
|
||||
if(FAST_BUILD)
|
||||
##############
|
||||
# fast build #
|
||||
##############
|
||||
if(FAST_BUILD)
|
||||
set_target_properties(${_target} PROPERTIES
|
||||
COTIRE_UNITY_TARGET_NAME "FairMQ"
|
||||
# COTIRE_ENABLE_PRECOMPILED_HEADER FALSE
|
||||
@@ -268,53 +388,51 @@ if(FAST_BUILD)
|
||||
cotire(${_target})
|
||||
set_target_properties(FairMQ PROPERTIES EXCLUDE_FROM_ALL FALSE)
|
||||
set_target_properties(FairMQ PROPERTIES LABELS coverage)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
###############
|
||||
# executables #
|
||||
###############
|
||||
add_executable(fairmq-bsampler run/runBenchmarkSampler.cxx)
|
||||
target_link_libraries(fairmq-bsampler FairMQ)
|
||||
###############
|
||||
# executables #
|
||||
###############
|
||||
add_executable(fairmq-bsampler run/runBenchmarkSampler.cxx)
|
||||
target_link_libraries(fairmq-bsampler FairMQ)
|
||||
|
||||
add_executable(fairmq-merger run/runMerger.cxx)
|
||||
target_link_libraries(fairmq-merger FairMQ)
|
||||
add_executable(fairmq-merger run/runMerger.cxx)
|
||||
target_link_libraries(fairmq-merger FairMQ)
|
||||
|
||||
add_executable(fairmq-multiplier run/runMultiplier.cxx)
|
||||
target_link_libraries(fairmq-multiplier FairMQ)
|
||||
add_executable(fairmq-multiplier run/runMultiplier.cxx)
|
||||
target_link_libraries(fairmq-multiplier FairMQ)
|
||||
|
||||
add_executable(fairmq-proxy run/runProxy.cxx)
|
||||
target_link_libraries(fairmq-proxy FairMQ)
|
||||
add_executable(fairmq-proxy run/runProxy.cxx)
|
||||
target_link_libraries(fairmq-proxy FairMQ)
|
||||
|
||||
add_executable(fairmq-sink run/runSink.cxx)
|
||||
target_link_libraries(fairmq-sink FairMQ)
|
||||
add_executable(fairmq-sink run/runSink.cxx)
|
||||
target_link_libraries(fairmq-sink FairMQ)
|
||||
|
||||
add_executable(fairmq-splitter run/runSplitter.cxx)
|
||||
target_link_libraries(fairmq-splitter FairMQ)
|
||||
add_executable(fairmq-splitter run/runSplitter.cxx)
|
||||
target_link_libraries(fairmq-splitter FairMQ)
|
||||
|
||||
add_executable(runConfigExample options/runConfigEx.cxx)
|
||||
target_link_libraries(runConfigExample FairMQ)
|
||||
|
||||
add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx)
|
||||
target_link_libraries(fairmq-shmmonitor PUBLIC
|
||||
add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx)
|
||||
target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
||||
target_link_libraries(fairmq-shmmonitor PUBLIC
|
||||
Threads::Threads
|
||||
$<$<PLATFORM_ID:Linux>:rt>
|
||||
Boost::boost
|
||||
Boost::date_time
|
||||
Boost::program_options
|
||||
)
|
||||
target_include_directories(fairmq-shmmonitor PUBLIC
|
||||
)
|
||||
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 run/runUuidGenerator.cxx)
|
||||
target_link_libraries(fairmq-uuid-gen FairMQ)
|
||||
|
||||
|
||||
###########
|
||||
# install #
|
||||
###########
|
||||
install(
|
||||
###########
|
||||
# install #
|
||||
###########
|
||||
install(
|
||||
TARGETS
|
||||
FairMQ
|
||||
fairmq-bsampler
|
||||
@@ -330,13 +448,22 @@ install(
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
)
|
||||
)
|
||||
|
||||
# preserve relative path and prepend fairmq
|
||||
foreach(HEADER ${FAIRMQ_PUBLIC_HEADER_FILES})
|
||||
# preserve relative path and prepend fairmq
|
||||
foreach(HEADER ${FAIRMQ_PUBLIC_HEADER_FILES})
|
||||
get_filename_component(_path ${HEADER} DIRECTORY)
|
||||
file(TO_CMAKE_PATH ${PROJECT_INSTALL_INCDIR}/${_path} _destination)
|
||||
install(FILES ${HEADER}
|
||||
DESTINATION ${_destination}
|
||||
)
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(BUILD_SDK_COMMANDS)
|
||||
add_subdirectory(sdk/commands)
|
||||
endif()
|
||||
|
||||
if(BUILD_SDK)
|
||||
add_subdirectory(sdk)
|
||||
endif()
|
||||
|
@@ -12,9 +12,10 @@
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/Version.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
DeviceRunner::DeviceRunner(int argc, char* const argv[], bool printLogo)
|
||||
DeviceRunner::DeviceRunner(int argc, char*const* argv, bool printLogo)
|
||||
: fRawCmdLineArgs(tools::ToStrVector(argc, argv, false))
|
||||
, fConfig()
|
||||
, fDevice(nullptr)
|
||||
@@ -23,8 +24,80 @@ DeviceRunner::DeviceRunner(int argc, char* const argv[], bool printLogo)
|
||||
, fEvents()
|
||||
{}
|
||||
|
||||
bool DeviceRunner::HandleGeneralOptions(const fair::mq::ProgOptions& config, bool printLogo)
|
||||
{
|
||||
if (config.Count("help")) {
|
||||
config.PrintHelp();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config.Count("print-options")) {
|
||||
config.PrintOptionsRaw();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config.Count("print-channels") || config.Count("version")) {
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
} else {
|
||||
string severity = config.GetProperty<string>("severity");
|
||||
string logFile = config.GetProperty<string>("log-to-file");
|
||||
string logFileSeverity = config.GetProperty<string>("file-severity");
|
||||
bool color = config.GetProperty<bool>("color");
|
||||
|
||||
string verbosity = config.GetProperty<string>("verbosity");
|
||||
fair::Logger::SetVerbosity(verbosity);
|
||||
|
||||
if (logFile != "") {
|
||||
fair::Logger::InitFileSink(logFileSeverity, logFile);
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
} else {
|
||||
fair::Logger::SetConsoleColor(color);
|
||||
fair::Logger::SetConsoleSeverity(severity);
|
||||
}
|
||||
|
||||
if (printLogo) {
|
||||
LOG(info) << endl
|
||||
<< " ______ _ _______ _________ " << endl
|
||||
<< " / ____/___ _(_)_______ |/ /_ __ \\ version " << FAIRMQ_GIT_VERSION << endl
|
||||
<< " / /_ / __ `/ / ___/__ /|_/ /_ / / / build " << FAIRMQ_BUILD_TYPE << endl
|
||||
<< " / __/ / /_/ / / / _ / / / / /_/ / " << FAIRMQ_REPO_URL << endl
|
||||
<< " /_/ \\__,_/_/_/ /_/ /_/ \\___\\_\\ " << FAIRMQ_LICENSE << " © " << FAIRMQ_COPYRIGHT << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceRunner::SubscribeForConfigChange()
|
||||
{
|
||||
fConfig.Subscribe<bool>("device-runner", [](const std::string& key, const bool val) {
|
||||
if (key == "color") {
|
||||
fair::Logger::SetConsoleColor(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") {
|
||||
fair::Logger::SetFileSeverity(val);
|
||||
} else if (key == "verbosity") {
|
||||
fair::Logger::SetVerbosity(val);
|
||||
} else if (key == "log-to-file") {
|
||||
string fileSeverity = fConfig.GetProperty<string>("file-severity");
|
||||
fair::Logger::InitFileSink(fileSeverity, val);
|
||||
}
|
||||
});
|
||||
}
|
||||
void DeviceRunner::UnsubscribeFromConfigChange()
|
||||
{
|
||||
fConfig.Unsubscribe<bool>("device-runner");
|
||||
fConfig.Unsubscribe<string>("device-runner");
|
||||
}
|
||||
|
||||
auto DeviceRunner::Run() -> int
|
||||
{
|
||||
fPluginManager.LoadPlugin("s:config");
|
||||
|
||||
////// CALL HOOK ///////
|
||||
fEvents.Emit<hooks::LoadPlugins>(*this);
|
||||
////////////////////////
|
||||
@@ -36,8 +109,7 @@ auto DeviceRunner::Run() -> int
|
||||
fEvents.Emit<hooks::SetCustomCmdLineOptions>(*this);
|
||||
////////////////////////
|
||||
|
||||
fPluginManager.ForEachPluginProgOptions(
|
||||
[&](boost::program_options::options_description options) {
|
||||
fPluginManager.ForEachPluginProgOptions([&](boost::program_options::options_description options) {
|
||||
fConfig.AddToCmdLineOptions(options);
|
||||
});
|
||||
fConfig.AddToCmdLineOptions(fPluginManager.ProgramOptions());
|
||||
@@ -46,18 +118,16 @@ auto DeviceRunner::Run() -> int
|
||||
fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);
|
||||
////////////////////////
|
||||
|
||||
if (fConfig.ParseAll(fRawCmdLineArgs, true)) {
|
||||
fConfig.ParseAll(fRawCmdLineArgs, true);
|
||||
|
||||
if (!HandleGeneralOptions(fConfig)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fPrintLogo) {
|
||||
LOG(info) << std::endl
|
||||
<< " ______ _ _______ _________ " << std::endl
|
||||
<< " / ____/___ _(_)_______ |/ /_ __ \\ version " << FAIRMQ_GIT_VERSION << std::endl
|
||||
<< " / /_ / __ `/ / ___/__ /|_/ /_ / / / build " << FAIRMQ_BUILD_TYPE << std::endl
|
||||
<< " / __/ / /_/ / / / _ / / / / /_/ / " << FAIRMQ_REPO_URL << std::endl
|
||||
<< " /_/ \\__,_/_/_/ /_/ /_/ \\___\\_\\ " << FAIRMQ_LICENSE << " © " << FAIRMQ_COPYRIGHT << std::endl;
|
||||
}
|
||||
fConfig.Notify();
|
||||
|
||||
// handle configuration updates (for general options)
|
||||
SubscribeForConfigChange();
|
||||
|
||||
////// CALL HOOK ///////
|
||||
fEvents.Emit<hooks::InstantiateDevice>(*this);
|
||||
@@ -80,7 +150,8 @@ auto DeviceRunner::Run() -> int
|
||||
|
||||
// Handle --version
|
||||
if (fConfig.Count("version")) {
|
||||
std::cout << "User device version: " << fDevice->GetVersion() << std::endl;
|
||||
cout << "FairMQ version: " << FAIRMQ_GIT_VERSION << endl;
|
||||
cout << "User device version: " << fDevice->GetVersion() << endl;
|
||||
fDevice->ChangeState(fair::mq::Transition::End);
|
||||
return 0;
|
||||
}
|
||||
@@ -96,12 +167,18 @@ auto DeviceRunner::Run() -> int
|
||||
// Instantiate and run plugins
|
||||
fPluginManager.InstantiatePlugins();
|
||||
|
||||
// Log IDLE configuration
|
||||
fConfig.PrintOptions();
|
||||
|
||||
// Run the device
|
||||
fDevice->RunStateMachine();
|
||||
|
||||
// Wait for control plugin to release device control
|
||||
fPluginManager.WaitForPluginsToReleaseDeviceControl();
|
||||
|
||||
// stop handling configuration updates (for general options)
|
||||
UnsubscribeFromConfigChange();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -109,7 +186,7 @@ auto DeviceRunner::RunWithExceptionHandlers() -> int
|
||||
{
|
||||
try {
|
||||
return Run();
|
||||
} catch (std::exception& e) {
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Uncaught exception reached the top of DeviceRunner: " << e.what();
|
||||
return 1;
|
||||
} catch (...) {
|
||||
|
@@ -11,9 +11,9 @@
|
||||
|
||||
#include <fairmq/EventManager.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <fairmq/ProgOptions.h>
|
||||
#include <FairMQDevice.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <options/FairMQProgOptions.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -51,11 +51,16 @@ namespace mq {
|
||||
class DeviceRunner
|
||||
{
|
||||
public:
|
||||
DeviceRunner(int argc, char* const argv[], bool printLogo = true);
|
||||
DeviceRunner(int argc, char*const* argv, bool printLogo = true);
|
||||
|
||||
auto Run() -> int;
|
||||
auto RunWithExceptionHandlers() -> int;
|
||||
|
||||
static bool HandleGeneralOptions(const fair::mq::ProgOptions& config, bool printLogo = true);
|
||||
|
||||
void SubscribeForConfigChange();
|
||||
void UnsubscribeFromConfigChange();
|
||||
|
||||
template<typename H>
|
||||
auto AddHook(std::function<void(DeviceRunner&)> hook) -> void
|
||||
{
|
||||
@@ -68,7 +73,7 @@ class DeviceRunner
|
||||
}
|
||||
|
||||
std::vector<std::string> fRawCmdLineArgs;
|
||||
FairMQProgOptions fConfig;
|
||||
fair::mq::ProgOptions fConfig;
|
||||
std::unique_ptr<FairMQDevice> fDevice;
|
||||
PluginManager fPluginManager;
|
||||
const bool fPrintLogo;
|
||||
|
@@ -12,12 +12,10 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
@@ -5,64 +5,114 @@
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
* FairMQChannel.cxx
|
||||
*
|
||||
* @since 2015-06-02
|
||||
* @author A. Rybalchenko
|
||||
*/
|
||||
|
||||
#include "FairMQChannel.h"
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
#include <fairmq/Properties.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp> // join/split
|
||||
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <random>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
mutex FairMQChannel::fChannelMutex;
|
||||
template<typename T>
|
||||
T GetPropertyOrDefault(const fair::mq::Properties& m, const string& k, const T& ifNotFound) noexcept
|
||||
{
|
||||
if (m.count(k)) {
|
||||
return boost::any_cast<T>(m.at(k));
|
||||
}
|
||||
return ifNotFound;
|
||||
}
|
||||
|
||||
constexpr fair::mq::Transport FairMQChannel::DefaultTransportType;
|
||||
constexpr const char* FairMQChannel::DefaultTransportName;
|
||||
constexpr const char* FairMQChannel::DefaultName;
|
||||
constexpr const char* FairMQChannel::DefaultType;
|
||||
constexpr const char* FairMQChannel::DefaultMethod;
|
||||
constexpr const char* FairMQChannel::DefaultAddress;
|
||||
constexpr int FairMQChannel::DefaultSndBufSize;
|
||||
constexpr int FairMQChannel::DefaultRcvBufSize;
|
||||
constexpr int FairMQChannel::DefaultSndKernelSize;
|
||||
constexpr int FairMQChannel::DefaultRcvKernelSize;
|
||||
constexpr int FairMQChannel::DefaultLinger;
|
||||
constexpr int FairMQChannel::DefaultRateLogging;
|
||||
constexpr int FairMQChannel::DefaultPortRangeMin;
|
||||
constexpr int FairMQChannel::DefaultPortRangeMax;
|
||||
constexpr bool FairMQChannel::DefaultAutoBind;
|
||||
|
||||
FairMQChannel::FairMQChannel()
|
||||
: FairMQChannel("", "unspecified", "unspecified", "unspecified", nullptr)
|
||||
: FairMQChannel(DefaultName, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
||||
{}
|
||||
|
||||
FairMQChannel::FairMQChannel(const string& name)
|
||||
: FairMQChannel(name, DefaultType, DefaultMethod, DefaultAddress, nullptr)
|
||||
{}
|
||||
|
||||
FairMQChannel::FairMQChannel(const string& type, const string& method, const string& address)
|
||||
: FairMQChannel("", type, method, address, nullptr)
|
||||
: FairMQChannel(DefaultName, type, method, address, nullptr)
|
||||
{}
|
||||
|
||||
FairMQChannel::FairMQChannel(const string& name, const string& type, shared_ptr<FairMQTransportFactory> factory)
|
||||
: FairMQChannel(name, type, "unspecified", "unspecified", factory)
|
||||
: FairMQChannel(name, type, DefaultMethod, DefaultAddress, factory)
|
||||
{}
|
||||
|
||||
FairMQChannel::FairMQChannel(const string& name, const string& type, const string& method, const string& address, shared_ptr<FairMQTransportFactory> factory)
|
||||
: fTransportFactory(factory)
|
||||
, fTransportType(factory ? factory->GetType() : fair::mq::Transport::DEFAULT)
|
||||
, fTransportType(factory ? factory->GetType() : DefaultTransportType)
|
||||
, fSocket(factory ? factory->CreateSocket(type, name) : nullptr)
|
||||
, fName(name)
|
||||
, fType(type)
|
||||
, fMethod(method)
|
||||
, fAddress(address)
|
||||
, fSndBufSize(1000)
|
||||
, fRcvBufSize(1000)
|
||||
, fSndKernelSize(0)
|
||||
, fRcvKernelSize(0)
|
||||
, fLinger(500)
|
||||
, fRateLogging(1)
|
||||
, fPortRangeMin(22000)
|
||||
, fPortRangeMax(23000)
|
||||
, fAutoBind(true)
|
||||
, fName(name)
|
||||
, fSndBufSize(DefaultSndBufSize)
|
||||
, fRcvBufSize(DefaultRcvBufSize)
|
||||
, fSndKernelSize(DefaultSndKernelSize)
|
||||
, fRcvKernelSize(DefaultRcvKernelSize)
|
||||
, fLinger(DefaultLinger)
|
||||
, fRateLogging(DefaultRateLogging)
|
||||
, fPortRangeMin(DefaultPortRangeMin)
|
||||
, fPortRangeMax(DefaultPortRangeMax)
|
||||
, fAutoBind(DefaultAutoBind)
|
||||
, fIsValid(false)
|
||||
, fMultipart(false)
|
||||
, fModified(true)
|
||||
, fReset(false)
|
||||
, fMtx()
|
||||
{}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
||||
: FairMQChannel(chan, chan.fName)
|
||||
{}
|
||||
|
||||
FairMQChannel::FairMQChannel(const FairMQChannel& chan, const string& newName)
|
||||
: fTransportFactory(nullptr)
|
||||
, fTransportType(chan.fTransportType)
|
||||
, fSocket(nullptr)
|
||||
, fName(newName)
|
||||
, fType(chan.fType)
|
||||
, fMethod(chan.fMethod)
|
||||
, fAddress(chan.fAddress)
|
||||
@@ -75,7 +125,6 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
||||
, fPortRangeMin(chan.fPortRangeMin)
|
||||
, fPortRangeMax(chan.fPortRangeMax)
|
||||
, fAutoBind(chan.fAutoBind)
|
||||
, fName(chan.fName)
|
||||
, fIsValid(false)
|
||||
, fMultipart(chan.fMultipart)
|
||||
, fModified(chan.fModified)
|
||||
@@ -87,6 +136,7 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
fTransportFactory = nullptr;
|
||||
fTransportType = chan.fTransportType;
|
||||
fSocket = nullptr;
|
||||
fName = chan.fName;
|
||||
fType = chan.fType;
|
||||
fMethod = chan.fMethod;
|
||||
fAddress = chan.fAddress;
|
||||
@@ -99,7 +149,6 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
fPortRangeMin = chan.fPortRangeMin;
|
||||
fPortRangeMax = chan.fPortRangeMax;
|
||||
fAutoBind = chan.fAutoBind;
|
||||
fName = chan.fName;
|
||||
fIsValid = false;
|
||||
fMultipart = chan.fMultipart;
|
||||
fModified = chan.fModified;
|
||||
@@ -116,13 +165,13 @@ FairMQSocket & FairMQChannel::GetSocket() const
|
||||
|
||||
string FairMQChannel::GetName() const
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fName;
|
||||
}
|
||||
|
||||
string FairMQChannel::GetPrefix() const
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
string prefix = fName;
|
||||
prefix = prefix.erase(fName.rfind('['));
|
||||
return prefix;
|
||||
@@ -130,7 +179,7 @@ string FairMQChannel::GetPrefix() const
|
||||
|
||||
string FairMQChannel::GetIndex() const
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
string indexStr = fName;
|
||||
indexStr.erase(indexStr.rfind(']'));
|
||||
indexStr.erase(0, indexStr.rfind('[') + 1);
|
||||
@@ -139,296 +188,306 @@ string FairMQChannel::GetIndex() const
|
||||
|
||||
string FairMQChannel::GetType() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fType;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetType: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetMethod() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fMethod;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetMethod: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetAddress() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fAddress;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetAddress: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
string FairMQChannel::GetTransportName() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
return fair::mq::TransportNames.at(fTransportType);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return TransportNames.at(fTransportType);
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetTransportName: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", 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(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fSndBufSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetSndBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRcvBufSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRcvBufSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRcvBufSize: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetSndKernelSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fSndKernelSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetSndKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRcvKernelSize() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRcvKernelSize;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRcvKernelSize: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetLinger() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fLinger;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetLinger: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetRateLogging() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fRateLogging;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetRateLogging: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetPortRangeMin() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fPortRangeMin;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMin: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
int FairMQChannel::GetPortRangeMax() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fPortRangeMax;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetPortRangeMax: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::GetAutoBind() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fAutoBind;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetAutoBind: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateType(const string& type)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateMethod(const string& method)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateAddress(const string& address)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateTransport(const string& transport)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
fTransportType = fair::mq::TransportTypes.at(transport);
|
||||
fTransportType = TransportTypes.at(transport);
|
||||
fModified = true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::UpdateTransport: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateSndBufSize(const int sndBufSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRcvBufSize(const int rcvBufSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateSndKernelSize(const int sndKernelSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRcvKernelSize(const int rcvKernelSize)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateLinger(const int duration)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateRateLogging(const int rateLogging)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdatePortRangeMin(const int minPort)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdatePortRangeMax(const int maxPort)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateAutoBind(const bool autobind)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
auto FairMQChannel::SetModified(const bool modified) -> void
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fModified = modified;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::SetModified: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::UpdateName(const string& name)
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::IsValid() const
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
return fIsValid;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::IsValid: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("failed to acquire lock: ", e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString("failed to acquire lock: ", e.what()));
|
||||
}
|
||||
|
||||
bool FairMQChannel::Validate()
|
||||
try {
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
stringstream ss;
|
||||
ss << "Validating channel '" << fName << "'... ";
|
||||
|
||||
@@ -438,13 +497,22 @@ try {
|
||||
return true;
|
||||
}
|
||||
|
||||
// validate channel name
|
||||
smatch m;
|
||||
if (regex_search(fName, m, regex("[^a-zA-Z0-9\\-_\\[\\]#]"))) {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "channel name contains illegal character: '" << m.str(0) << "', allowed characters are: a-z, A-Z, 0-9, -, _, [, ], #";
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate socket type
|
||||
const set<string> socketTypes{ "sub", "pub", "pull", "push", "req", "rep", "xsub", "xpub", "dealer", "router", "pair" };
|
||||
if (socketTypes.find(fType) == socketTypes.end()) {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "Invalid channel type: '" << fType << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("Invalid channel type: '", fType, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("Invalid channel type: '", fType, "'"));
|
||||
}
|
||||
|
||||
// validate socket address
|
||||
@@ -467,7 +535,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "Invalid endpoint connection method: '" << fMethod << "' for " << endpoint;
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("Invalid endpoint connection method: '", fMethod, "' for ", endpoint));
|
||||
throw ChannelConfigurationError(tools::ToString("Invalid endpoint connection method: '", fMethod, "' for ", endpoint));
|
||||
}
|
||||
address = endpoint;
|
||||
}
|
||||
@@ -523,7 +591,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "invalid channel send buffer size (cannot be negative): '" << fSndBufSize << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("invalid channel send buffer size (cannot be negative): '", fSndBufSize, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("invalid channel send buffer size (cannot be negative): '", fSndBufSize, "'"));
|
||||
}
|
||||
|
||||
// validate socket buffer size for receiving
|
||||
@@ -531,7 +599,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "invalid channel receive buffer size (cannot be negative): '" << fRcvBufSize << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("invalid channel receive buffer size (cannot be negative): '", fRcvBufSize, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("invalid channel receive buffer size (cannot be negative): '", fRcvBufSize, "'"));
|
||||
}
|
||||
|
||||
// validate socket kernel transmit size for sending
|
||||
@@ -539,7 +607,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "invalid channel send kernel transmit size (cannot be negative): '" << fSndKernelSize << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("invalid channel send kernel transmit size (cannot be negative): '", fSndKernelSize, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("invalid channel send kernel transmit size (cannot be negative): '", fSndKernelSize, "'"));
|
||||
}
|
||||
|
||||
// validate socket kernel transmit size for receiving
|
||||
@@ -547,7 +615,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "invalid channel receive kernel transmit size (cannot be negative): '" << fRcvKernelSize << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("invalid channel receive kernel transmit size (cannot be negative): '", fRcvKernelSize, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("invalid channel receive kernel transmit size (cannot be negative): '", fRcvKernelSize, "'"));
|
||||
}
|
||||
|
||||
// validate socket rate logging interval
|
||||
@@ -555,7 +623,7 @@ try {
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "invalid socket rate logging interval (cannot be negative): '" << fRateLogging << "'";
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString("invalid socket rate logging interval (cannot be negative): '", fRateLogging, "'"));
|
||||
throw ChannelConfigurationError(tools::ToString("invalid socket rate logging interval (cannot be negative): '", fRateLogging, "'"));
|
||||
}
|
||||
|
||||
fIsValid = true;
|
||||
@@ -564,12 +632,12 @@ try {
|
||||
return true;
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "Exception caught in FairMQChannel::ValidateChannel: " << e.what();
|
||||
throw ChannelConfigurationError(fair::mq::tools::ToString(e.what()));
|
||||
throw ChannelConfigurationError(tools::ToString(e.what()));
|
||||
}
|
||||
|
||||
void FairMQChannel::Init()
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
|
||||
fSocket = fTransportFactory->CreateSocket(fType, fName);
|
||||
|
||||
@@ -591,14 +659,14 @@ void FairMQChannel::Init()
|
||||
|
||||
bool FairMQChannel::ConnectEndpoint(const string& endpoint)
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
|
||||
return fSocket->Connect(endpoint);
|
||||
}
|
||||
|
||||
bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
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)) {
|
||||
@@ -623,7 +691,7 @@ bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||
}
|
||||
|
||||
size_t pos = endpoint.rfind(':');
|
||||
endpoint = endpoint.substr(0, pos + 1) + fair::mq::tools::ToString(static_cast<int>(randomPort(generator)));
|
||||
endpoint = endpoint.substr(0, pos + 1) + tools::ToString(static_cast<int>(randomPort(generator)));
|
||||
} while (!fSocket->Bind(endpoint));
|
||||
|
||||
return true;
|
||||
@@ -636,7 +704,7 @@ bool FairMQChannel::BindEndpoint(string& endpoint)
|
||||
|
||||
void FairMQChannel::ResetChannel()
|
||||
{
|
||||
lock_guard<mutex> lock(fChannelMutex);
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
fIsValid = false;
|
||||
// TODO: implement channel resetting
|
||||
}
|
||||
|
@@ -9,21 +9,24 @@
|
||||
#ifndef FAIRMQCHANNEL_H_
|
||||
#define FAIRMQCHANNEL_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory> // unique_ptr, shared_ptr
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <utility> // std::move
|
||||
|
||||
#include <FairMQTransportFactory.h>
|
||||
#include <FairMQUnmanagedRegion.h>
|
||||
#include <FairMQSocket.h>
|
||||
#include <fairmq/Transports.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <FairMQParts.h>
|
||||
#include <fairmq/Properties.h>
|
||||
#include <FairMQMessage.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory> // unique_ptr, shared_ptr
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <utility> // std::move
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // int64_t
|
||||
|
||||
class FairMQChannel
|
||||
{
|
||||
friend class FairMQDevice;
|
||||
@@ -32,6 +35,10 @@ class FairMQChannel
|
||||
/// Default constructor
|
||||
FairMQChannel();
|
||||
|
||||
/// Constructor
|
||||
/// @param name Channel name
|
||||
FairMQChannel(const std::string& name);
|
||||
|
||||
/// Constructor
|
||||
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
|
||||
/// @param method Socket method (bind/connect)
|
||||
@@ -52,14 +59,28 @@ class FairMQChannel
|
||||
/// @param factory TransportFactory
|
||||
FairMQChannel(const std::string& name, const std::string& type, const std::string& method, const std::string& address, std::shared_ptr<FairMQTransportFactory> factory);
|
||||
|
||||
FairMQChannel(const std::string& name, int index, const fair::mq::Properties& properties);
|
||||
|
||||
/// Copy Constructor
|
||||
FairMQChannel(const FairMQChannel&);
|
||||
|
||||
/// Copy Constructor (with new name)
|
||||
FairMQChannel(const FairMQChannel&, const std::string& name);
|
||||
|
||||
/// Move constructor
|
||||
FairMQChannel(FairMQChannel&&) = delete;
|
||||
|
||||
/// Assignment operator
|
||||
FairMQChannel& operator=(const FairMQChannel&);
|
||||
|
||||
/// Default destructor
|
||||
virtual ~FairMQChannel() {}
|
||||
/// Move assignment operator
|
||||
FairMQChannel& operator=(FairMQChannel&&) = delete;
|
||||
|
||||
/// Destructor
|
||||
virtual ~FairMQChannel()
|
||||
{
|
||||
// LOG(debug) << "Destroying channel " << fName;
|
||||
}
|
||||
|
||||
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
@@ -81,17 +102,17 @@ class FairMQChannel
|
||||
|
||||
/// Get channel name
|
||||
/// @return Returns full channel name (e.g. "data[0]")
|
||||
std::string GetChannelName() const { return GetName(); } // TODO: deprecate this in favor of following
|
||||
std::string GetName() const;
|
||||
std::string GetChannelName() const __attribute__((deprecated("Use GetName()"))) { return GetName(); }
|
||||
std::string GetName() const ;
|
||||
|
||||
/// Get channel prefix
|
||||
/// @return Returns channel prefix (e.g. "data" in "data[0]")
|
||||
std::string GetChannelPrefix() const { return GetPrefix(); } // TODO: deprecate this in favor of following
|
||||
std::string GetChannelPrefix() const __attribute__((deprecated("Use GetPrefix()"))) { return GetPrefix(); }
|
||||
std::string GetPrefix() const;
|
||||
|
||||
/// Get channel index
|
||||
/// @return Returns channel index (e.g. 0 in "data[0]")
|
||||
std::string GetChannelIndex() const { return GetIndex(); } // TODO: deprecate this in favor of following
|
||||
std::string GetChannelIndex() const __attribute__((deprecated("Use GetIndex()"))) { return GetIndex(); }
|
||||
std::string GetIndex() const;
|
||||
|
||||
/// Get socket type
|
||||
@@ -106,10 +127,14 @@ class FairMQChannel
|
||||
/// @return Returns socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
|
||||
std::string GetAddress() const;
|
||||
|
||||
/// Get channel transport ("default", "zeromq", "nanomsg" or "shmem")
|
||||
/// @return Returns channel transport (e.g. "default", "zeromq", "nanomsg" or "shmem")
|
||||
/// 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 type
|
||||
/// @return Returns channel transport type
|
||||
fair::mq::Transport GetTransportType() const;
|
||||
|
||||
/// Get socket send buffer size (in number of messages)
|
||||
/// @return Returns socket send buffer size (in number of messages)
|
||||
int GetSndBufSize() const;
|
||||
@@ -200,7 +225,7 @@ class FairMQChannel
|
||||
|
||||
/// Set channel name
|
||||
/// @param name Arbitrary channel name
|
||||
void UpdateChannelName(const std::string& name) { UpdateName(name); } // TODO: deprecate this in favor of following
|
||||
void UpdateChannelName(const std::string& name) __attribute__((deprecated("Use UpdateName()"))) { UpdateName(name); }
|
||||
void UpdateName(const std::string& name);
|
||||
|
||||
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
|
||||
@@ -209,10 +234,7 @@ class FairMQChannel
|
||||
|
||||
/// Validates channel configuration
|
||||
/// @return true if channel settings are valid, false otherwise.
|
||||
bool ValidateChannel() // TODO: deprecate this
|
||||
{
|
||||
return Validate();
|
||||
}
|
||||
bool ValidateChannel() __attribute__((deprecated("Use Validate()"))) { return Validate(); }
|
||||
|
||||
/// Validates channel configuration
|
||||
/// @return true if channel settings are valid, false otherwise.
|
||||
@@ -247,17 +269,6 @@ class FairMQChannel
|
||||
return fSocket->Receive(msg, rcvTimeoutInMs);
|
||||
}
|
||||
|
||||
int SendAsync(FairMQMessagePtr& msg) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(msg, timeout);")))
|
||||
{
|
||||
CheckSendCompatibility(msg);
|
||||
return fSocket->Send(msg, 0);
|
||||
}
|
||||
int ReceiveAsync(FairMQMessagePtr& msg) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(msg, timeout);")))
|
||||
{
|
||||
CheckReceiveCompatibility(msg);
|
||||
return fSocket->Receive(msg, 0);
|
||||
}
|
||||
|
||||
/// 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)
|
||||
@@ -278,17 +289,6 @@ class FairMQChannel
|
||||
return fSocket->Receive(msgVec, rcvTimeoutInMs);
|
||||
}
|
||||
|
||||
int64_t SendAsync(std::vector<FairMQMessagePtr>& msgVec) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(msgVec, timeout);")))
|
||||
{
|
||||
CheckSendCompatibility(msgVec);
|
||||
return fSocket->Send(msgVec, 0);
|
||||
}
|
||||
int64_t ReceiveAsync(std::vector<FairMQMessagePtr>& msgVec) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(msgVec, timeout);")))
|
||||
{
|
||||
CheckReceiveCompatibility(msgVec);
|
||||
return fSocket->Receive(msgVec, 0);
|
||||
}
|
||||
|
||||
/// 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)
|
||||
@@ -307,16 +307,6 @@ class FairMQChannel
|
||||
return Receive(parts.fParts, rcvTimeoutInMs);
|
||||
}
|
||||
|
||||
int64_t SendAsync(FairMQParts& parts) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(parts, timeout);")))
|
||||
{
|
||||
return Send(parts.fParts, 0);
|
||||
}
|
||||
|
||||
int64_t ReceiveAsync(FairMQParts& parts) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(parts, timeout);")))
|
||||
{
|
||||
return Receive(parts.fParts, 0);
|
||||
}
|
||||
|
||||
unsigned long GetBytesTx() const { return fSocket->GetBytesTx(); }
|
||||
unsigned long GetBytesRx() const { return fSocket->GetBytesRx(); }
|
||||
unsigned long GetMessagesTx() const { return fSocket->GetMessagesTx(); }
|
||||
@@ -345,16 +335,33 @@ class FairMQChannel
|
||||
return Transport()->NewStaticMessage(data);
|
||||
}
|
||||
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr)
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
|
||||
{
|
||||
return Transport()->CreateUnmanagedRegion(size, callback);
|
||||
return Transport()->CreateUnmanagedRegion(size, callback, path, flags);
|
||||
}
|
||||
|
||||
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::DEFAULT;
|
||||
static constexpr const char* DefaultTransportName = "default";
|
||||
static constexpr const char* DefaultName = "";
|
||||
static constexpr const char* DefaultType = "unspecified";
|
||||
static constexpr const char* DefaultMethod = "unspecified";
|
||||
static constexpr const char* DefaultAddress = "unspecified";
|
||||
static constexpr int DefaultSndBufSize = 1000;
|
||||
static constexpr int DefaultRcvBufSize = 1000;
|
||||
static constexpr int DefaultSndKernelSize = 0;
|
||||
static constexpr int DefaultRcvKernelSize = 0;
|
||||
static constexpr int DefaultLinger = 500;
|
||||
static constexpr int DefaultRateLogging = 1;
|
||||
static constexpr int DefaultPortRangeMin = 22000;
|
||||
static constexpr int DefaultPortRangeMax = 23000;
|
||||
static constexpr bool DefaultAutoBind = true;
|
||||
|
||||
private:
|
||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory;
|
||||
fair::mq::Transport fTransportType;
|
||||
std::unique_ptr<FairMQSocket> fSocket;
|
||||
|
||||
std::string fName;
|
||||
std::string fType;
|
||||
std::string fMethod;
|
||||
std::string fAddress;
|
||||
@@ -368,23 +375,17 @@ class FairMQChannel
|
||||
int fPortRangeMax;
|
||||
bool fAutoBind;
|
||||
|
||||
std::string fName;
|
||||
std::atomic<bool> fIsValid;
|
||||
|
||||
// use static mutex to make the class easily copyable
|
||||
// implication: same mutex is used for all instances of the class
|
||||
// this does not hurt much, because mutex is used only during initialization with very low contention
|
||||
// possible TODO: improve this
|
||||
static std::mutex fChannelMutex;
|
||||
bool fIsValid;
|
||||
|
||||
bool fMultipart;
|
||||
bool fModified;
|
||||
bool fReset;
|
||||
|
||||
mutable std::mutex fMtx;
|
||||
|
||||
void CheckSendCompatibility(FairMQMessagePtr& msg)
|
||||
{
|
||||
if (fTransportType != msg->GetType()) {
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr msgWrapper(NewMessage(
|
||||
msg->GetData(),
|
||||
msg->GetSize(),
|
||||
@@ -400,7 +401,7 @@ class FairMQChannel
|
||||
{
|
||||
for (auto& msg : msgVec) {
|
||||
if (fTransportType != msg->GetType()) {
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
|
||||
FairMQMessagePtr msgWrapper(NewMessage(
|
||||
msg->GetData(),
|
||||
msg->GetSize(),
|
||||
@@ -416,7 +417,6 @@ class FairMQChannel
|
||||
void CheckReceiveCompatibility(FairMQMessagePtr& msg)
|
||||
{
|
||||
if (fTransportType != msg->GetType()) {
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr newMsg(NewMessage());
|
||||
msg = move(newMsg);
|
||||
}
|
||||
@@ -426,7 +426,7 @@ class FairMQChannel
|
||||
{
|
||||
for (auto& msg : msgVec) {
|
||||
if (fTransportType != msg->GetType()) {
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
|
||||
FairMQMessagePtr newMsg(NewMessage());
|
||||
msg = move(newMsg);
|
||||
}
|
||||
@@ -438,6 +438,7 @@ class FairMQChannel
|
||||
fTransportFactory = factory;
|
||||
fTransportType = factory->GetType();
|
||||
}
|
||||
|
||||
auto SetModified(const bool modified) -> void;
|
||||
};
|
||||
|
||||
|
@@ -8,19 +8,15 @@
|
||||
|
||||
#include <FairMQDevice.h>
|
||||
|
||||
#include <fairmq/tools/RateLimit.h>
|
||||
#include <fairmq/tools/Network.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp> // join/split
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <cstdlib>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <future>
|
||||
#include <algorithm> // std::max
|
||||
@@ -56,34 +52,61 @@ static map<int, Transition> backwardsCompatibilityChangeStateHelper =
|
||||
{ FairMQDevice::Event::ERROR_FOUND, Transition::ErrorFound }
|
||||
};
|
||||
|
||||
constexpr const char* FairMQDevice::DefaultId;
|
||||
constexpr int FairMQDevice::DefaultIOThreads;
|
||||
constexpr const char* FairMQDevice::DefaultTransportName;
|
||||
constexpr fair::mq::Transport FairMQDevice::DefaultTransportType;
|
||||
constexpr const char* FairMQDevice::DefaultNetworkInterface;
|
||||
constexpr int FairMQDevice::DefaultInitTimeout;
|
||||
constexpr uint64_t FairMQDevice::DefaultMaxRunTime;
|
||||
constexpr float FairMQDevice::DefaultRate;
|
||||
constexpr const char* FairMQDevice::DefaultSession;
|
||||
|
||||
struct StateSubscription
|
||||
{
|
||||
fair::mq::StateMachine& fStateMachine;
|
||||
fair::mq::StateQueue& fStateQueue;
|
||||
string fId;
|
||||
|
||||
explicit StateSubscription(const string& id, fair::mq::StateMachine& stateMachine, fair::mq::StateQueue& stateQueue)
|
||||
: fStateMachine(stateMachine)
|
||||
, fStateQueue(stateQueue)
|
||||
, fId(id)
|
||||
{
|
||||
fStateMachine.SubscribeToStateChange(fId, [&](fair::mq::State state) {
|
||||
fStateQueue.Push(state);
|
||||
});
|
||||
}
|
||||
|
||||
~StateSubscription() {
|
||||
fStateMachine.UnsubscribeFromStateChange(fId);
|
||||
}
|
||||
};
|
||||
|
||||
FairMQDevice::FairMQDevice()
|
||||
: FairMQDevice(nullptr, {0, 0, 0})
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
FairMQDevice::FairMQDevice(FairMQProgOptions& config)
|
||||
FairMQDevice::FairMQDevice(ProgOptions& config)
|
||||
: FairMQDevice(&config, {0, 0, 0})
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
FairMQDevice::FairMQDevice(const tools::Version version)
|
||||
: FairMQDevice(nullptr, version)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
FairMQDevice::FairMQDevice(FairMQProgOptions& config, const tools::Version version)
|
||||
FairMQDevice::FairMQDevice(ProgOptions& config, const tools::Version version)
|
||||
: FairMQDevice(&config, version)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
FairMQDevice::FairMQDevice(FairMQProgOptions* config, const tools::Version version)
|
||||
FairMQDevice::FairMQDevice(ProgOptions* config, const tools::Version version)
|
||||
: fTransportFactory(nullptr)
|
||||
, fTransports()
|
||||
, fChannels()
|
||||
, fInternalConfig(config ? nullptr : tools::make_unique<FairMQProgOptions>())
|
||||
, fInternalConfig(config ? nullptr : tools::make_unique<ProgOptions>())
|
||||
, fConfig(config ? config : fInternalConfig.get())
|
||||
, fId()
|
||||
, fDefaultTransportType(fair::mq::Transport::ZMQ)
|
||||
, fId(DefaultId)
|
||||
, fDefaultTransportType(DefaultTransportType)
|
||||
, fStateMachine()
|
||||
, fUninitializedBindingChannels()
|
||||
, fUninitializedConnectingChannels()
|
||||
@@ -96,9 +119,12 @@ FairMQDevice::FairMQDevice(FairMQProgOptions* config, const tools::Version versi
|
||||
, fMultitransportMutex()
|
||||
, fMultitransportProceed(false)
|
||||
, fVersion(version)
|
||||
, fRate(0.)
|
||||
, fMaxRunRuntimeInS(0)
|
||||
, fRate(DefaultRate)
|
||||
, fMaxRunRuntimeInS(DefaultMaxRunTime)
|
||||
, fInitializationTimeoutInS(DefaultInitTimeout)
|
||||
, fRawCmdLineArgs()
|
||||
, fTransitionMtx()
|
||||
, fTransitioning(false)
|
||||
{
|
||||
SubscribeToNewTransition("device", [&](Transition transition) {
|
||||
LOG(trace) << "device notified on new transition: " << transition;
|
||||
@@ -115,11 +141,7 @@ FairMQDevice::FairMQDevice(FairMQProgOptions* config, const tools::Version versi
|
||||
fStateMachine.HandleStates([&](fair::mq::State state) {
|
||||
LOG(trace) << "device notified on new state: " << state;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(fStatesMtx);
|
||||
fStates.push(state);
|
||||
}
|
||||
fStatesCV.notify_all();
|
||||
fStateQueue.Push(state);
|
||||
|
||||
switch (state) {
|
||||
case fair::mq::State::InitializingDevice:
|
||||
@@ -155,27 +177,71 @@ FairMQDevice::FairMQDevice(FairMQProgOptions* config, const tools::Version versi
|
||||
fStateMachine.Start();
|
||||
}
|
||||
|
||||
fair::mq::State FairMQDevice::WaitForNextState()
|
||||
void FairMQDevice::TransitionTo(const fair::mq::State s)
|
||||
{
|
||||
unique_lock<mutex> lock(fStatesMtx);
|
||||
while (fStates.empty()) {
|
||||
fStatesCV.wait_for(lock, chrono::milliseconds(50));
|
||||
{
|
||||
lock_guard<mutex> lock(fTransitionMtx);
|
||||
if (fTransitioning) {
|
||||
LOG(debug) << "Attempting a transition with TransitionTo() while another one is already in progress";
|
||||
throw OngoingTransition("Attempting a transition with TransitionTo() while another one is already in progress");
|
||||
}
|
||||
fTransitioning = true;
|
||||
}
|
||||
|
||||
auto result = fStates.front();
|
||||
using fair::mq::State;
|
||||
|
||||
if (result == fair::mq::State::Error) {
|
||||
throw DeviceStateError("Device transitioned to error state.");
|
||||
StateQueue sq;
|
||||
StateSubscription ss(tools::ToString(fId, ".TransitionTo"), fStateMachine, sq);
|
||||
|
||||
State currentState = GetCurrentState();
|
||||
|
||||
while (s != currentState) {
|
||||
switch (currentState) {
|
||||
case State::Idle:
|
||||
if (s == State::Exiting) { ChangeState(Transition::End); }
|
||||
else { ChangeState(Transition::InitDevice); }
|
||||
break;
|
||||
case State::InitializingDevice:
|
||||
ChangeState(Transition::CompleteInit);
|
||||
break;
|
||||
case State::Initialized:
|
||||
if (s == State::Exiting || s == State::Idle) { ChangeState(Transition::ResetDevice); }
|
||||
else { ChangeState(Transition::Bind); }
|
||||
break;
|
||||
case State::Bound:
|
||||
if (s == State::DeviceReady || s == State::Ready || s == State::Running) { ChangeState(Transition::Connect); }
|
||||
else { ChangeState(Transition::ResetDevice); }
|
||||
break;
|
||||
case State::DeviceReady:
|
||||
if (s == State::Running || s == State::Ready) { ChangeState(Transition::InitTask); }
|
||||
else { ChangeState(Transition::ResetDevice); }
|
||||
break;
|
||||
case State::Ready:
|
||||
if (s == State::Running) { ChangeState(Transition::Run); }
|
||||
else { ChangeState(Transition::ResetTask); }
|
||||
break;
|
||||
case State::Running:
|
||||
ChangeState(Transition::Stop);
|
||||
break;
|
||||
case State::Binding:
|
||||
case State::Connecting:
|
||||
case State::InitializingTask:
|
||||
case State::ResettingDevice:
|
||||
case State::ResettingTask:
|
||||
LOG(debug) << "TransitionTo ignoring state: " << currentState << " (expected, automatic transition).";
|
||||
break;
|
||||
default:
|
||||
LOG(debug) << "TransitionTo ignoring state: " << currentState;
|
||||
break;
|
||||
}
|
||||
|
||||
fStates.pop();
|
||||
currentState = sq.WaitForNext();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FairMQDevice::WaitForState(fair::mq::State state)
|
||||
{
|
||||
while (WaitForNextState() != state) {}
|
||||
{
|
||||
lock_guard<mutex> lock(fTransitionMtx);
|
||||
fTransitioning = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FairMQDevice::ChangeState(const int transition)
|
||||
@@ -190,69 +256,65 @@ void FairMQDevice::WaitForEndOfState(Transition transition)
|
||||
|
||||
void FairMQDevice::InitWrapper()
|
||||
{
|
||||
// run initialization once CompleteInit transition is requested
|
||||
fStateMachine.WaitForPendingState();
|
||||
|
||||
fId = fConfig->GetValue<string>("id");
|
||||
fId = fConfig->GetProperty<string>("id", DefaultId);
|
||||
|
||||
Init();
|
||||
|
||||
fRate = fConfig->GetValue<float>("rate");
|
||||
fMaxRunRuntimeInS = fConfig->GetValue<uint64_t>("max-run-time");
|
||||
fRate = fConfig->GetProperty<float>("rate", DefaultRate);
|
||||
fMaxRunRuntimeInS = fConfig->GetProperty<uint64_t>("max-run-time", DefaultMaxRunTime);
|
||||
fInitializationTimeoutInS = fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout);
|
||||
|
||||
try {
|
||||
fDefaultTransportType = fair::mq::TransportTypes.at(fConfig->GetValue<string>("transport"));
|
||||
fDefaultTransportType = fair::mq::TransportTypes.at(fConfig->GetProperty<string>("transport", DefaultTransportName));
|
||||
} catch (const exception& e) {
|
||||
LOG(error) << "exception: " << e.what();
|
||||
LOG(error) << "invalid transport type provided: " << fConfig->GetValue<string>("transport");
|
||||
LOG(error) << "invalid transport type provided: " << fConfig->GetProperty<string>("transport", "not provided");
|
||||
throw;
|
||||
}
|
||||
|
||||
for (auto& c : fConfig->GetFairMQMap()) {
|
||||
if (fChannels.find(c.first) == fChannels.end()) {
|
||||
LOG(debug) << "Inserting new device channel from config: " << c.first;
|
||||
fChannels.insert(c);
|
||||
} else {
|
||||
LOG(debug) << "Updating existing device channel from config: " << c.first;
|
||||
fChannels[c.first] = c.second;
|
||||
unordered_map<string, int> infos = fConfig->GetChannelInfo();
|
||||
for (const auto& info : infos) {
|
||||
for (int i = 0; i < info.second; ++i) {
|
||||
fChannels[info.first].emplace_back(info.first, i, fConfig->GetPropertiesStartingWith(tools::ToString("chans.", info.first, ".", i, ".")));
|
||||
}
|
||||
}
|
||||
|
||||
LOG(debug) << "Setting '" << fair::mq::TransportNames.at(fDefaultTransportType) << "' as default transport for the device";
|
||||
fTransportFactory = AddTransport(fDefaultTransportType);
|
||||
|
||||
string networkInterface = fConfig->GetValue<string>("network-interface");
|
||||
string networkInterface = fConfig->GetProperty<string>("network-interface", DefaultNetworkInterface);
|
||||
|
||||
// Fill the uninitialized channel containers
|
||||
for (auto& mi : fChannels) {
|
||||
for (auto& channel : fChannels) {
|
||||
int subChannelIndex = 0;
|
||||
for (auto& vi : mi.second) {
|
||||
// set channel name: name + vector index
|
||||
vi.fName = tools::ToString(mi.first, "[", subChannelIndex, "]");
|
||||
|
||||
for (auto& subChannel : channel.second) {
|
||||
// set channel transport
|
||||
LOG(debug) << "Initializing transport for channel " << vi.fName << ": " << fair::mq::TransportNames.at(vi.fTransportType);
|
||||
vi.InitTransport(AddTransport(vi.fTransportType));
|
||||
LOG(debug) << "Initializing transport for channel " << subChannel.fName << ": " << fair::mq::TransportNames.at(subChannel.fTransportType);
|
||||
subChannel.InitTransport(AddTransport(subChannel.fTransportType));
|
||||
|
||||
if (vi.fMethod == "bind") {
|
||||
if (subChannel.fMethod == "bind") {
|
||||
// if binding address is not specified, try getting it from the configured network interface
|
||||
if (vi.fAddress == "unspecified" || vi.fAddress == "") {
|
||||
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();
|
||||
}
|
||||
vi.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
|
||||
subChannel.fAddress = "tcp://" + tools::getInterfaceIP(networkInterface) + ":1";
|
||||
}
|
||||
// fill the uninitialized list
|
||||
fUninitializedBindingChannels.push_back(&vi);
|
||||
} else if (vi.fMethod == "connect") {
|
||||
fUninitializedBindingChannels.push_back(&subChannel);
|
||||
} else if (subChannel.fMethod == "connect") {
|
||||
// fill the uninitialized list
|
||||
fUninitializedConnectingChannels.push_back(&vi);
|
||||
} else if (vi.fAddress.find_first_of("@+>") != string::npos) {
|
||||
fUninitializedConnectingChannels.push_back(&subChannel);
|
||||
} else if (subChannel.fAddress.find_first_of("@+>") != string::npos) {
|
||||
// fill the uninitialized list
|
||||
fUninitializedConnectingChannels.push_back(&vi);
|
||||
fUninitializedConnectingChannels.push_back(&subChannel);
|
||||
} else {
|
||||
LOG(error) << "Cannot update configuration. Socket method (bind/connect) for channel '" << vi.fName << "' not specified.";
|
||||
throw runtime_error(tools::ToString("Cannot update configuration. Socket method (bind/connect) for channel ", vi.fName, " not specified."));
|
||||
LOG(error) << "Cannot update configuration. Socket method (bind/connect) for channel '" << subChannel.fName << "' not specified.";
|
||||
throw runtime_error(tools::ToString("Cannot update configuration. Socket method (bind/connect) for channel ", subChannel.fName, " not specified."));
|
||||
}
|
||||
|
||||
subChannelIndex++;
|
||||
@@ -280,12 +342,10 @@ void FairMQDevice::BindWrapper()
|
||||
|
||||
void FairMQDevice::ConnectWrapper()
|
||||
{
|
||||
int initializationTimeoutInS = fConfig->GetValue<int>("initialization-timeout");
|
||||
|
||||
// go over the list of channels until all are initialized (and removed from the uninitialized list)
|
||||
int numAttempts = 1;
|
||||
auto sleepTimeInMS = 50;
|
||||
auto maxAttempts = initializationTimeoutInS * 1000 / sleepTimeInMS;
|
||||
auto maxAttempts = fInitializationTimeoutInS * 1000 / sleepTimeInMS;
|
||||
// first attempt
|
||||
AttachChannels(fUninitializedConnectingChannels);
|
||||
// if not all channels could be connected, update their address values from config and retry
|
||||
@@ -293,16 +353,16 @@ void FairMQDevice::ConnectWrapper()
|
||||
this_thread::sleep_for(chrono::milliseconds(sleepTimeInMS));
|
||||
|
||||
for (auto& chan : fUninitializedConnectingChannels) {
|
||||
string key{"chans." + chan->GetChannelPrefix() + "." + chan->GetChannelIndex() + ".address"};
|
||||
string newAddress = fConfig->GetValue<string>(key);
|
||||
string key{"chans." + chan->GetPrefix() + "." + chan->GetIndex() + ".address"};
|
||||
string newAddress = fConfig->GetProperty<string>(key);
|
||||
if (newAddress != chan->GetAddress()) {
|
||||
chan->UpdateAddress(newAddress);
|
||||
}
|
||||
}
|
||||
|
||||
if (numAttempts++ > maxAttempts) {
|
||||
LOG(error) << "could not connect all channels after " << initializationTimeoutInS << " attempts";
|
||||
throw runtime_error(tools::ToString("could not connect all channels after ", initializationTimeoutInS, " attempts"));
|
||||
LOG(error) << "could not connect all channels after " << fInitializationTimeoutInS << " attempts";
|
||||
throw runtime_error(tools::ToString("could not connect all channels after ", fInitializationTimeoutInS, " attempts"));
|
||||
}
|
||||
|
||||
AttachChannels(fUninitializedConnectingChannels);
|
||||
@@ -322,7 +382,7 @@ void FairMQDevice::AttachChannels(vector<FairMQChannel*>& chans)
|
||||
auto itr = chans.begin();
|
||||
|
||||
while (itr != chans.end()) {
|
||||
if ((*itr)->ValidateChannel()) {
|
||||
if ((*itr)->Validate()) {
|
||||
(*itr)->Init();
|
||||
if (AttachChannel(**itr)) {
|
||||
(*itr)->SetModified(false);
|
||||
@@ -405,7 +465,7 @@ bool FairMQDevice::AttachChannel(FairMQChannel& chan)
|
||||
chan.UpdateAddress(newAddress);
|
||||
|
||||
// update address in the config, it could have been modified during binding
|
||||
fConfig->SetValue({"chans." + chan.GetPrefix() + "." + chan.GetIndex() + ".address"}, newAddress);
|
||||
fConfig->SetProperty({"chans." + chan.GetPrefix() + "." + chan.GetIndex() + ".address"}, newAddress);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -418,32 +478,6 @@ void FairMQDevice::InitTaskWrapper()
|
||||
ChangeState(Transition::Auto);
|
||||
}
|
||||
|
||||
bool FairMQDevice::SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs)
|
||||
{
|
||||
return lhs.fAddress < rhs.fAddress;
|
||||
}
|
||||
|
||||
void FairMQDevice::SortChannel(const string& name, const bool reindex)
|
||||
{
|
||||
if (fChannels.find(name) != fChannels.end())
|
||||
{
|
||||
sort(fChannels.at(name).begin(), fChannels.at(name).end(), SortSocketsByAddress);
|
||||
|
||||
if (reindex)
|
||||
{
|
||||
for (auto vi = fChannels.at(name).begin(); vi != fChannels.at(name).end(); ++vi)
|
||||
{
|
||||
// set channel name: name + vector index
|
||||
vi->fName = tools::ToString(name, "[", vi - fChannels.at(name).begin(), "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "Sorting failed: no channel with the name \"" << name << "\".";
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQDevice::RunWrapper()
|
||||
{
|
||||
LOG(info) << "DEVICE: Running...";
|
||||
@@ -716,7 +750,7 @@ shared_ptr<FairMQTransportFactory> FairMQDevice::AddTransport(fair::mq::Transpor
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQDevice::SetConfig(FairMQProgOptions& config)
|
||||
void FairMQDevice::SetConfig(ProgOptions& config)
|
||||
{
|
||||
fInternalConfig.reset();
|
||||
fConfig = &config;
|
||||
@@ -724,7 +758,7 @@ void FairMQDevice::SetConfig(FairMQProgOptions& config)
|
||||
|
||||
void FairMQDevice::LogSocketRates()
|
||||
{
|
||||
vector<FairMQSocket*> filteredSockets;
|
||||
vector<FairMQChannel*> filteredChannels;
|
||||
vector<string> filteredChannelNames;
|
||||
vector<int> logIntervals;
|
||||
vector<int> intervalCounters;
|
||||
@@ -732,40 +766,40 @@ void FairMQDevice::LogSocketRates()
|
||||
size_t chanNameLen = 0;
|
||||
|
||||
// iterate over the channels map
|
||||
for (const auto& mi : fChannels) {
|
||||
for (auto& channel : fChannels) {
|
||||
// iterate over the channels vector
|
||||
for (auto vi = (mi.second).begin(); vi != (mi.second).end(); ++vi) {
|
||||
if (vi->fRateLogging > 0) {
|
||||
filteredSockets.push_back(vi->fSocket.get());
|
||||
logIntervals.push_back(vi->fRateLogging);
|
||||
for (auto& subChannel : channel.second) {
|
||||
if (subChannel.fRateLogging > 0) {
|
||||
filteredChannels.push_back(&subChannel);
|
||||
logIntervals.push_back(subChannel.fRateLogging);
|
||||
intervalCounters.push_back(0);
|
||||
filteredChannelNames.push_back(tools::ToString(mi.first, "[", vi - (mi.second).begin(), "]"));
|
||||
filteredChannelNames.push_back(subChannel.GetName());
|
||||
chanNameLen = max(chanNameLen, filteredChannelNames.back().length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<unsigned long> bytesIn(filteredSockets.size());
|
||||
vector<unsigned long> msgIn(filteredSockets.size());
|
||||
vector<unsigned long> bytesOut(filteredSockets.size());
|
||||
vector<unsigned long> msgOut(filteredSockets.size());
|
||||
vector<unsigned long> bytesIn(filteredChannels.size());
|
||||
vector<unsigned long> msgIn(filteredChannels.size());
|
||||
vector<unsigned long> bytesOut(filteredChannels.size());
|
||||
vector<unsigned long> msgOut(filteredChannels.size());
|
||||
|
||||
vector<unsigned long> bytesInNew(filteredSockets.size());
|
||||
vector<unsigned long> msgInNew(filteredSockets.size());
|
||||
vector<unsigned long> bytesOutNew(filteredSockets.size());
|
||||
vector<unsigned long> msgOutNew(filteredSockets.size());
|
||||
vector<unsigned long> bytesInNew(filteredChannels.size());
|
||||
vector<unsigned long> msgInNew(filteredChannels.size());
|
||||
vector<unsigned long> bytesOutNew(filteredChannels.size());
|
||||
vector<unsigned long> msgOutNew(filteredChannels.size());
|
||||
|
||||
vector<double> mbPerSecIn(filteredSockets.size());
|
||||
vector<double> msgPerSecIn(filteredSockets.size());
|
||||
vector<double> mbPerSecOut(filteredSockets.size());
|
||||
vector<double> msgPerSecOut(filteredSockets.size());
|
||||
vector<double> mbPerSecIn(filteredChannels.size());
|
||||
vector<double> msgPerSecIn(filteredChannels.size());
|
||||
vector<double> mbPerSecOut(filteredChannels.size());
|
||||
vector<double> msgPerSecOut(filteredChannels.size());
|
||||
|
||||
int i = 0;
|
||||
for (const auto& vi : filteredSockets) {
|
||||
bytesIn.at(i) = vi->GetBytesRx();
|
||||
bytesOut.at(i) = vi->GetBytesTx();
|
||||
msgIn.at(i) = vi->GetMessagesRx();
|
||||
msgOut.at(i) = vi->GetMessagesTx();
|
||||
for (const auto& channel : filteredChannels) {
|
||||
bytesIn.at(i) = channel->GetBytesRx();
|
||||
bytesOut.at(i) = channel->GetBytesTx();
|
||||
msgIn.at(i) = channel->GetMessagesRx();
|
||||
msgOut.at(i) = channel->GetMessagesTx();
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -782,17 +816,17 @@ void FairMQDevice::LogSocketRates()
|
||||
|
||||
i = 0;
|
||||
|
||||
for (const auto& vi : filteredSockets) {
|
||||
for (const auto& channel : filteredChannels) {
|
||||
intervalCounters.at(i)++;
|
||||
|
||||
if (intervalCounters.at(i) == logIntervals.at(i)) {
|
||||
intervalCounters.at(i) = 0;
|
||||
|
||||
if (msSinceLastLog > 0) {
|
||||
bytesInNew.at(i) = vi->GetBytesRx();
|
||||
msgInNew.at(i) = vi->GetMessagesRx();
|
||||
bytesOutNew.at(i) = vi->GetBytesTx();
|
||||
msgOutNew.at(i) = vi->GetMessagesTx();
|
||||
bytesInNew.at(i) = channel->GetBytesRx();
|
||||
msgInNew.at(i) = channel->GetMessagesRx();
|
||||
bytesOutNew.at(i) = channel->GetBytesTx();
|
||||
msgOutNew.at(i) = channel->GetMessagesTx();
|
||||
|
||||
mbPerSecIn.at(i) = (static_cast<double>(bytesInNew.at(i) - bytesIn.at(i)) / (1000. * 1000.)) / static_cast<double>(msSinceLastLog) * 1000.;
|
||||
msgPerSecIn.at(i) = static_cast<double>(msgInNew.at(i) - msgIn.at(i)) / static_cast<double>(msSinceLastLog) * 1000.;
|
||||
@@ -822,8 +856,8 @@ void FairMQDevice::LogSocketRates()
|
||||
|
||||
void FairMQDevice::UnblockTransports()
|
||||
{
|
||||
for (auto& t : fTransports) {
|
||||
t.second->Interrupt();
|
||||
for (auto& transport : fTransports) {
|
||||
transport.second->Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,21 +870,15 @@ void FairMQDevice::ResetTaskWrapper()
|
||||
|
||||
void FairMQDevice::ResetWrapper()
|
||||
{
|
||||
for (auto& t : fTransports) {
|
||||
t.second->Reset();
|
||||
}
|
||||
|
||||
// iterate over the channels map
|
||||
for (auto& mi : fChannels) {
|
||||
// iterate over the channels vector
|
||||
for (auto& vi : mi.second) {
|
||||
// vi.fReset = true;
|
||||
vi.fSocket.reset(); // destroy FairMQSocket
|
||||
}
|
||||
for (auto& transport : fTransports) {
|
||||
transport.second->Reset();
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
fChannels.clear();
|
||||
fTransports.clear();
|
||||
fTransportFactory.reset();
|
||||
ChangeState(Transition::Auto);
|
||||
}
|
||||
|
||||
|
@@ -12,38 +12,44 @@
|
||||
#include <StateMachine.h>
|
||||
#include <FairMQTransportFactory.h>
|
||||
#include <fairmq/Transports.h>
|
||||
#include <fairmq/StateQueue.h>
|
||||
|
||||
#include <FairMQSocket.h>
|
||||
#include <FairMQChannel.h>
|
||||
#include <FairMQMessage.h>
|
||||
#include <FairMQParts.h>
|
||||
#include <FairMQUnmanagedRegion.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <options/FairMQProgOptions.h>
|
||||
#include <fairmq/ProgOptions.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory> // unique_ptr
|
||||
#include <algorithm> // std::sort()
|
||||
#include <algorithm> // find
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <assert.h> // static_assert
|
||||
#include <type_traits> // is_trivially_copyable
|
||||
#include <stdexcept>
|
||||
#include <queue>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <utility> // pair
|
||||
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/Version.h>
|
||||
|
||||
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
|
||||
using InputMsgCallback = std::function<bool(FairMQMessagePtr&, int)>;
|
||||
using InputMultipartCallback = std::function<bool(FairMQParts&, int)>;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
struct OngoingTransition : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
}
|
||||
}
|
||||
|
||||
class FairMQDevice
|
||||
{
|
||||
friend class FairMQChannel;
|
||||
@@ -83,17 +89,17 @@ class FairMQDevice
|
||||
|
||||
/// Default constructor
|
||||
FairMQDevice();
|
||||
/// Constructor with external FairMQProgOptions
|
||||
FairMQDevice(FairMQProgOptions& config);
|
||||
/// Constructor with external fair::mq::ProgOptions
|
||||
FairMQDevice(fair::mq::ProgOptions& config);
|
||||
|
||||
/// Constructor that sets the version
|
||||
FairMQDevice(const fair::mq::tools::Version version);
|
||||
|
||||
/// Constructor that sets the version and external FairMQProgOptions
|
||||
FairMQDevice(FairMQProgOptions& config, const fair::mq::tools::Version version);
|
||||
/// Constructor that sets the version and external fair::mq::ProgOptions
|
||||
FairMQDevice(fair::mq::ProgOptions& config, const fair::mq::tools::Version version);
|
||||
|
||||
private:
|
||||
FairMQDevice(FairMQProgOptions* config, const fair::mq::tools::Version version);
|
||||
FairMQDevice(fair::mq::ProgOptions* config, const fair::mq::tools::Version version);
|
||||
|
||||
public:
|
||||
/// Copy constructor (disabled)
|
||||
@@ -106,11 +112,6 @@ class FairMQDevice
|
||||
/// Outputs the socket transfer rates
|
||||
virtual void LogSocketRates();
|
||||
|
||||
/// Sorts a channel by address, with optional reindexing of the sorted values
|
||||
/// @param name Channel name
|
||||
/// @param reindex Should reindexing be done
|
||||
void SortChannel(const std::string& name, const bool reindex = true);
|
||||
|
||||
template<typename Serializer, typename DataType, typename... Args>
|
||||
void Serialize(FairMQMessage& msg, DataType&& data, Args&&... args) const
|
||||
{
|
||||
@@ -145,15 +146,6 @@ class FairMQDevice
|
||||
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs);
|
||||
}
|
||||
|
||||
int SendAsync(FairMQMessagePtr& msg, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(msg, \"channelA\", subchannelIndex, timeout);")))
|
||||
{
|
||||
return GetChannel(channel, index).Send(msg, 0);
|
||||
}
|
||||
int ReceiveAsync(FairMQMessagePtr& msg, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(msg, \"channelA\", subchannelIndex, timeout);")))
|
||||
{
|
||||
return GetChannel(channel, index).Receive(msg, 0);
|
||||
}
|
||||
|
||||
/// Shorthand method to send FairMQParts on `chan` at index `i`
|
||||
/// @param parts parts reference
|
||||
/// @param chan channel name
|
||||
@@ -176,15 +168,6 @@ class FairMQDevice
|
||||
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs);
|
||||
}
|
||||
|
||||
int64_t SendAsync(FairMQParts& parts, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Send, use timeout version with timeout of 0: Send(parts, \"channelA\", subchannelIndex, timeout);")))
|
||||
{
|
||||
return GetChannel(channel, index).Send(parts.fParts, 0);
|
||||
}
|
||||
int64_t ReceiveAsync(FairMQParts& parts, const std::string& channel, const int index = 0) __attribute__((deprecated("For non-blocking Receive, use timeout version with timeout of 0: Receive(parts, \"channelA\", subchannelIndex, timeout);")))
|
||||
{
|
||||
return GetChannel(channel, index).Receive(parts.fParts, 0);
|
||||
}
|
||||
|
||||
/// @brief Getter for default transport factory
|
||||
auto Transport() const -> FairMQTransportFactory*
|
||||
{
|
||||
@@ -240,9 +223,9 @@ class FairMQDevice
|
||||
}
|
||||
|
||||
// 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)
|
||||
FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(const std::string& channel, int index, const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0)
|
||||
{
|
||||
return GetChannel(channel, index).NewUnmanagedRegion(size, callback);
|
||||
return GetChannel(channel, index).NewUnmanagedRegion(size, callback, path, flags);
|
||||
}
|
||||
|
||||
template<typename ...Ts>
|
||||
@@ -288,26 +271,18 @@ class FairMQDevice
|
||||
return channels.at(0)->Transport()->CreatePoller(channels);
|
||||
}
|
||||
|
||||
/// Waits for the first initialization run to finish
|
||||
void WaitForInitialValidation() __attribute__((deprecated("This method will have no effect in future versions and will be removed. Instead subscribe for state changes and inspect configuration values."))) {}
|
||||
|
||||
/// Adds a transport to the device if it doesn't exist
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
|
||||
|
||||
/// Assigns config to the device
|
||||
void SetConfig(FairMQProgOptions& config);
|
||||
void SetConfig(fair::mq::ProgOptions& config);
|
||||
/// Get pointer to the config
|
||||
FairMQProgOptions* GetConfig() const
|
||||
fair::mq::ProgOptions* GetConfig() const
|
||||
{
|
||||
return fConfig;
|
||||
}
|
||||
|
||||
/// Implements the sort algorithm used in SortChannel()
|
||||
/// @param lhs Right hand side value for comparison
|
||||
/// @param rhs Left hand side value for comparison
|
||||
static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs);
|
||||
|
||||
// overload to easily bind member functions
|
||||
template<typename T>
|
||||
void OnData(const std::string& channelName, bool (T::* memberFunction)(FairMQMessagePtr& msg, int index))
|
||||
@@ -399,23 +374,23 @@ class FairMQDevice
|
||||
|
||||
const fair::mq::tools::Version GetVersion() const { return fVersion; }
|
||||
|
||||
void SetNumIoThreads(int numIoThreads) { fConfig->SetValue<int>("io-threads", numIoThreads);}
|
||||
int GetNumIoThreads() const { return fConfig->GetValue<int>("io-threads"); }
|
||||
void SetNumIoThreads(int numIoThreads) { fConfig->SetProperty("io-threads", numIoThreads);}
|
||||
int GetNumIoThreads() const { return fConfig->GetProperty<int>("io-threads", DefaultIOThreads); }
|
||||
|
||||
void SetNetworkInterface(const std::string& networkInterface) { fConfig->SetValue<std::string>("network-interface", networkInterface); }
|
||||
std::string GetNetworkInterface() const { return fConfig->GetValue<std::string>("network-interface"); }
|
||||
void SetNetworkInterface(const std::string& networkInterface) { fConfig->SetProperty("network-interface", networkInterface); }
|
||||
std::string GetNetworkInterface() const { return fConfig->GetProperty<std::string>("network-interface", DefaultNetworkInterface); }
|
||||
|
||||
void SetDefaultTransport(const std::string& name) { fConfig->SetValue<std::string>("transport", name); }
|
||||
std::string GetDefaultTransport() const { return fConfig->GetValue<std::string>("transport"); }
|
||||
void SetDefaultTransport(const std::string& name) { fConfig->SetProperty("transport", name); }
|
||||
std::string GetDefaultTransport() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
|
||||
|
||||
void SetInitializationTimeoutInS(int initializationTimeoutInS) { fConfig->SetValue<int>("initialization-timeout", initializationTimeoutInS); }
|
||||
int GetInitializationTimeoutInS() const { return fConfig->GetValue<int>("initialization-timeout"); }
|
||||
void SetInitTimeoutInS(int initTimeoutInS) { fConfig->SetProperty("init-timeout", initTimeoutInS); }
|
||||
int GetInitTimeoutInS() const { return fConfig->GetProperty<int>("init-timeout", DefaultInitTimeout); }
|
||||
|
||||
/// Sets the default transport for the device
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
void SetTransport(const std::string& transport) { fConfig->SetValue<std::string>("transport", transport); }
|
||||
void SetTransport(const std::string& transport) { fConfig->SetProperty("transport", transport); }
|
||||
/// Gets the default transport name
|
||||
std::string GetTransportName() const { return fConfig->GetValue<std::string>("transport"); }
|
||||
std::string GetTransportName() const { return fConfig->GetProperty<std::string>("transport", DefaultTransportName); }
|
||||
|
||||
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
||||
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
||||
@@ -428,7 +403,7 @@ class FairMQDevice
|
||||
/// Wait for the supplied amount of time or for interruption.
|
||||
/// If interrupted, returns false, otherwise true.
|
||||
/// @param duration wait duration
|
||||
template<class Rep, class Period>
|
||||
template<typename Rep, typename Period>
|
||||
bool WaitFor(std::chrono::duration<Rep, Period> const& duration)
|
||||
{
|
||||
return !fStateMachine.WaitForPendingStateFor(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
|
||||
@@ -440,12 +415,12 @@ class FairMQDevice
|
||||
|
||||
public:
|
||||
std::unordered_map<std::string, std::vector<FairMQChannel>> fChannels; ///< Device channels
|
||||
std::unique_ptr<FairMQProgOptions> fInternalConfig; ///< Internal program options configuration
|
||||
FairMQProgOptions* fConfig; ///< Pointer to config (internal or external)
|
||||
std::unique_ptr<fair::mq::ProgOptions> fInternalConfig; ///< Internal program options configuration
|
||||
fair::mq::ProgOptions* fConfig; ///< Pointer to config (internal or external)
|
||||
|
||||
void AddChannel(const std::string& channelName, const FairMQChannel& channel)
|
||||
void AddChannel(const std::string& name, FairMQChannel&& channel)
|
||||
{
|
||||
fConfig->AddChannel(channelName, channel);
|
||||
fConfig->AddChannel(name, channel);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -483,16 +458,18 @@ class FairMQDevice
|
||||
|
||||
public:
|
||||
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
|
||||
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::StateMachine::GetTransition(transition)); }
|
||||
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); }
|
||||
|
||||
fair::mq::State WaitForNextState();
|
||||
void WaitForState(fair::mq::State state);
|
||||
void WaitForState(const std::string& state) { fair::mq::StateMachine::GetState(state); }
|
||||
fair::mq::State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
||||
void WaitForState(fair::mq::State state) { fStateQueue.WaitForState(state); }
|
||||
void WaitForState(const std::string& state) { WaitForState(fair::mq::GetState(state)); }
|
||||
|
||||
void TransitionTo(const fair::mq::State state);
|
||||
|
||||
void SubscribeToStateChange(const std::string& key, std::function<void(const fair::mq::State)> callback) { fStateMachine.SubscribeToStateChange(key, callback); }
|
||||
void UnsubscribeFromStateChange(const std::string& key) { fStateMachine.UnsubscribeFromStateChange(key); }
|
||||
@@ -509,10 +486,18 @@ class FairMQDevice
|
||||
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
||||
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
||||
|
||||
static std::string GetStateName(const fair::mq::State state) { return fair::mq::StateMachine::GetStateName(state); }
|
||||
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::StateMachine::GetTransitionName(transition); }
|
||||
static std::string GetStateName(const fair::mq::State state) { return fair::mq::GetStateName(state); }
|
||||
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::GetTransitionName(transition); }
|
||||
|
||||
struct DeviceStateError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
static constexpr const char* DefaultId = "";
|
||||
static constexpr int DefaultIOThreads = 1;
|
||||
static constexpr const char* DefaultTransportName = "zeromq";
|
||||
static constexpr fair::mq::Transport DefaultTransportType = fair::mq::Transport::ZMQ;
|
||||
static constexpr const char* DefaultNetworkInterface = "default";
|
||||
static constexpr int DefaultInitTimeout = 120;
|
||||
static constexpr uint64_t DefaultMaxRunTime = 0;
|
||||
static constexpr float DefaultRate = 0.;
|
||||
static constexpr const char* DefaultSession = "default";
|
||||
|
||||
private:
|
||||
fair::mq::Transport fDefaultTransportType; ///< Default transport for the device
|
||||
@@ -566,11 +551,13 @@ class FairMQDevice
|
||||
const fair::mq::tools::Version fVersion;
|
||||
float fRate; ///< Rate limiting for ConditionalRun
|
||||
uint64_t fMaxRunRuntimeInS; ///< Maximum runtime for the Running state handler, after which state will change to Ready (in seconds, 0 for no limit).
|
||||
int fInitializationTimeoutInS;
|
||||
std::vector<std::string> fRawCmdLineArgs;
|
||||
|
||||
std::queue<fair::mq::State> fStates;
|
||||
std::mutex fStatesMtx;
|
||||
std::condition_variable fStatesCV;
|
||||
fair::mq::StateQueue fStateQueue;
|
||||
|
||||
std::mutex fTransitionMtx;
|
||||
bool fTransitioning;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQDEVICE_H_ */
|
||||
|
@@ -33,7 +33,7 @@ class FairMQParts
|
||||
FairMQParts& operator=(const FairMQParts&) = delete;
|
||||
/// Constructor from argument pack of std::unique_ptr<FairMQMessage> rvalues
|
||||
template <typename... Ts>
|
||||
FairMQParts(Ts&&... messages) : fParts() {AddPart(std::forward<Ts>(messages)...);}
|
||||
FairMQParts(Ts&&... messages) : fParts() { AddPart(std::forward<Ts>(messages)...); }
|
||||
/// Default destructor
|
||||
~FairMQParts() {};
|
||||
|
||||
|
@@ -16,18 +16,17 @@
|
||||
#include <fairmq/ofi/TransportFactory.h>
|
||||
#endif
|
||||
#include <FairMQLogger.h>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/Unique.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
FairMQTransportFactory::FairMQTransportFactory(const std::string& id)
|
||||
: fkId(id)
|
||||
{
|
||||
}
|
||||
|
||||
auto FairMQTransportFactory::CreateTransportFactory(const std::string& type, const std::string& id, const FairMQProgOptions* config) -> std::shared_ptr<FairMQTransportFactory>
|
||||
auto FairMQTransportFactory::CreateTransportFactory(const std::string& type, const std::string& id, const fair::mq::ProgOptions* config) -> std::shared_ptr<FairMQTransportFactory>
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
|
@@ -21,9 +21,11 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
class FairMQChannel;
|
||||
class FairMQProgOptions;
|
||||
namespace fair { namespace mq { class ProgOptions; } }
|
||||
|
||||
class FairMQTransportFactory
|
||||
{
|
||||
@@ -72,7 +74,7 @@ class FairMQTransportFactory
|
||||
/// 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 = 0;
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr, const std::string& path = "", int flags = 0) const = 0;
|
||||
|
||||
/// Get transport type
|
||||
virtual fair::mq::Transport GetType() const = 0;
|
||||
@@ -83,7 +85,7 @@ class FairMQTransportFactory
|
||||
|
||||
virtual ~FairMQTransportFactory() {};
|
||||
|
||||
static auto CreateTransportFactory(const std::string& type, const std::string& id = "", const FairMQProgOptions* config = nullptr) -> std::shared_ptr<FairMQTransportFactory>;
|
||||
static auto CreateTransportFactory(const std::string& type, const std::string& id = "", const fair::mq::ProgOptions* config = nullptr) -> std::shared_ptr<FairMQTransportFactory>;
|
||||
|
||||
static void FairMQNoCleanup(void* /*data*/, void* /*obj*/)
|
||||
{
|
||||
|
187
fairmq/JSONParser.cxx
Normal file
187
fairmq/JSONParser.cxx
Normal file
@@ -0,0 +1,187 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/*
|
||||
* File: JSONParser.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on May 14, 2015, 5:01 PM
|
||||
*/
|
||||
|
||||
#include <fairmq/PropertyOutput.h>
|
||||
#include "JSONParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/any.hpp>
|
||||
|
||||
#include <ios>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
using namespace fair::mq::tools;
|
||||
using namespace boost::property_tree;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
fair::mq::Properties PtreeParser(const ptree& pt, const string& id)
|
||||
{
|
||||
if (id == "") {
|
||||
throw ParserError("no device ID provided. Provide with `--id` cmd option");
|
||||
}
|
||||
|
||||
// json_parser::write_json(cout, pt);
|
||||
|
||||
return helper::DeviceParser(pt.get_child("fairMQOptions"), id);
|
||||
}
|
||||
|
||||
fair::mq::Properties JSONParser(const string& filename, const string& deviceId)
|
||||
{
|
||||
ptree pt;
|
||||
LOG(debug) << "Parsing JSON from " << filename << " ...";
|
||||
read_json(filename, pt);
|
||||
return PtreeParser(pt, deviceId);
|
||||
}
|
||||
|
||||
namespace helper
|
||||
{
|
||||
|
||||
fair::mq::Properties DeviceParser(const ptree& fairMQOptions, const string& deviceId)
|
||||
{
|
||||
fair::mq::Properties properties;
|
||||
|
||||
for (const auto& node : fairMQOptions) {
|
||||
if (node.first == "devices") {
|
||||
for (const auto& device : node.second) {
|
||||
// check if key is provided, otherwise use id
|
||||
string deviceIdKey = device.second.get<string>("key", device.second.get<string>("id", ""));
|
||||
|
||||
// if not correct device id, do not fill MQMap
|
||||
if (deviceId != deviceIdKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG(trace) << "Found following channels for device ID '" << deviceId << "' :";
|
||||
ChannelParser(device.second, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
void ChannelParser(const ptree& tree, fair::mq::Properties& properties)
|
||||
{
|
||||
for (const auto& node : tree) {
|
||||
if (node.first == "channels") {
|
||||
for (const auto& cn : node.second) {
|
||||
fair::mq::Properties commonProperties;
|
||||
commonProperties.emplace("type", cn.second.get<string>("type", FairMQChannel::DefaultType));
|
||||
commonProperties.emplace("method", cn.second.get<string>("method", FairMQChannel::DefaultMethod));
|
||||
commonProperties.emplace("address", cn.second.get<string>("address", FairMQChannel::DefaultAddress));
|
||||
commonProperties.emplace("transport", cn.second.get<string>("transport", FairMQChannel::DefaultTransportName));
|
||||
commonProperties.emplace("sndBufSize", cn.second.get<int>("sndBufSize", FairMQChannel::DefaultSndBufSize));
|
||||
commonProperties.emplace("rcvBufSize", cn.second.get<int>("rcvBufSize", FairMQChannel::DefaultRcvBufSize));
|
||||
commonProperties.emplace("sndKernelSize", cn.second.get<int>("sndKernelSize", FairMQChannel::DefaultSndKernelSize));
|
||||
commonProperties.emplace("rcvKernelSize", cn.second.get<int>("rcvKernelSize", FairMQChannel::DefaultRcvKernelSize));
|
||||
commonProperties.emplace("linger", cn.second.get<int>("linger", FairMQChannel::DefaultLinger));
|
||||
commonProperties.emplace("rateLogging", cn.second.get<int>("rateLogging", FairMQChannel::DefaultRateLogging));
|
||||
commonProperties.emplace("portRangeMin", cn.second.get<int>("portRangeMin", FairMQChannel::DefaultPortRangeMin));
|
||||
commonProperties.emplace("portRangeMax", cn.second.get<int>("portRangeMax", FairMQChannel::DefaultPortRangeMax));
|
||||
commonProperties.emplace("autoBind", cn.second.get<bool>("autoBind", FairMQChannel::DefaultAutoBind));
|
||||
|
||||
string name = cn.second.get<string>("name");
|
||||
int numSockets = cn.second.get<int>("numSockets", 0);
|
||||
|
||||
if (numSockets > 0) {
|
||||
LOG(trace) << name << ":";
|
||||
LOG(trace) << "\tnumSockets of " << numSockets << " specified, applying common settings to each:";
|
||||
|
||||
for (auto& p : commonProperties) {
|
||||
LOG(trace) << "\t" << setw(13) << left << p.first << " : " << p.second;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numSockets; ++i) {
|
||||
for (const auto& p : commonProperties) {
|
||||
properties.emplace(ToString("chans.", name, ".", i, ".", p.first), p.second);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SubChannelParser(cn.second.get_child(""), properties, name, commonProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties, const string& channelName, const fair::mq::Properties& commonProperties)
|
||||
{
|
||||
// for each socket in channel
|
||||
int i = 0;
|
||||
|
||||
for (const auto& node : channelTree) {
|
||||
if (node.first == "sockets") {
|
||||
for (const auto& sn : node.second) {
|
||||
// a sub-channel inherits relevant properties from the common channel ...
|
||||
fair::mq::Properties newProperties(commonProperties);
|
||||
|
||||
// ... and adds/overwrites its own properties
|
||||
newProperties["type"] = sn.second.get<string>("type", boost::any_cast<string>(commonProperties.at("type")));
|
||||
newProperties["method"] = sn.second.get<string>("method", boost::any_cast<string>(commonProperties.at("method")));
|
||||
newProperties["address"] = sn.second.get<string>("address", boost::any_cast<string>(commonProperties.at("address")));
|
||||
newProperties["transport"] = sn.second.get<string>("transport", boost::any_cast<string>(commonProperties.at("transport")));
|
||||
newProperties["sndBufSize"] = sn.second.get<int>("sndBufSize", boost::any_cast<int>(commonProperties.at("sndBufSize")));
|
||||
newProperties["rcvBufSize"] = sn.second.get<int>("rcvBufSize", boost::any_cast<int>(commonProperties.at("rcvBufSize")));
|
||||
newProperties["sndKernelSize"] = sn.second.get<int>("sndKernelSize", boost::any_cast<int>(commonProperties.at("sndKernelSize")));
|
||||
newProperties["rcvKernelSize"] = sn.second.get<int>("rcvKernelSize", boost::any_cast<int>(commonProperties.at("rcvKernelSize")));
|
||||
newProperties["linger"] = sn.second.get<int>("linger", boost::any_cast<int>(commonProperties.at("linger")));
|
||||
newProperties["rateLogging"] = sn.second.get<int>("rateLogging", boost::any_cast<int>(commonProperties.at("rateLogging")));
|
||||
newProperties["portRangeMin"] = sn.second.get<int>("portRangeMin", boost::any_cast<int>(commonProperties.at("portRangeMin")));
|
||||
newProperties["portRangeMax"] = sn.second.get<int>("portRangeMax", boost::any_cast<int>(commonProperties.at("portRangeMax")));
|
||||
newProperties["autoBind"] = sn.second.get<bool>("autoBind", boost::any_cast<bool>(commonProperties.at("autoBind")));
|
||||
|
||||
LOG(trace) << "" << channelName << "[" << i << "]:";
|
||||
for (auto& p : newProperties) {
|
||||
LOG(trace) << "\t" << setw(13) << left << p.first << " : " << p.second;
|
||||
}
|
||||
|
||||
for (const auto& p : newProperties) {
|
||||
properties.emplace(ToString("chans.", channelName, ".", i, ".", p.first), p.second);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
LOG(trace) << "Found " << i << " socket(s) in channel.";
|
||||
} else {
|
||||
// if no sockets are specified, apply common channel properties
|
||||
LOG(trace) << "" << channelName << ":";
|
||||
LOG(trace) << "\tNo sockets specified,";
|
||||
LOG(trace) << "\tapplying common settings to the channel:";
|
||||
|
||||
fair::mq::Properties newProperties(commonProperties);
|
||||
|
||||
for (auto& p : newProperties) {
|
||||
LOG(trace) << "\t" << setw(13) << left << p.first << " : " << p.second;
|
||||
}
|
||||
|
||||
for (const auto& p : newProperties) {
|
||||
properties.emplace(ToString("chans.", channelName, ".0.", p.first), p.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // helper namespace
|
||||
} // namespace mq
|
||||
} // namespace fair
|
51
fairmq/JSONParser.h
Normal file
51
fairmq/JSONParser.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/*
|
||||
* File: FairMQParser.h
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on May 14, 2015, 5:01 PM
|
||||
*/
|
||||
|
||||
#ifndef FAIR_MQ_JSONPARSER_H
|
||||
#define FAIR_MQ_JSONPARSER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <exception>
|
||||
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include "FairMQChannel.h"
|
||||
#include <fairmq/Properties.h>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
struct ParserError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
fair::mq::Properties PtreeParser(const boost::property_tree::ptree& pt, const std::string& deviceId);
|
||||
|
||||
fair::mq::Properties JSONParser(const std::string& filename, const std::string& deviceId);
|
||||
|
||||
namespace helper
|
||||
{
|
||||
|
||||
fair::mq::Properties DeviceParser(const boost::property_tree::ptree& tree, const std::string& deviceId);
|
||||
void ChannelParser(const boost::property_tree::ptree& tree, fair::mq::Properties& properties);
|
||||
void SubChannelParser(const boost::property_tree::ptree& tree, fair::mq::Properties& properties, const std::string& channelName, const fair::mq::Properties& commonProperties);
|
||||
|
||||
} // helper namespace
|
||||
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
|
||||
#endif /* FAIR_MQ_JSONPARSER_H */
|
@@ -23,11 +23,7 @@ class FairMQTransportFactory;
|
||||
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
|
||||
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace fair {
|
||||
namespace mq {
|
||||
|
@@ -9,7 +9,8 @@
|
||||
#ifndef FAIR_MQ_PLUGIN_H
|
||||
#define FAIR_MQ_PLUGIN_H
|
||||
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/CppSTL.h>
|
||||
#include <fairmq/tools/Version.h>
|
||||
#include <fairmq/PluginServices.h>
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
@@ -85,13 +86,30 @@ class Plugin
|
||||
// device config API
|
||||
// see <fairmq/PluginServices.h> for docs
|
||||
auto PropertyExists(const std::string& key) -> int { return fPluginServices->PropertyExists(key); }
|
||||
|
||||
template<typename T>
|
||||
auto SetProperty(const std::string& key, T val) -> void { fPluginServices->SetProperty(key, val); }
|
||||
T GetProperty(const std::string& key) const { return fPluginServices->GetProperty<T>(key); }
|
||||
template<typename T>
|
||||
auto GetProperty(const std::string& key) const -> T { return fPluginServices->GetProperty<T>(key); }
|
||||
auto GetPropertyAsString(const std::string& key) const -> std::string { return fPluginServices->GetPropertyAsString(key); }
|
||||
T GetProperty(const std::string& key, const T& ifNotFound) const { return fPluginServices->GetProperty(key, ifNotFound); }
|
||||
std::string GetPropertyAsString(const std::string& key) const { return fPluginServices->GetPropertyAsString(key); }
|
||||
std::string GetPropertyAsString(const std::string& key, const std::string& ifNotFound) const { return fPluginServices->GetPropertyAsString(key, ifNotFound); }
|
||||
fair::mq::Properties GetProperties(const std::string& q) const { return fPluginServices->GetProperties(q); }
|
||||
fair::mq::Properties GetPropertiesStartingWith(const std::string& q) const { return fPluginServices->GetPropertiesStartingWith(q); };
|
||||
std::map<std::string, std::string> GetPropertiesAsString(const std::string& q) const { return fPluginServices->GetPropertiesAsString(q); }
|
||||
std::map<std::string, std::string> GetPropertiesAsStringStartingWith(const std::string& q) const { return fPluginServices->GetPropertiesAsStringStartingWith(q); };
|
||||
|
||||
auto GetChannelInfo() const -> std::unordered_map<std::string, int> { return fPluginServices->GetChannelInfo(); }
|
||||
auto GetPropertyKeys() const -> std::vector<std::string> { return fPluginServices->GetPropertyKeys(); }
|
||||
|
||||
template<typename T>
|
||||
auto SetProperty(const std::string& key, T val) -> void { fPluginServices->SetProperty(key, val); }
|
||||
void SetProperties(const fair::mq::Properties& props) { fPluginServices->SetProperties(props); }
|
||||
template<typename T>
|
||||
bool UpdateProperty(const std::string& key, T val) { return fPluginServices->UpdateProperty(key, val); }
|
||||
bool UpdateProperties(const fair::mq::Properties& input) { return fPluginServices->UpdateProperties(input); }
|
||||
|
||||
void DeleteProperty(const std::string& key) { fPluginServices->DeleteProperty(key); }
|
||||
|
||||
template<typename T>
|
||||
auto SubscribeToPropertyChange(std::function<void(const std::string& key, T newValue)> callback) -> void { fPluginServices->SubscribeToPropertyChange<T>(fkName, callback); }
|
||||
template<typename T>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <fairmq/plugins/Builtin.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -49,13 +49,11 @@ fair::mq::PluginManager::PluginManager(const vector<string> args)
|
||||
// Parse command line options
|
||||
auto options = ProgramOptions();
|
||||
auto vm = po::variables_map{};
|
||||
try
|
||||
{
|
||||
try {
|
||||
auto parsed = po::command_line_parser(args).options(options).allow_unregistered().run();
|
||||
po::store(parsed, vm);
|
||||
po::notify(vm);
|
||||
} catch (const po::error& e)
|
||||
{
|
||||
} catch (const po::error& e) {
|
||||
throw ProgramOptionsParseError{ToString("Error occured while parsing the 'Plugin Manager' program options: ", e.what())};
|
||||
}
|
||||
|
||||
@@ -63,10 +61,8 @@ fair::mq::PluginManager::PluginManager(const vector<string> args)
|
||||
auto append = vector<fs::path>{};
|
||||
auto prepend = vector<fs::path>{};
|
||||
auto searchPaths = vector<fs::path>{};
|
||||
if (vm.count("plugin-search-path"))
|
||||
{
|
||||
for (const auto& path : vm["plugin-search-path"].as<vector<string>>())
|
||||
{
|
||||
if (vm.count("plugin-search-path")) {
|
||||
for (const auto& path : vm["plugin-search-path"].as<vector<string>>()) {
|
||||
if (path.substr(0, 1) == "<") { prepend.emplace_back(path.substr(1)); }
|
||||
else if (path.substr(0, 1) == ">") { append.emplace_back(path.substr(1)); }
|
||||
else { searchPaths.emplace_back(path); }
|
||||
@@ -126,23 +122,16 @@ auto fair::mq::PluginManager::ProgramOptions() -> po::options_description
|
||||
|
||||
auto fair::mq::PluginManager::LoadPlugin(const string& pluginName) -> void
|
||||
{
|
||||
if (pluginName.substr(0,2) == "p:")
|
||||
{
|
||||
if (pluginName.substr(0,2) == "p:") {
|
||||
// Mechanism A: prelinked dynamic
|
||||
LoadPluginPrelinkedDynamic(pluginName.substr(2));
|
||||
}
|
||||
else if (pluginName.substr(0,2) == "d:")
|
||||
{
|
||||
} else if (pluginName.substr(0,2) == "d:") {
|
||||
// Mechanism B: dynamic
|
||||
LoadPluginDynamic(pluginName.substr(2));
|
||||
}
|
||||
else if (pluginName.substr(0,2) == "s:")
|
||||
{
|
||||
} else if (pluginName.substr(0,2) == "s:") {
|
||||
// Mechanism C: static (builtin)
|
||||
LoadPluginStatic(pluginName.substr(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Mechanism B: dynamic (default)
|
||||
LoadPluginDynamic(pluginName);
|
||||
}
|
||||
@@ -151,15 +140,11 @@ auto fair::mq::PluginManager::LoadPlugin(const string& pluginName) -> void
|
||||
auto fair::mq::PluginManager::LoadPluginPrelinkedDynamic(const string& pluginName) -> void
|
||||
{
|
||||
// Load symbol
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end()) {
|
||||
try {
|
||||
LoadSymbols(pluginName, dll::program_location());
|
||||
fPluginOrder.push_back(pluginName);
|
||||
}
|
||||
catch (boost::system::system_error& e)
|
||||
{
|
||||
} catch (boost::system::system_error& e) {
|
||||
throw PluginLoadError(ToString("An error occurred while loading prelinked dynamic plugin ", pluginName, ": ", e.what()));
|
||||
}
|
||||
}
|
||||
@@ -168,13 +153,11 @@ auto fair::mq::PluginManager::LoadPluginPrelinkedDynamic(const string& pluginNam
|
||||
auto fair::mq::PluginManager::LoadPluginDynamic(const string& pluginName) -> void
|
||||
{
|
||||
// Search plugin and load, if found
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end())
|
||||
{
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end()) {
|
||||
auto success = false;
|
||||
for (const auto& searchPath : SearchPaths()) {
|
||||
try {
|
||||
LoadSymbols(pluginName,
|
||||
searchPath / ToString(LibPrefix(), pluginName),
|
||||
LoadSymbols(pluginName, searchPath / ToString(LibPrefix(), pluginName),
|
||||
dll::load_mode::append_decorations | dll::load_mode::rtld_global);
|
||||
fPluginOrder.push_back(pluginName);
|
||||
success = true;
|
||||
@@ -213,15 +196,11 @@ auto fair::mq::PluginManager::LoadPluginDynamic(const string& pluginName) -> voi
|
||||
auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
|
||||
{
|
||||
// Load symbol
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fPluginFactories.find(pluginName) == fPluginFactories.end()) {
|
||||
try {
|
||||
LoadSymbols(pluginName, dll::program_location());
|
||||
fPluginOrder.push_back(pluginName);
|
||||
}
|
||||
catch (boost::system::system_error& e)
|
||||
{
|
||||
} catch (boost::system::system_error& e) {
|
||||
throw PluginLoadError(ToString("An error occurred while loading static plugin ", pluginName, ": ", e.what()));
|
||||
}
|
||||
}
|
||||
@@ -229,22 +208,17 @@ auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
|
||||
|
||||
auto fair::mq::PluginManager::InstantiatePlugin(const string& pluginName) -> void
|
||||
{
|
||||
if (fPlugins.find(pluginName) == fPlugins.end())
|
||||
{
|
||||
if (fPlugins.find(pluginName) == fPlugins.end()) {
|
||||
fPlugins[pluginName] = fPluginFactories[pluginName](*fPluginServices);
|
||||
}
|
||||
}
|
||||
|
||||
auto fair::mq::PluginManager::InstantiatePlugins() -> void
|
||||
{
|
||||
for(const auto& pluginName : fPluginOrder)
|
||||
{
|
||||
try
|
||||
{
|
||||
for(const auto& pluginName : fPluginOrder) {
|
||||
try {
|
||||
InstantiatePlugin(pluginName);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
} catch (std::exception& e) {
|
||||
throw PluginInstantiationError(ToString("An error occurred while instantiating plugin ", pluginName, ": ", e.what()));
|
||||
}
|
||||
}
|
||||
|
@@ -11,8 +11,9 @@
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
#include <fairmq/PluginServices.h>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <FairMQDevice.h>
|
||||
#include <fairmq/tools/CppSTL.h>
|
||||
#include <fairmq/tools/Strings.h>
|
||||
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
#define BOOST_FILESYSTEM_NO_DEPRECATED
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -21,13 +22,14 @@
|
||||
#include <boost/dll/import.hpp>
|
||||
#include <boost/dll/shared_library.hpp>
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <utility> // forward
|
||||
|
||||
namespace fair
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user