mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 16:46:47 +00:00
Compare commits
195 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dcea48fcee | ||
|
67dcf77a7f | ||
|
24e7a5b8d0 | ||
|
c11506e958 | ||
|
e4f258c9ea | ||
|
324a27a2e1 | ||
|
c80f97b338 | ||
|
76824fee36 | ||
|
d2e4679dc8 | ||
|
6bb70bd519 | ||
|
fe2127e12f | ||
|
41165cf16b | ||
|
8fe95e644e | ||
|
6628a231e2 | ||
|
91b31f0799 | ||
|
39cb021827 | ||
|
36b48f5594 | ||
|
0e221b28b8 | ||
|
1ee0977df4 | ||
|
24d578a4ba | ||
|
ce1a4499cc | ||
|
7d009f0915 | ||
|
b70b181c38 | ||
|
94602d23b3 | ||
|
41ac755c57 | ||
|
6d4a82427b | ||
|
0966dee55d | ||
|
b649356c5a | ||
|
2df3d909fa | ||
|
05a2ae6a31 | ||
|
58ffdfd1f4 | ||
|
addfd071bb | ||
|
2d27abc533 | ||
|
faf577086a | ||
|
ff1f9b94ef | ||
|
34e8a24c86 | ||
|
7567a10513 | ||
|
424e22b41a | ||
|
961eca5276 | ||
|
fbb6577625 | ||
|
6122010694 | ||
|
b40db42196 | ||
|
f732b87def | ||
|
f05a09da5a | ||
|
5aa6c99442 | ||
|
3c714fd9e0 | ||
|
1b7532a520 | ||
|
f092b94c96 | ||
|
8d28824489 | ||
|
4310d07ed1 | ||
|
7bd31f8ff0 | ||
|
1a0ab3a4e2 | ||
|
cacf69d5f6 | ||
|
46f50a10ea | ||
|
68038c4693 | ||
|
1036e204d0 | ||
|
fddbbc1732 | ||
|
3c1723fc54 | ||
|
c3418cc7b8 | ||
|
cc00c5a6f1 | ||
|
e6bb14f535 | ||
|
b18d60372c | ||
|
7ceccdeaa6 | ||
|
d1c99f7e15 | ||
|
bfc665d76e | ||
|
42d27af20f | ||
|
25614e3e06 | ||
|
3decac58fc | ||
|
f278e7e312 | ||
|
491a943c63 | ||
|
c47fc6f9fe | ||
|
7b259afdb5 | ||
|
33ddcaad5e | ||
|
4d5dbedeab | ||
|
c8fde17b6a | ||
|
3781495d29 | ||
|
8960ce9416 | ||
|
05b734ee0d | ||
|
f2dce91098 | ||
|
4af0954ae9 | ||
|
8f60929f85 | ||
|
7d401115a0 | ||
|
0aecfff133 | ||
|
2e98a4e2cb | ||
|
21735544f5 | ||
|
651d779226 | ||
|
5108f699b7 | ||
|
c35d35a3c3 | ||
|
c2fa2e8848 | ||
|
b25c0787c0 | ||
|
84de22f80b | ||
|
435d07eaf9 | ||
|
5ef17fddbb | ||
|
f699208e30 | ||
|
8f5efdf74c | ||
|
45663189a9 | ||
|
61d2797971 | ||
|
afd5700cca | ||
|
569f2ccebf | ||
|
a83e401100 | ||
|
0a63c74849 | ||
|
a58b4870d7 | ||
|
7bf1d368a8 | ||
|
ae7bc6fc6c | ||
|
9093ed82dc | ||
|
efb659f0ac | ||
|
ae51ecc659 | ||
|
da1c9e4400 | ||
|
16275db125 | ||
|
42ce691f57 | ||
|
58aa2b4f88 | ||
|
c3b273cec0 | ||
|
a982d60ed7 | ||
|
1076fbf824 | ||
|
d16e473b91 | ||
|
ae6b60cc60 | ||
|
1881986cca | ||
|
adf91d053d | ||
|
d3be9af9b6 | ||
|
4104636456 | ||
|
c6dc360dc1 | ||
|
f04266f738 | ||
|
7e0faa297b | ||
|
9389030835 | ||
|
7697f2f4b1 | ||
|
87baf9749d | ||
|
a8b7ebef09 | ||
|
ac661dfd63 | ||
|
ed364a4857 | ||
|
9a25c4d28a | ||
|
19e40bd32e | ||
|
b7a4f22a13 | ||
|
77e04d56de | ||
|
64a09dd991 | ||
|
126475e7d2 | ||
|
0e12c57ff0 | ||
|
6eb973235a | ||
|
904037d9be | ||
|
de8236491f | ||
|
af0d668951 | ||
|
072d7cb744 | ||
|
f5c46ce018 | ||
|
de09018198 | ||
|
46e568c55e | ||
|
1870c1c060 | ||
|
c5cbc3d33b | ||
|
fdfde95dec | ||
|
d105960444 | ||
|
3aae5bae58 | ||
|
9031029d2c | ||
|
d478e050ba | ||
|
06b2b9b01f | ||
|
b3fa4f6e7e | ||
|
75e68e3e4d | ||
|
83ddbcef4c | ||
|
1b796b80dd | ||
|
9f06cfe66b | ||
|
a37781475b | ||
|
832c83247a | ||
|
69e82ca60c | ||
|
8086a04fb3 | ||
|
3367abdce3 | ||
|
f462e595ed | ||
|
40fcc466a9 | ||
|
69220a2e49 | ||
|
b707a8b45e | ||
|
c9fb8ac936 | ||
|
3925feb2b6 | ||
|
41b4a5f027 | ||
|
faa309556f | ||
|
da5cb34416 | ||
|
4587af2eb4 | ||
|
73fd1b2c2a | ||
|
a1e5962262 | ||
|
e57f746dc9 | ||
|
9a51c7b5fb | ||
|
b3395ef26e | ||
|
a48344bb03 | ||
|
9297308f8a | ||
|
c3fdc8c08c | ||
|
4ae68b63e9 | ||
|
2db9bd4b82 | ||
|
e202512621 | ||
|
2513da2136 | ||
|
640becc436 | ||
|
ca420a0e0d | ||
|
b798b1e098 | ||
|
ac1904661a | ||
|
cfc6090405 | ||
|
12a85c6fb1 | ||
|
0959095a39 | ||
|
9ad9393d44 | ||
|
cda7282422 | ||
|
226733c653 | ||
|
b06efc401e |
5
.devcontainer/devcontainer.json
Normal file
5
.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"image": "ghcr.io/fairrootgroup/fairmq-dev/fedora-38:latest",
|
||||||
|
"features": {
|
||||||
|
}
|
||||||
|
}
|
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
target-branch: "dev"
|
||||||
|
schedule:
|
||||||
|
interval: "monthly"
|
||||||
|
- package-ecosystem: "gitsubmodule"
|
||||||
|
directory: "/"
|
||||||
|
target-branch: "dev"
|
||||||
|
schedule:
|
||||||
|
interval: "monthly"
|
29
.github/workflows/check_metadata.yaml
vendored
Normal file
29
.github/workflows/check_metadata.yaml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH, Darmstadt, Germany
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
name: Check AUTHORS and CONTRIBUTORS in metadata
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- AUTHORS
|
||||||
|
- CONTRIBUTORS
|
||||||
|
- codemeta.json
|
||||||
|
- .zenodo.json
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- AUTHORS
|
||||||
|
- CONTRIBUTORS
|
||||||
|
- codemeta.json
|
||||||
|
- .zenodo.json
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Try updating metadata
|
||||||
|
run: python meta_update.py
|
||||||
|
- name: Check for Updates
|
||||||
|
run: git diff --exit-code
|
21
.github/workflows/codemeta_validate.yaml
vendored
Normal file
21
.github/workflows/codemeta_validate.yaml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
name: validate codemeta
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- codemeta.json
|
||||||
|
- .github/workflows/codemeta_validate.yaml
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- codemeta.json
|
||||||
|
- .github/workflows/codemeta_validate.yaml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: gitlab-registry.in2p3.fr/escape2020/wp3/eossr:v1.0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: validate codemeta
|
||||||
|
run: eossr-metadata-validator codemeta.json
|
16
.github/workflows/fair-software.yml
vendored
Normal file
16
.github/workflows/fair-software.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
name: fair-software
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
verify:
|
||||||
|
name: "fair-software"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'FairRootGroup/FairMQ'
|
||||||
|
steps:
|
||||||
|
- uses: fair-software/howfairis-github-action@0.2.1
|
||||||
|
name: Measure compliance with fair-software.eu recommendations
|
||||||
|
env:
|
||||||
|
PYCHARM_HOSTED: "Trick colorama into displaying colored output"
|
||||||
|
with:
|
||||||
|
MY_REPO_URL: "https://github.com/${{ github.repository }}"
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,3 +4,5 @@ install
|
||||||
.vscode
|
.vscode
|
||||||
/compile_commands.json
|
/compile_commands.json
|
||||||
.cache
|
.cache
|
||||||
|
.spack-env
|
||||||
|
spack.lock
|
||||||
|
|
88
.zenodo.json
Normal file
88
.zenodo.json
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
{
|
||||||
|
"creators": [
|
||||||
|
{
|
||||||
|
"orcid": "0000-0002-8071-4497",
|
||||||
|
"name": "Al-Turany, Mohammad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"orcid": "0000-0003-3787-1910",
|
||||||
|
"name": "Klein, Dennis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kollegger, Thorsten"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"orcid": "0000-0002-6249-155X",
|
||||||
|
"name": "Rybalchenko, Alexey"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Winckler, Nicolas"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Aphecetche, Laurent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Binet, Sebastien"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Eulisse, Giulio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Karabowicz, Radoslaw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Kretz, Matthias"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Krzewicki, Mikolaj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Lebedev, Andrey"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Mrnjavac, Teo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Neskovic, Gvozden"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Richter, Matthias"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"orcid": "0000-0002-5321-8404",
|
||||||
|
"name": "Tacke, Christian"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Uhlig, Florian"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Other",
|
||||||
|
"name": "Wenzel, Sandro"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "<p>C++ Message Queuing Library and Framework</p>",
|
||||||
|
"related_identifiers": [
|
||||||
|
{
|
||||||
|
"identifier": "https://github.com/FairRootGroup/FairMQ/",
|
||||||
|
"relation": "isSupplementTo",
|
||||||
|
"resource_type": "software",
|
||||||
|
"scheme": "url"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "FairMQ",
|
||||||
|
"license": "LGPL-3.0-only"
|
||||||
|
}
|
6
AUTHORS
6
AUTHORS
|
@ -1,5 +1,5 @@
|
||||||
Al-Turany, Mohammad
|
Al-Turany, Mohammad [https://orcid.org/0000-0002-8071-4497]
|
||||||
Klein, Dennis
|
Klein, Dennis [https://orcid.org/0000-0003-3787-1910]
|
||||||
Kollegger, Thorsten
|
Kollegger, Thorsten
|
||||||
Rybalchenko, Alexey
|
Rybalchenko, Alexey [https://orcid.org/0000-0002-6249-155X]
|
||||||
Winckler, Nicolas
|
Winckler, Nicolas
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -8,8 +8,7 @@
|
||||||
|
|
||||||
|
|
||||||
# Project ######################################################################
|
# Project ######################################################################
|
||||||
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.15...3.30 FATAL_ERROR)
|
||||||
cmake_policy(VERSION 3.15...3.22)
|
|
||||||
|
|
||||||
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
include(GitHelper)
|
include(GitHelper)
|
||||||
|
@ -27,18 +26,8 @@ fairmq_build_option(BUILD_FAIRMQ "Build FairMQ library and devices."
|
||||||
DEFAULT ON)
|
DEFAULT ON)
|
||||||
fairmq_build_option(BUILD_TESTING "Build tests."
|
fairmq_build_option(BUILD_TESTING "Build tests."
|
||||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
||||||
fairmq_build_option(BUILD_OFI_TRANSPORT "Build experimental OFI transport."
|
|
||||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ")
|
|
||||||
fairmq_build_option(BUILD_SDK_COMMANDS "Build the FairMQ SDK commands."
|
|
||||||
DEFAULT OFF)
|
|
||||||
fairmq_build_option(BUILD_DDS_PLUGIN "Build DDS plugin."
|
|
||||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
|
||||||
fairmq_build_option(BUILD_PMIX_PLUGIN "Build PMIx plugin."
|
|
||||||
DEFAULT OFF REQUIRES "BUILD_FAIRMQ;BUILD_SDK_COMMANDS")
|
|
||||||
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
||||||
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
|
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_TIDY_TOOL "Build the fairmq-tidy tool."
|
fairmq_build_option(BUILD_TIDY_TOOL "Build the fairmq-tidy tool."
|
||||||
DEFAULT OFF)
|
DEFAULT OFF)
|
||||||
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
||||||
|
@ -57,7 +46,7 @@ include(FairMQDependencies)
|
||||||
|
|
||||||
|
|
||||||
# Targets ######################################################################
|
# Targets ######################################################################
|
||||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
if(BUILD_FAIRMQ)
|
||||||
add_subdirectory(fairmq)
|
add_subdirectory(fairmq)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -92,27 +81,12 @@ endif()
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS tests)
|
list(APPEND PROJECT_PACKAGE_COMPONENTS tests)
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_DDS_PLUGIN)
|
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS dds_plugin)
|
|
||||||
endif()
|
|
||||||
if(BUILD_PMIX_PLUGIN)
|
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS pmix_plugin)
|
|
||||||
endif()
|
|
||||||
if(BUILD_OFI_TRANSPORT)
|
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS ofi_transport)
|
|
||||||
endif()
|
|
||||||
if(BUILD_EXAMPLES)
|
if(BUILD_EXAMPLES)
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS examples)
|
list(APPEND PROJECT_PACKAGE_COMPONENTS examples)
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_DOCS)
|
if(BUILD_DOCS)
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS docs)
|
list(APPEND PROJECT_PACKAGE_COMPONENTS docs)
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_SDK)
|
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk)
|
|
||||||
endif()
|
|
||||||
if(BUILD_SDK_COMMANDS)
|
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
|
|
||||||
endif()
|
|
||||||
if(BUILD_TIDY_TOOL)
|
if(BUILD_TIDY_TOOL)
|
||||||
list(APPEND PROJECT_PACKAGE_COMPONENTS tidy_tool)
|
list(APPEND PROJECT_PACKAGE_COMPONENTS tidy_tool)
|
||||||
endif()
|
endif()
|
||||||
|
@ -125,11 +99,6 @@ if(BUILD_FAIRMQ)
|
||||||
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_SDK OR BUILD_DDS_PLUGIN)
|
|
||||||
install(FILES cmake/Findasio.cmake
|
|
||||||
DESTINATION ${PROJECT_INSTALL_CMAKEMODDIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(BUILD_DOCS)
|
if(BUILD_DOCS)
|
||||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/doxygen/html
|
install(DIRECTORY ${CMAKE_BINARY_DIR}/doxygen/html
|
||||||
DESTINATION ${PROJECT_INSTALL_DATADIR}/docs
|
DESTINATION ${PROJECT_INSTALL_DATADIR}/docs
|
||||||
|
@ -157,5 +126,6 @@ fairmq_summary_components()
|
||||||
fairmq_summary_static_analysis()
|
fairmq_summary_static_analysis()
|
||||||
fairmq_summary_install_prefix()
|
fairmq_summary_install_prefix()
|
||||||
fairmq_summary_debug_mode()
|
fairmq_summary_debug_mode()
|
||||||
|
fairmq_summary_compile_definitions()
|
||||||
message(STATUS " ")
|
message(STATUS " ")
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
@ -8,6 +8,6 @@ Lebedev, Andrey
|
||||||
Mrnjavac, Teo <teo.m@cern.ch>
|
Mrnjavac, Teo <teo.m@cern.ch>
|
||||||
Neskovic, Gvozden
|
Neskovic, Gvozden
|
||||||
Richter, Matthias
|
Richter, Matthias
|
||||||
Tacke, Christian
|
Tacke, Christian [https://orcid.org/0000-0002-5321-8404]
|
||||||
Uhlig, Florian
|
Uhlig, Florian
|
||||||
Wenzel, Sandro
|
Wenzel, Sandro
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2021-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -42,15 +42,6 @@ endif()
|
||||||
ctest_start(Continuous)
|
ctest_start(Continuous)
|
||||||
|
|
||||||
list(APPEND options "-DDISABLE_COLOR=ON" "-DBUILD_EXAMPLES=ON" "-DBUILD_TESTING=ON")
|
list(APPEND options "-DDISABLE_COLOR=ON" "-DBUILD_EXAMPLES=ON" "-DBUILD_TESTING=ON")
|
||||||
if(HAS_ASIO AND HAS_DDS)
|
|
||||||
list(APPEND options "-DBUILD_SDK_COMMANDS=ON" "-DBUILD_SDK=ON" "-DBUILD_DDS_PLUGIN=ON")
|
|
||||||
endif()
|
|
||||||
if(HAS_PMIX)
|
|
||||||
list(APPEND options "-DBUILD_SDK_COMMANDS=ON" "-DBUILD_PMIX_PLUGIN=ON")
|
|
||||||
endif()
|
|
||||||
if(HAS_ASIO AND HAS_ASIOFI)
|
|
||||||
list(APPEND options "-DBUILD_OFI_TRANSPORT=ON")
|
|
||||||
endif()
|
|
||||||
if(RUN_STATIC_ANALYSIS)
|
if(RUN_STATIC_ANALYSIS)
|
||||||
list(APPEND options "-DRUN_STATIC_ANALYSIS=ON")
|
list(APPEND options "-DRUN_STATIC_ANALYSIS=ON")
|
||||||
endif()
|
endif()
|
||||||
|
@ -90,7 +81,7 @@ ctest_submit()
|
||||||
|
|
||||||
if(NOT RUN_STATIC_ANALYSIS)
|
if(NOT RUN_STATIC_ANALYSIS)
|
||||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||||
PARALLEL_LEVEL 1
|
PARALLEL_LEVEL ${NCPUS}
|
||||||
SCHEDULE_RANDOM ON
|
SCHEDULE_RANDOM ON
|
||||||
RETURN_VALUE _ctest_test_ret_val)
|
RETURN_VALUE _ctest_test_ret_val)
|
||||||
|
|
||||||
|
|
46
Jenkinsfile
vendored
46
Jenkinsfile
vendored
|
@ -4,20 +4,21 @@ def jobMatrix(String type, List specs) {
|
||||||
def nodes = [:]
|
def nodes = [:]
|
||||||
for (spec in specs) {
|
for (spec in specs) {
|
||||||
def job = ""
|
def job = ""
|
||||||
def selector = ""
|
def selector = "slurm"
|
||||||
def os = ""
|
def os = ""
|
||||||
def ver = ""
|
def ver = ""
|
||||||
|
|
||||||
if (type == 'build') {
|
if (type == 'build') {
|
||||||
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
|
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
|
||||||
|
if (spec.os =~ /^macos/) {
|
||||||
selector = "${spec.os}-${spec.ver}-${spec.arch}"
|
selector = "${spec.os}-${spec.ver}-${spec.arch}"
|
||||||
|
}
|
||||||
os = spec.os
|
os = spec.os
|
||||||
ver = spec.ver
|
ver = spec.ver
|
||||||
} else { // == 'check'
|
} else { // == 'check'
|
||||||
job = "${spec.name}"
|
job = "${spec.name}"
|
||||||
selector = 'fedora-35-x86_64'
|
|
||||||
os = 'fedora'
|
os = 'fedora'
|
||||||
ver = '35'
|
ver = '36'
|
||||||
}
|
}
|
||||||
|
|
||||||
def label = "${job}"
|
def label = "${job}"
|
||||||
|
@ -36,14 +37,14 @@ def jobMatrix(String type, List specs) {
|
||||||
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
|
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
|
||||||
if (selector =~ /^macos/) {
|
if (selector =~ /^macos/) {
|
||||||
sh """\
|
sh """\
|
||||||
echo \"export DDS_ROOT=\\\"\\\$(brew --prefix dds)\\\"\" >> ${jobscript}
|
|
||||||
echo \"export PATH=\\\"\\\$(brew --prefix dds)/bin:\\\$PATH\\\"\" >> ${jobscript}
|
|
||||||
echo \"${ctestcmd}\" >> ${jobscript}
|
echo \"${ctestcmd}\" >> ${jobscript}
|
||||||
"""
|
"""
|
||||||
sh "cat ${jobscript}"
|
sh "cat ${jobscript}"
|
||||||
sh "bash ${jobscript}"
|
sh "bash ${jobscript}"
|
||||||
} else {
|
} else { // selector == "slurm"
|
||||||
def containercmd = "singularity exec --net --ipc --uts --pid -B/shared ${env.SINGULARITY_CONTAINER_ROOT}/fairmq/${os}.${ver}.sif bash -l -c \\\"${ctestcmd} ${extra}\\\""
|
def imageurl = "oras://ghcr.io/fairrootgroup/fairmq-dev/${os}-${ver}-sif:latest"
|
||||||
|
def execopts = "--ipc --uts --pid -B/shared"
|
||||||
|
def containercmd = "singularity exec ${execopts} ${imageurl} bash -l -c \\\"${ctestcmd} ${extra}\\\""
|
||||||
sh """\
|
sh """\
|
||||||
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
|
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
|
||||||
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
|
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
|
||||||
|
@ -67,12 +68,6 @@ def jobMatrix(String type, List specs) {
|
||||||
deleteDir()
|
deleteDir()
|
||||||
githubNotify(context: "${label}", description: 'Success', status: 'SUCCESS')
|
githubNotify(context: "${label}", description: 'Success', status: 'SUCCESS')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
def tarball = "${type}_${job}_dds_logs.tar.gz"
|
|
||||||
if (fileExists("build/test/.DDS")) {
|
|
||||||
sh "tar czvf ${tarball} -C \${WORKSPACE}/build/test .DDS/"
|
|
||||||
archiveArtifacts tarball
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteDir()
|
deleteDir()
|
||||||
githubNotify(context: "${label}", description: 'Error', status: 'ERROR')
|
githubNotify(context: "${label}", description: 'Error', status: 'ERROR')
|
||||||
throw e
|
throw e
|
||||||
|
@ -89,19 +84,24 @@ pipeline{
|
||||||
stage("CI") {
|
stage("CI") {
|
||||||
steps{
|
steps{
|
||||||
script {
|
script {
|
||||||
def all = '-DHAS_ASIO=ON -DHAS_ASIOFI=ON -DHAS_PMIX=ON'
|
|
||||||
|
|
||||||
def builds = jobMatrix('build', [
|
def builds = jobMatrix('build', [
|
||||||
[os: 'ubuntu', ver: '20.04', arch: 'x86_64', compiler: 'gcc-9', extra: all],
|
[os: 'ubuntu', ver: '20.04', arch: 'x86_64', compiler: 'gcc-9'],
|
||||||
[os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10', extra: all],
|
[os: 'ubuntu', ver: '22.04', arch: 'x86_64', compiler: 'gcc-11'],
|
||||||
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10', extra: all],
|
[os: 'ubuntu', ver: '24.04', arch: 'x86_64', compiler: 'gcc-13'],
|
||||||
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11', extra: all],
|
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10'],
|
||||||
[os: 'fedora', ver: '35', arch: 'x86_64', compiler: 'gcc-11', extra: all],
|
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11'],
|
||||||
[os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12', extra: '-DHAS_ASIO=ON'],
|
[os: 'fedora', ver: '35', arch: 'x86_64', compiler: 'gcc-11'],
|
||||||
[os: 'macos', ver: '11', arch: 'arm64', compiler: 'apple-clang-13', extra: '-DHAS_ASIO=ON'],
|
[os: 'fedora', ver: '36', arch: 'x86_64', compiler: 'gcc-12'],
|
||||||
|
[os: 'fedora', ver: '37', arch: 'x86_64', compiler: 'gcc-12'],
|
||||||
|
[os: 'fedora', ver: '38', arch: 'x86_64', compiler: 'gcc-13'],
|
||||||
|
[os: 'fedora', ver: '39', arch: 'x86_64', compiler: 'gcc-13'],
|
||||||
|
[os: 'fedora', ver: '40', arch: 'x86_64', compiler: 'gcc-14'],
|
||||||
|
[os: 'macos', ver: '14', arch: 'x86_64', compiler: 'apple-clang-16'],
|
||||||
|
[os: 'macos', ver: '15', arch: 'x86_64', compiler: 'apple-clang-16'],
|
||||||
|
[os: 'macos', ver: '15', arch: 'arm64', compiler: 'apple-clang-16'],
|
||||||
])
|
])
|
||||||
|
|
||||||
def all_debug = "${all} -DCMAKE_BUILD_TYPE=Debug"
|
def all_debug = "-DCMAKE_BUILD_TYPE=Debug"
|
||||||
|
|
||||||
def checks = jobMatrix('check', [
|
def checks = jobMatrix('check', [
|
||||||
[name: 'static-analyzers', extra: "${all_debug} -DRUN_STATIC_ANALYSIS=ON"],
|
[name: 'static-analyzers', extra: "${all_debug} -DRUN_STATIC_ANALYSIS=ON"],
|
||||||
|
|
56
README.md
56
README.md
|
@ -1,5 +1,11 @@
|
||||||
<!-- {#mainpage} -->
|
<!-- {#mainpage} -->
|
||||||
# FairMQ [](COPYRIGHT)
|
# FairMQ
|
||||||
|
|
||||||
|
[](COPYRIGHT)
|
||||||
|
[](https://doi.org/10.5281/zenodo.1689985)
|
||||||
|
[](https://bestpractices.coreinfrastructure.org/projects/6915)
|
||||||
|
[](https://github.com/FairRootGroup/FairMQ/actions/workflows/fair-software.yml)
|
||||||
|
[](https://repology.org/project/fairmq/versions)
|
||||||
|
|
||||||
C++ Message Queuing Library and Framework
|
C++ Message Queuing Library and Framework
|
||||||
|
|
||||||
|
@ -18,7 +24,8 @@ FairMQ is designed to help implementing large-scale data processing workflows ne
|
||||||
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
|
The core of FairMQ provides an abstract asynchronous message passing API with scalability protocols
|
||||||
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
|
inspired by [ZeroMQ](https://github.com/zeromq/libzmq) (e.g. PUSH/PULL, PUB/SUB).
|
||||||
FairMQ provides multiple implementations for its API (so-called "transports",
|
FairMQ provides multiple implementations for its API (so-called "transports",
|
||||||
e.g. `zeromq`, `shmem` and `ofi` (in development)) to cover a variety of use cases
|
e.g. `zeromq` and `shmem` (latest release of the `ofi` transport in v1.4.56, removed since v1.5+)) to cover
|
||||||
|
a variety of use cases
|
||||||
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
|
(e.g. inter-thread, inter-process, inter-node communication) and machines (e.g. Ethernet, Infiniband).
|
||||||
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
|
In addition to this core functionality FairMQ provides a framework for creating "devices" - actors which
|
||||||
are communicating through message passing. FairMQ does not only allow the user to use different transport
|
are communicating through message passing. FairMQ does not only allow the user to use different transport
|
||||||
|
@ -38,10 +45,10 @@ Recommended:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/FairRootGroup/FairMQ fairmq_source
|
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 -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release [-DBUILD_TESTING=ON]
|
||||||
cmake --build fairmq_build
|
cmake --build fairmq_build
|
||||||
cmake --build fairmq_build --target test
|
[ctest --test-dir fairmq_build --output-on-failure --schedule-random -j<ncpus>] # needs -DBUILD_TESTING=ON
|
||||||
cmake --build fairmq_build --target install
|
cmake --install fairmq_build --prefix $(pwd)/fairmq_install
|
||||||
```
|
```
|
||||||
|
|
||||||
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
|
Please consult the [manpages of your CMake version](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for more options.
|
||||||
|
@ -49,6 +56,25 @@ Please consult the [manpages of your CMake version](https://cmake.org/cmake/help
|
||||||
If dependencies are not installed in standard system directories, you can hint the installation location via
|
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=...` (`*_ROOT` variables can also be environment variables).
|
`-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...` (`*_ROOT` variables can also be environment variables).
|
||||||
|
|
||||||
|
## Installation via Spack
|
||||||
|
|
||||||
|
Prerequisite: [Spack](https://spack.readthedocs.io/en/latest/getting_started.html)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
spack info fairmq # inspect build options
|
||||||
|
spack install fairmq # build latest packaged version with default options
|
||||||
|
```
|
||||||
|
|
||||||
|
Build FairMQ's dependencies via Spack for development:
|
||||||
|
```bash
|
||||||
|
git clone -b dev https://github.com/FairRootGroup/FairMQ fairmq_source
|
||||||
|
spack --env fairmq_source install # installs deps declared in fairmq_source/spack.yaml
|
||||||
|
spack env activate fairmq_source # sets $CMAKE_PREFIX_PATH which is used by CMake to find FairMQ's deps
|
||||||
|
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
|
||||||
|
# develop, compile, test
|
||||||
|
spack env deactivate # at end of dev session, or simply close the shell
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
FairMQ ships as a CMake package, so in your `CMakeLists.txt` you can discover it like this:
|
FairMQ ships as a CMake package, so in your `CMakeLists.txt` you can discover it like this:
|
||||||
|
@ -68,27 +94,14 @@ If FairMQ is not installed in system directories, you can hint the installation:
|
||||||
list(PREPEND CMAKE_PREFIX_PATH /path/to/fairmq_install)
|
list(PREPEND CMAKE_PREFIX_PATH /path/to/fairmq_install)
|
||||||
```
|
```
|
||||||
|
|
||||||
Optionally, you can require certain FairMQ package components and a minimum version:
|
|
||||||
|
|
||||||
```cmake
|
|
||||||
find_package(FairMQ 1.4.50 COMPONENTS ofi_transport)
|
|
||||||
```
|
|
||||||
|
|
||||||
When building FairMQ, CMake will print a summary table of all available package components.
|
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
* [asio](https://github.com/chriskohlhoff/asio)
|
|
||||||
* [asiofi](https://github.com/FairRootGroup/asiofi)
|
|
||||||
* [Boost](https://www.boost.org/)
|
* [Boost](https://www.boost.org/)
|
||||||
* [CMake](https://cmake.org/)
|
* [CMake](https://cmake.org/)
|
||||||
* [DDS](http://dds.gsi.de)
|
|
||||||
* [Doxygen](http://www.doxygen.org/)
|
* [Doxygen](http://www.doxygen.org/)
|
||||||
* [FairCMakeModules](https://github.com/FairRootGroup/FairCMakeModules) (optionally bundled)
|
* [FairCMakeModules](https://github.com/FairRootGroup/FairCMakeModules) (optionally bundled)
|
||||||
* [FairLogger](https://github.com/FairRootGroup/FairLogger)
|
* [FairLogger](https://github.com/FairRootGroup/FairLogger)
|
||||||
* [Flatbuffers](https://google.github.io/flatbuffers/)
|
|
||||||
* [GTest](https://github.com/google/googletest) (optionally bundled)
|
* [GTest](https://github.com/google/googletest) (optionally bundled)
|
||||||
* [PMIx](https://pmix.org/)
|
|
||||||
* [ZeroMQ](http://zeromq.org/)
|
* [ZeroMQ](http://zeromq.org/)
|
||||||
|
|
||||||
Which dependencies are required depends on which components are built.
|
Which dependencies are required depends on which components are built.
|
||||||
|
@ -102,9 +115,8 @@ On command line:
|
||||||
* `-DDISABLE_COLOR=ON` disables coloured console output.
|
* `-DDISABLE_COLOR=ON` disables coloured console output.
|
||||||
* `-DBUILD_TESTING=OFF` disables building of tests.
|
* `-DBUILD_TESTING=OFF` disables building of tests.
|
||||||
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
|
* `-DBUILD_EXAMPLES=OFF` disables building of examples.
|
||||||
* `-DBUILD_OFI_TRANSPORT=ON` enables building of the experimental OFI transport.
|
|
||||||
* `-DBUILD_PMIX_PLUGIN=ON` enables building of the PMIx plugin.
|
|
||||||
* `-DBUILD_DOCS=ON` enables building of API docs.
|
* `-DBUILD_DOCS=ON` enables building of API docs.
|
||||||
|
* `-DFAIRMQ_CHANNEL_DEFAULT_AUTOBIND=OFF` disable channel `autoBind` by default
|
||||||
* You can hint non-system installations for dependent packages, see the #installation-from-source 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:
|
After the `find_package(FairMQ)` call the following CMake variables are defined:
|
||||||
|
@ -161,6 +173,4 @@ After the `find_package(FairMQ)` call the following CMake variables are defined:
|
||||||
1. [Usage](docs/Plugins.md#71-usage)
|
1. [Usage](docs/Plugins.md#71-usage)
|
||||||
2. [Development](docs/Plugins.md#72-development)
|
2. [Development](docs/Plugins.md#72-development)
|
||||||
3. [Provided Plugins](docs/Plugins.md#73-provided-plugins)
|
3. [Provided Plugins](docs/Plugins.md#73-provided-plugins)
|
||||||
1. [DDS](docs/Plugins.md#731-dds)
|
1. [PMIx](docs/Plugins.md#731-pmix)
|
||||||
2. [PMIx](docs/Plugins.md#732-pmix)
|
|
||||||
8. [Controller SDK](docs/SDK.md)
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -12,46 +12,19 @@ include(FairCMakeModules)
|
||||||
include(FairFindPackage2)
|
include(FairFindPackage2)
|
||||||
include(FairMQBundlePackageHelper)
|
include(FairMQBundlePackageHelper)
|
||||||
|
|
||||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
if(BUILD_FAIRMQ)
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||||
find_package2(PUBLIC Threads REQUIRED)
|
find_package2(PUBLIC Threads REQUIRED)
|
||||||
set(Threads_PREFIX "<system>")
|
set(Threads_PREFIX "<system>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_OFI_TRANSPORT)
|
if(BUILD_FAIRMQ OR BUILD_TIDY_TOOL)
|
||||||
find_package2(PRIVATE asiofi REQUIRED VERSION 0.5)
|
|
||||||
find_package2(PRIVATE OFI REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_SDK_COMMANDS)
|
|
||||||
find_package2(PRIVATE Flatbuffers REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_DDS_PLUGIN OR BUILD_SDK)
|
|
||||||
find_package2(PRIVATE DDS REQUIRED VERSION 3.5.13.7)
|
|
||||||
set(DDS_Boost_COMPONENTS system log log_setup regex filesystem thread)
|
|
||||||
set(DDS_Boost_VERSION 1.67)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_PMIX_PLUGIN)
|
|
||||||
find_package2(PRIVATE PMIx REQUIRED VERSION 2.1.4)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_FAIRMQ OR BUILD_SDK OR BUILD_TIDY_TOOL)
|
|
||||||
find_package2(PUBLIC FairLogger REQUIRED VERSION 1.6.0)
|
find_package2(PUBLIC FairLogger REQUIRED VERSION 1.6.0)
|
||||||
find_package2(PUBLIC Boost REQUIRED VERSION 1.66
|
find_package2(PUBLIC Boost REQUIRED VERSION 1.66
|
||||||
COMPONENTS container program_options filesystem date_time regex
|
COMPONENTS container program_options filesystem date_time regex
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_OFI_TRANSPORT OR BUILD_SDK OR BUILD_DDS_PLUGIN)
|
|
||||||
set(__old ${CMAKE_FIND_PACKAGE_PREFER_CONFIG})
|
|
||||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
|
||||||
find_package2(PUBLIC asio REQUIRED VERSION 1.18)
|
|
||||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${__old})
|
|
||||||
unset(__old)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_FAIRMQ)
|
if(BUILD_FAIRMQ)
|
||||||
find_package2(PRIVATE ZeroMQ REQUIRED VERSION 4.1.4)
|
find_package2(PRIVATE ZeroMQ REQUIRED VERSION 4.1.4)
|
||||||
if(NOT PicoSHA2_BUNDLED)
|
if(NOT PicoSHA2_BUNDLED)
|
||||||
|
@ -68,7 +41,7 @@ if(BUILD_TESTING)
|
||||||
endif()
|
endif()
|
||||||
find_package2(BUNDLED GTest REQUIRED)
|
find_package2(BUNDLED GTest REQUIRED)
|
||||||
if(GTest_BUNDLED)
|
if(GTest_BUNDLED)
|
||||||
set(GTest_VERSION "Apr 28 2021 @f5e592d8")
|
set(GTest_VERSION "Dec 26 2024 @7d76a23")
|
||||||
set(GTest_PREFIX "<bundled>")
|
set(GTest_PREFIX "<bundled>")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -97,12 +70,6 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||||
if(NOT FairLogger_PREFIX AND FairLogger_ROOT)
|
if(NOT FairLogger_PREFIX AND FairLogger_ROOT)
|
||||||
set(FairLogger_PREFIX ${FairLogger_ROOT})
|
set(FairLogger_PREFIX ${FairLogger_ROOT})
|
||||||
endif()
|
endif()
|
||||||
elseif(${dep} STREQUAL asiofi)
|
|
||||||
if(NOT asiofi_PREFIX AND asiofi_ROOT)
|
|
||||||
set(asiofi_PREFIX ${asiofi_ROOT})
|
|
||||||
endif()
|
|
||||||
elseif(${dep} STREQUAL DDS)
|
|
||||||
set(DDS_PREFIX "${DDS_INSTALL_PREFIX}")
|
|
||||||
elseif(${dep} STREQUAL Boost)
|
elseif(${dep} STREQUAL Boost)
|
||||||
if(TARGET Boost::headers)
|
if(TARGET Boost::headers)
|
||||||
get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
get_target_property(boost_include Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
@ -116,14 +83,6 @@ if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||||
get_filename_component(Doxygen_PREFIX ${doxygen_bin} DIRECTORY)
|
get_filename_component(Doxygen_PREFIX ${doxygen_bin} DIRECTORY)
|
||||||
get_filename_component(Doxygen_PREFIX ${Doxygen_PREFIX}/.. ABSOLUTE)
|
get_filename_component(Doxygen_PREFIX ${Doxygen_PREFIX}/.. ABSOLUTE)
|
||||||
unset(doxygen_bin)
|
unset(doxygen_bin)
|
||||||
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(Flatbuffers_PREFIX ${flatbuffers_include}/.. ABSOLUTE)
|
|
||||||
unset(flatbuffers_include)
|
|
||||||
elseif(NOT ${dep}_PREFIX)
|
elseif(NOT ${dep}_PREFIX)
|
||||||
# try to guess
|
# try to guess
|
||||||
if(TARGET ${dep}::${dep})
|
if(TARGET ${dep}::${dep})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -34,8 +34,6 @@ endfunction()
|
||||||
|
|
||||||
# Configure/Install CMake package
|
# Configure/Install CMake package
|
||||||
macro(install_cmake_package)
|
macro(install_cmake_package)
|
||||||
list(SORT PROJECT_PACKAGE_DEPENDENCIES)
|
|
||||||
list(SORT PROJECT_INTERFACE_PACKAGE_DEPENDENCIES)
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
set(PACKAGE_INSTALL_DESTINATION
|
set(PACKAGE_INSTALL_DESTINATION
|
||||||
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
|
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -114,8 +114,8 @@ endif()
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo")
|
set(CMAKE_CONFIGURATION_TYPES "Debug" "Release" "RelWithDebInfo")
|
||||||
set(_warnings "-Wshadow -Wall -Wextra -Wpedantic")
|
set(_warnings "-Wshadow -Wall -Wextra -Wpedantic")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${_warnings} ${_sanitizers}")
|
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${_warnings} ${_sanitizers}")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${_warnings} -DNDEBUG ${_sanitizers}")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g ${_warnings} -DNDEBUG ${_sanitizers}")
|
||||||
unset(_warnings)
|
unset(_warnings)
|
||||||
unset(_sanitizers)
|
unset(_sanitizers)
|
||||||
|
|
||||||
|
@ -168,9 +168,22 @@ if(CMAKE_GENERATOR STREQUAL Ninja AND ENABLE_CCACHE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
if(NOT DEFINED FAIRMQ_HAS_STD_FILESYSTEM)
|
||||||
|
if( ( CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
|
||||||
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
|
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
|
||||||
|
OR ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
|
||||||
|
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9))
|
||||||
set(FAIRMQ_HAS_STD_FILESYSTEM 0)
|
set(FAIRMQ_HAS_STD_FILESYSTEM 0)
|
||||||
else()
|
else()
|
||||||
set(FAIRMQ_HAS_STD_FILESYSTEM 1)
|
set(FAIRMQ_HAS_STD_FILESYSTEM 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED FAIRMQ_HAS_STD_PMR)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
# Clang (to be more precise: libc++) currently does not implement <memory_resource>
|
||||||
|
set(FAIRMQ_HAS_STD_PMR 0)
|
||||||
|
else()
|
||||||
|
set(FAIRMQ_HAS_STD_PMR 1)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -27,24 +27,6 @@ macro(fairmq_summary_components)
|
||||||
set(tests_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
|
set(tests_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_TESTING=ON${CR})")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
|
message(STATUS " ${BWhite}tests${CR} ${tests_summary}")
|
||||||
if(BUILD_OFI_TRANSPORT)
|
|
||||||
set(ofi_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_OFI_TRANSPORT=OFF${CR})")
|
|
||||||
else()
|
|
||||||
set(ofi_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_OFI_TRANSPORT=ON${CR})")
|
|
||||||
endif()
|
|
||||||
message(STATUS " ${BWhite}ofi_transport${CR} ${ofi_summary}")
|
|
||||||
if(BUILD_DDS_PLUGIN)
|
|
||||||
set(dds_summary "${BGreen}YES${CR} DEPRECATED (disable with ${BMagenta}-DBUILD_DDS_PLUGIN=OFF${CR})")
|
|
||||||
else()
|
|
||||||
set(dds_summary "${BRed} NO${CR} DEPRECATED (default, enable with ${BMagenta}-DBUILD_DDS_PLUGIN=ON${CR})")
|
|
||||||
endif()
|
|
||||||
message(STATUS " ${BWhite}dds_plugin${CR} ${dds_summary}")
|
|
||||||
if(BUILD_PMIX_PLUGIN)
|
|
||||||
set(pmix_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_PMIX_PLUGIN=OFF${CR})")
|
|
||||||
else()
|
|
||||||
set(pmix_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_PMIX_PLUGIN=ON${CR})")
|
|
||||||
endif()
|
|
||||||
message(STATUS " ${BWhite}pmix_plugin${CR} ${pmix_summary}")
|
|
||||||
if(BUILD_EXAMPLES)
|
if(BUILD_EXAMPLES)
|
||||||
set(examples_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_EXAMPLES=OFF${CR})")
|
set(examples_summary "${BGreen}YES${CR} (default, disable with ${BMagenta}-DBUILD_EXAMPLES=OFF${CR})")
|
||||||
else()
|
else()
|
||||||
|
@ -57,39 +39,12 @@ macro(fairmq_summary_components)
|
||||||
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
|
set(docs_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_DOCS=ON${CR})")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
|
message(STATUS " ${BWhite}docs${CR} ${docs_summary}")
|
||||||
if(BUILD_SDK)
|
|
||||||
set(sdk_summary "${BGreen}YES${CR} DEPRECATED (disable with ${BMagenta}-DBUILD_SDK=OFF${CR})")
|
|
||||||
else()
|
|
||||||
set(sdk_summary "${BRed} NO${CR} DEPRECATED (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} DEPRECATED (disable with ${BMagenta}-DBUILD_SDK_COMMANDS=OFF${CR})")
|
|
||||||
else()
|
|
||||||
set(sdk_commands_summary "${BRed} NO${CR} DEPRECATED (default, enable with ${BMagenta}-DBUILD_SDK_COMMANDS=ON${CR})")
|
|
||||||
endif()
|
|
||||||
message(STATUS " ${BWhite}sdk_commands${CR} ${sdk_commands_summary}")
|
|
||||||
if(BUILD_TIDY_TOOL)
|
if(BUILD_TIDY_TOOL)
|
||||||
set(sdk_tidy_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_TIDY_TOOL=OFF${CR})")
|
set(sdk_tidy_summary "${BGreen}YES${CR} EXPERIMENTAL (disable with ${BMagenta}-DBUILD_TIDY_TOOL=OFF${CR})")
|
||||||
else()
|
else()
|
||||||
set(sdk_tidy_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_TIDY_TOOL=ON${CR})")
|
set(sdk_tidy_summary "${BRed} NO${CR} EXPERIMENTAL (default, enable with ${BMagenta}-DBUILD_TIDY_TOOL=ON${CR})")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS " ${BWhite}tidy_tool${CR} ${sdk_tidy_summary}")
|
message(STATUS " ${BWhite}tidy_tool${CR} ${sdk_tidy_summary}")
|
||||||
|
|
||||||
set(_deprecated)
|
|
||||||
if(BUILD_SDK)
|
|
||||||
list(APPEND _deprecated sdk)
|
|
||||||
endif()
|
|
||||||
if(BUILD_SDK_COMMANDS)
|
|
||||||
list(APPEND _deprecated sdk_commands)
|
|
||||||
endif()
|
|
||||||
if(BUILD_DDS_PLUGIN)
|
|
||||||
list(APPEND _deprecated dds_plugin)
|
|
||||||
endif()
|
|
||||||
list(JOIN _deprecated ", " _deprecated)
|
|
||||||
if(_deprecated)
|
|
||||||
message(DEPRECATION "You have selected to build deprecated components '${_deprecated}' which will be removed in a future release. See https://github.com/FairRootGroup/FairMQ/discussions/392 for more information. Use '-Wno-deprecated' to silence deprecation warnings.")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
macro(fairmq_summary_static_analysis)
|
macro(fairmq_summary_static_analysis)
|
||||||
|
@ -138,3 +93,13 @@ macro(fairmq_summary_debug_mode)
|
||||||
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
|
message(STATUS " ${Cyan}DEBUG MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})")
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
macro(fairmq_summary_compile_definitions)
|
||||||
|
message(STATUS " ")
|
||||||
|
message(STATUS " ${Cyan}COMPILE DEFINITION VALUE${CR}")
|
||||||
|
message(STATUS " ${BWhite}FAIRMQ_HAS_STD_FILESYSTEM${CR} ${FAIRMQ_HAS_STD_FILESYSTEM} (overridable with ${BMagenta}-DFAIRMQ_HAS_STD_FILESYSTEM=0|1${CR})")
|
||||||
|
message(STATUS " ${BWhite}FAIRMQ_HAS_STD_PMR${CR} ${FAIRMQ_HAS_STD_PMR} (overridable with ${BMagenta}-DFAIRMQ_HAS_STD_PMR=0|1${CR})")
|
||||||
|
if(DEFINED FAIRMQ_CHANNEL_DEFAULT_AUTOBIND)
|
||||||
|
message(STATUS " ${BWhite}FAIRMQ_CHANNEL_DEFAULT_AUTOBIND${CR} ${FAIRMQ_CHANNEL_DEFAULT_AUTOBIND}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
################################################################################
|
|
||||||
# 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" #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
# The "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix" part in all
|
|
||||||
# the PATH_SUFFIXES is here to be able to find Debian's
|
|
||||||
# libpmix-dev package. It installs everything below
|
|
||||||
# /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix
|
|
||||||
|
|
||||||
|
|
||||||
find_path(PMIx_INCLUDE_DIR
|
|
||||||
NAMES pmix.h
|
|
||||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
|
||||||
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(PMIx_LIBRARY_DIR
|
|
||||||
NAMES libpmix.dylib libpmix.so
|
|
||||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
|
||||||
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(PMIx_LIBRARY_SHARED
|
|
||||||
NAMES libpmix.dylib libpmix.so
|
|
||||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
|
||||||
PATH_SUFFIXES lib lib64 lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_file(PMIx_VERSION_FILE
|
|
||||||
NAMES pmix_version.h
|
|
||||||
HINTS ${PMIX_ROOT} $ENV{PMIX_ROOT}
|
|
||||||
PATH_SUFFIXES include lib/${CMAKE_LIBRARY_ARCHITECTURE}/pmix/include
|
|
||||||
)
|
|
||||||
|
|
||||||
file(READ "${PMIx_VERSION_FILE}" __version_raw)
|
|
||||||
string(REGEX MATCH "#define PMIX_VERSION_MAJOR ([0-9]?)L?"
|
|
||||||
__version_major_raw "${__version_raw}"
|
|
||||||
)
|
|
||||||
set(PMIx_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
|
||||||
|
|
||||||
string(REGEX MATCH "#define PMIX_VERSION_MINOR ([0-9]?)L?"
|
|
||||||
__version_minor_raw "${__version_raw}"
|
|
||||||
)
|
|
||||||
set(PMIx_VERSION_MINOR "${CMAKE_MATCH_1}")
|
|
||||||
|
|
||||||
string(REGEX MATCH "#define PMIX_VERSION_RELEASE ([0-9]?)L?"
|
|
||||||
__version_patch_raw "${__version_raw}"
|
|
||||||
)
|
|
||||||
set(PMIx_VERSION_PATCH "${CMAKE_MATCH_1}")
|
|
||||||
|
|
||||||
set(PMIx_VERSION "${PMIx_VERSION_MAJOR}.${PMIx_VERSION_MINOR}.${PMIx_VERSION_PATCH}")
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(PMIx
|
|
||||||
REQUIRED_VARS
|
|
||||||
PMIx_INCLUDE_DIR
|
|
||||||
PMIx_LIBRARY_DIR
|
|
||||||
PMIx_LIBRARY_SHARED
|
|
||||||
|
|
||||||
VERSION_VAR PMIx_VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT TARGET PMIx::libpmix AND PMIx_FOUND)
|
|
||||||
add_library(PMIx::libpmix SHARED IMPORTED)
|
|
||||||
set_target_properties(PMIx::libpmix PROPERTIES
|
|
||||||
IMPORTED_LOCATION ${PMIx_LIBRARY_SHARED}
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES ${PMIx_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
|
@ -1,5 +1,5 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
# [DEPENDS dep1 [dep2 ...]]
|
# [DEPENDS dep1 [dep2 ...]]
|
||||||
# [LINKS linklib1 [linklib2 ...]
|
# [LINKS linklib1 [linklib2 ...]
|
||||||
# [INCLUDES dir1 [dir2 ...]
|
# [INCLUDES dir1 [dir2 ...]
|
||||||
|
# [ENVIRONMENT var1=op:val1[;var2=op:val2 ...]]
|
||||||
# [TIMEOUT seconds]
|
# [TIMEOUT seconds]
|
||||||
# [RUN_SERIAL ON/OFF])
|
# [RUN_SERIAL ON/OFF])
|
||||||
#
|
#
|
||||||
|
@ -56,7 +57,7 @@ function(add_testsuite suitename)
|
||||||
cmake_parse_arguments(testsuite
|
cmake_parse_arguments(testsuite
|
||||||
""
|
""
|
||||||
"TIMEOUT;RUN_SERIAL"
|
"TIMEOUT;RUN_SERIAL"
|
||||||
"SOURCES;LINKS;DEPENDS;INCLUDES;DEFINITIONS"
|
"SOURCES;LINKS;DEPENDS;INCLUDES;DEFINITIONS;ENVIRONMENT"
|
||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -77,6 +78,9 @@ function(add_testsuite suitename)
|
||||||
if(testsuite_DEFINITIONS)
|
if(testsuite_DEFINITIONS)
|
||||||
target_compile_definitions("${target}" PUBLIC ${testsuite_DEFINITIONS})
|
target_compile_definitions("${target}" PUBLIC ${testsuite_DEFINITIONS})
|
||||||
endif()
|
endif()
|
||||||
|
if(testsuite_ENVIRONMENT AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
|
||||||
|
set(env "ENVIRONMENT_MODIFICATION" ${testsuite_ENVIRONMENT})
|
||||||
|
endif()
|
||||||
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
||||||
fairmq_target_tidy(TARGET ${target})
|
fairmq_target_tidy(TARGET ${target})
|
||||||
endif()
|
endif()
|
||||||
|
@ -97,6 +101,7 @@ function(add_testsuite suitename)
|
||||||
TEST_PREFIX ${suitename}.
|
TEST_PREFIX ${suitename}.
|
||||||
PROPERTIES RUN_SERIAL ${testsuite_RUN_SERIAL}
|
PROPERTIES RUN_SERIAL ${testsuite_RUN_SERIAL}
|
||||||
TIMEOUT ${testsuite_TIMEOUT}
|
TIMEOUT ${testsuite_TIMEOUT}
|
||||||
|
${env}
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND ALL_TEST_TARGETS ${target})
|
list(APPEND ALL_TEST_TARGETS ${target})
|
||||||
|
|
|
@ -6,17 +6,29 @@
|
||||||
"license": "./COPYRIGHT",
|
"license": "./COPYRIGHT",
|
||||||
"datePublished": "2018-04-15",
|
"datePublished": "2018-04-15",
|
||||||
"developmentStatus": "active",
|
"developmentStatus": "active",
|
||||||
|
"softwareVersion": "master",
|
||||||
|
"releaseNotes": "https://github.com/FairRootGroup/FairMQ/releases",
|
||||||
"codeRepository": "https://github.com/FairRootGroup/FairMQ/",
|
"codeRepository": "https://github.com/FairRootGroup/FairMQ/",
|
||||||
|
"readme": "https://github.com/FairRootGroup/FairMQ/#readme",
|
||||||
"issueTracker": "https://github.com/FairRootGroup/FairMQ/issues",
|
"issueTracker": "https://github.com/FairRootGroup/FairMQ/issues",
|
||||||
"identifier": "https://doi.org/10.5281/zenodo.1689985",
|
"identifier": "https://doi.org/10.5281/zenodo.1689985",
|
||||||
|
"maintainer": [
|
||||||
|
{
|
||||||
|
"@type": "ResearchOrganisation",
|
||||||
|
"@id": "https://ror.org/02k8cbn47",
|
||||||
|
"name": "GSI Helmholtz Centre for Heavy Ion Research"
|
||||||
|
}
|
||||||
|
],
|
||||||
"author": [
|
"author": [
|
||||||
{
|
{
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
|
"@id": "https://orcid.org/0000-0002-8071-4497",
|
||||||
"givenName": "Mohammad",
|
"givenName": "Mohammad",
|
||||||
"familyName": "Al-Turany"
|
"familyName": "Al-Turany"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
|
"@id": "https://orcid.org/0000-0003-3787-1910",
|
||||||
"givenName": "Dennis",
|
"givenName": "Dennis",
|
||||||
"familyName": "Klein"
|
"familyName": "Klein"
|
||||||
},
|
},
|
||||||
|
@ -27,6 +39,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
|
"@id": "https://orcid.org/0000-0002-6249-155X",
|
||||||
"givenName": "Alexey",
|
"givenName": "Alexey",
|
||||||
"familyName": "Rybalchenko"
|
"familyName": "Rybalchenko"
|
||||||
},
|
},
|
||||||
|
@ -91,6 +104,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
|
"@id": "https://orcid.org/0000-0002-5321-8404",
|
||||||
"givenName": "Christian",
|
"givenName": "Christian",
|
||||||
"familyName": "Tacke"
|
"familyName": "Tacke"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
#! /usr/bin/env python3
|
|
||||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import re
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
|
|
||||||
class CodeMetaManipulator(object):
|
|
||||||
def load(self, filename='codemeta.json'):
|
|
||||||
with open(filename, 'rb') as fp:
|
|
||||||
self.data = json.load(fp, object_pairs_hook=OrderedDict)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _dict_entry_cmp(dict1, dict2, field):
|
|
||||||
if (field in dict1) and (field in dict2):
|
|
||||||
return dict1[field] == dict2[field]
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def find_person_entry(cls, person_list, matchdict):
|
|
||||||
for entry in person_list:
|
|
||||||
if cls._dict_entry_cmp(entry, matchdict, 'email'):
|
|
||||||
return entry
|
|
||||||
if cls._dict_entry_cmp(entry, matchdict, 'familyName') \
|
|
||||||
and cls._dict_entry_cmp(entry, matchdict, 'givenName'):
|
|
||||||
return entry
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def update_person_entry(entry, matchdict):
|
|
||||||
if entry is None:
|
|
||||||
entry = OrderedDict()
|
|
||||||
entry['@type'] = 'Person'
|
|
||||||
for field in ('givenName', 'familyName', 'email'):
|
|
||||||
val = matchdict.get(field, None)
|
|
||||||
if val is not None:
|
|
||||||
entry[field] = val
|
|
||||||
return entry
|
|
||||||
|
|
||||||
def handle_person_list_file(self, filename, cm_field_name):
|
|
||||||
fp = open(filename, 'r', encoding='utf8')
|
|
||||||
findregex = re.compile(r'^(?P<familyName>[-\w\s]*[-\w]),\s*'
|
|
||||||
r'(?P<givenName>[-\w\s]*[-\w])\s*'
|
|
||||||
r'(?:<(?P<email>\S+@\S+)>)?$')
|
|
||||||
person_list = self.data.setdefault(cm_field_name, [])
|
|
||||||
for line in fp:
|
|
||||||
line = line.strip()
|
|
||||||
m = findregex.match(line)
|
|
||||||
if m is None:
|
|
||||||
raise RuntimeError("Could not analyze line %r" % line)
|
|
||||||
found_entry = self.find_person_entry(person_list, m.groupdict())
|
|
||||||
entry = self.update_person_entry(found_entry, m.groupdict())
|
|
||||||
if found_entry is None:
|
|
||||||
person_list.append(entry)
|
|
||||||
|
|
||||||
def save(self, filename='codemeta.json'):
|
|
||||||
with open('codemeta.json', 'w', encoding='utf8') as fp:
|
|
||||||
json.dump(self.data, fp, indent=2)
|
|
||||||
fp.write('\n')
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description='Update codemeta.json')
|
|
||||||
parser.add_argument('--set-version', dest='newversion')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
cm = CodeMetaManipulator()
|
|
||||||
cm.load()
|
|
||||||
if args.newversion is not None:
|
|
||||||
cm.data['softwareVersion'] = args.newversion
|
|
||||||
cm.handle_person_list_file('AUTHORS', 'author')
|
|
||||||
cm.handle_person_list_file('CONTRIBUTORS', 'contributor')
|
|
||||||
cm.save()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -16,11 +16,11 @@ Here is an overview of the device/channel options and when they are applied:
|
||||||
|
|
||||||
| Property | Applied in |
|
| Property | Applied in |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<runFairMQDevice.h>`)) |
|
| `severity` | immidiately (if `fair::mq::DeviceRunner` is used (also the case when using `<fairmq/runDevice.h>`)) |
|
||||||
| `file-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 `<fairmq/runDevice.h>`)) |
|
||||||
| `verbosity` | 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 `<fairmq/runDevice.h>`)) |
|
||||||
| `color` | 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 `<fairmq/runDevice.h>`)) |
|
||||||
| `log-to-file` | 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 `<fairmq/runDevice.h>`)) |
|
||||||
| `id` | at the end of `fair::mq::State::InitializingDevice` |
|
| `id` | at the end of `fair::mq::State::InitializingDevice` |
|
||||||
| `io-threads` | 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` |
|
| `transport` | at the end of `fair::mq::State::InitializingDevice` |
|
||||||
|
@ -28,7 +28,6 @@ Here is an overview of the device/channel options and when they are applied:
|
||||||
| `init-timeout` | at the end of `fair::mq::State::InitializingDevice` |
|
| `init-timeout` | at the end of `fair::mq::State::InitializingDevice` |
|
||||||
| `shm-segment-size` | 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` |
|
| `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` |
|
| `rate` | at the end of `fair::mq::State::InitializingDevice` |
|
||||||
| `session` | 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`) |
|
| `chan.*` | at the end of `fair::mq::State::InitializingDevice` (channel addresses can be also applied during `fair::mq::State::Binding`/`fair::mq::State::Connecting`) |
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
For unit testing it is often not feasible to boot up a full-blown distributed system with dozens of processes.
|
For unit testing it is often not feasible to boot up a full-blown distributed system with dozens of processes.
|
||||||
|
|
||||||
In some scenarios it is useful to not even instantiate a `FairMQDevice` at all. Please see [this example](../test/protocols/_push_pull_multipart.cxx) for single and multi threaded unit test without a device instance. If you store your transport factories and channels on the heap, pls make sure, you destroy the channels before you destroy the related transport factory for proper shutdown. Channels provide all the `Send/Receive` and `New*Message/New*Poller` APIs provided by the device too.
|
In some scenarios it is useful to not even instantiate a `fair::mq::Device` at all. Please see [this example](../test/protocols/_push_pull_multipart.cxx) for single and multi threaded unit test without a device instance. If you store your transport factories and channels on the heap, pls make sure, you destroy the channels before you destroy the related transport factory for proper shutdown. Channels provide all the `Send/Receive` and `New*Message/New*Poller` APIs provided by the device too.
|
||||||
|
|
||||||
## 4.2 Static Analysis
|
## 4.2 Static Analysis
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# 1. Device
|
# 1. Device
|
||||||
|
|
||||||
The components encapsulating the tasks are called **devices** and derive from the common base class `FairMQDevice`. FairMQ provides ready to use devices to organize the dataflow between the components (without touching the contents of a message), providing functionality like merging and splitting of the data stream (see subdirectory `devices`).
|
The components encapsulating the tasks are called **devices** and derive from the common base class `fair::mq::Device`. FairMQ provides ready to use devices to organize the dataflow between the components (without touching the contents of a message), providing functionality like merging and splitting of the data stream (see subdirectory `devices`).
|
||||||
|
|
||||||
## 1.1 Topology
|
## 1.1 Topology
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ Plugin Manager:
|
||||||
see man ld.so(8) for details.
|
see man ld.so(8) for details.
|
||||||
-P [ --plugin ] arg List of plugin names to load in
|
-P [ --plugin ] arg List of plugin names to load in
|
||||||
order,e.g. if the file is called
|
order,e.g. if the file is called
|
||||||
'libFairMQPlugin_example.so', just list
|
'libfairmq-plugin-example.so', just list
|
||||||
'example' or 'd:example' here.To load a
|
'example' or 'd:example' here.To load a
|
||||||
prelinked plugin, list 'p:example'
|
prelinked plugin, list 'p:example'
|
||||||
here.
|
here.
|
||||||
|
@ -54,40 +54,8 @@ A more complete example which may serve as a start including example CMake code
|
||||||
|
|
||||||
## 7.3 Provided Plugins
|
## 7.3 Provided Plugins
|
||||||
|
|
||||||
### 7.3.1 DDS
|
### 7.3.1 PMIx
|
||||||
|
|
||||||
When launching a FairMQ topology via [DDS](http://dds.gsi.de/) the DDS plugin enables FairMQ devices to interact with DDS' custom command and property subsystems - enable the plugin by passing `-P dds` on the command line.
|
The [PMIx](https://pmix.org/) plugin enables launching a FairMQ topology with any PMIx capable launcher, e.g. the [Open Run-Time Environment (ORTE) of OpenMPI](https://www.open-mpi.org/doc/v4.0/man1/mpirun.1.php) or the [Slurm workload manager](https://slurm.schedmd.com/srun.html). This experimental plugin has been last released in v1.4.56 and is removed in v1.5+. For now there are no plans to pick up development of it again.
|
||||||
|
|
||||||
Via the property subsystem a FairMQ topology may exchange channel connection data (essentially to do service discovery) needed to connect/bind all FairMQ channels appropriately. DDS is highly optimized for this use case. See [examples/dds](examples/dds/README.md) for more details.
|
|
||||||
|
|
||||||
Via the custom command subsystem a FairMQ device can receive a number of commands. FairMQ provides a convenient command line tool `fairmq-dds-command-ui` that allows interactive or scripted control of a running FairMQ topology managed via DDS. If one develops directly against the custom command DDS API, the following table lists all the commands the DDS plugin currently understands:
|
|
||||||
|
|
||||||
| Custom Command | Response | Error | Description |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| `check-state` | `<ID>: <STATE> (pid: <PID>)` | n/a | Query current device state, see state machine for possible states |
|
|
||||||
| `dump-config` | `(<ID>: <PKEY> -> <PVALUE>\n)+` | n/a | Query current device config (list property key/value pairs) |
|
|
||||||
| `INIT DEVICE` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `BIND` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `CONNECT` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `INIT TASK` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `RUN` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `STOP` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `RESET TASK` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `RESET DEVICE` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `END` | `<ID>: queued <CMD> transition` | `<ID>: could not queue <CMD> transition` | Initiate state transition |
|
|
||||||
| `subscribe-to-heartbeats` | `heartbeat-subscription: <ID>,OK` | n/a | Subscribe to heartbeats |
|
|
||||||
| on heartbeat subscription | `heartbeat: <ID>,<PID>` | n/a | Heartbeat every 100ms |
|
|
||||||
| `unsubscribe-from-heartbeats` | `heartbeat-unsubscription: <ID>,OK` | n/a | Unsubscribe from heartbeats |
|
|
||||||
| `subscribe-to-state-changes` | `state-changes-subscription: <ID>,OK` | n/a | Subscribe to state changes |
|
|
||||||
| on state changes subscription | `state-change: <ID>,<STATE>` | n/a | State change notification |
|
|
||||||
| `unsubscribe-from-state-changes` | `state-changes-unsubscription: <ID>,OK` | n/a | Unsubscribe from state changes |
|
|
||||||
|
|
||||||
If unknown commands are received the plugin will print a warning.
|
|
||||||
|
|
||||||
### 7.3.2 PMIx
|
|
||||||
|
|
||||||
The [PMIx](https://pmix.org/) plugin enables launching a FairMQ topology with any PMIx capable launcher, e.g. the [Open Run-Time Environment (ORTE) of OpenMPI](https://www.open-mpi.org/doc/v4.0/man1/mpirun.1.php) or the [Slurm workload manager](https://slurm.schedmd.com/srun.html). This plugin is not (yet) very mature and serves as a proof of concept at the moment.
|
|
||||||
|
|
||||||
TODO example usage
|
|
||||||
|
|
||||||
← [Back](../README.md)
|
← [Back](../README.md)
|
||||||
|
|
34
docs/SDK.md
34
docs/SDK.md
|
@ -1,34 +0,0 @@
|
||||||
← [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)
|
|
|
@ -1,51 +1,9 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-1-1-sampler sampler.cxx)
|
add_example(NAME 1-1 DEVICE sampler sink)
|
||||||
target_link_libraries(fairmq-ex-1-1-sampler PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-1-1-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-1-1-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(Example11 DEPENDS fairmq-ex-1-1-sampler fairmq-ex-1-1-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
|
|
||||||
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
|
|
||||||
|
|
||||||
add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
|
|
||||||
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-1-1-sampler
|
|
||||||
fairmq-ex-1-1-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-1.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-1-1.sh
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -13,7 +15,7 @@ chan="data"
|
||||||
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanAddr' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanAddr; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-1-1-sampler"
|
SAMPLER="fairmq-ex-1-1-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -22,6 +24,7 @@ SAMPLER+=" --transport $transport"
|
||||||
SAMPLER+=" --verbosity veryhigh"
|
SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --session $session"
|
SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --max-iterations 1"
|
SAMPLER+=" --max-iterations 1"
|
||||||
SAMPLER+=" --channel-config name=$chan,type=push,method=bind,address=ipc://$chanAddr,rateLogging=0"
|
SAMPLER+=" --channel-config name=$chan,type=push,method=bind,address=ipc://$chanAddr,rateLogging=0"
|
||||||
|
@ -34,6 +37,7 @@ SINK+=" --transport $transport"
|
||||||
SINK+=" --verbosity veryhigh"
|
SINK+=" --verbosity veryhigh"
|
||||||
SINK+=" --session $session"
|
SINK+=" --session $session"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
SINK+=" --max-iterations 1"
|
SINK+=" --max-iterations 1"
|
||||||
SINK+=" --channel-config name=$chan,type=pull,method=connect,address=ipc://$chanAddr,rateLogging=0"
|
SINK+=" --channel-config name=$chan,type=pull,method=connect,address=ipc://$chanAddr,rateLogging=0"
|
||||||
|
@ -44,4 +48,6 @@ SINK_PID=$!
|
||||||
wait $SAMPLER_PID
|
wait $SAMPLER_PID
|
||||||
wait $SINK_PID
|
wait $SINK_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chanAddr
|
rm $chanAddr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,64 +1,9 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-1-n-1-sampler sampler.cxx)
|
add_example(NAME 1-n-1 DEVICE sampler processor sink CONFIG)
|
||||||
target_link_libraries(fairmq-ex-1-n-1-sampler PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-1-n-1-processor processor.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-1-n-1-processor PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-1-n-1-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-1-n-1-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(Example1N1 DEPENDS fairmq-ex-1-n-1-sampler fairmq-ex-1-n-1-processor fairmq-ex-1-n-1-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(EX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh)
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-1-n-1.json ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
|
|
||||||
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
|
|
||||||
|
|
||||||
add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
|
|
||||||
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-1-n-1-sampler
|
|
||||||
fairmq-ex-1-n-1-processor
|
|
||||||
fairmq-ex-1-n-1-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(EX_CONF_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-1-n-1.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-1-n-1.sh
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/ex-1-n-1.json
|
|
||||||
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -15,7 +17,7 @@ chan1Addr="/tmp/fmq_$session""_""$chan1""_""$transport"
|
||||||
chan2Addr="/tmp/fmq_$session""_""$chan2""_""$transport"
|
chan2Addr="/tmp/fmq_$session""_""$chan2""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $PROCESSOR1_PID; kill -TERM $PROCESSOR2_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $PROCESSOR1_PID; wait $PROCESSOR2_PID; rm $chan1Addr; rm $chan2Addr' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $PROCESSOR1_PID; kill -TERM $PROCESSOR2_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $PROCESSOR1_PID; wait $PROCESSOR2_PID; rm $chan1Addr; rm $chan2Addr; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-1-n-1-sampler"
|
SAMPLER="fairmq-ex-1-n-1-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -24,6 +26,7 @@ SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --session $session"
|
SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --severity debug"
|
SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --max-iterations 2"
|
SAMPLER+=" --max-iterations 2"
|
||||||
SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,address=ipc://$chan1Addr,rateLogging=0"
|
SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,address=ipc://$chan1Addr,rateLogging=0"
|
||||||
|
@ -37,6 +40,7 @@ PROCESSOR1+=" --verbosity veryhigh"
|
||||||
PROCESSOR1+=" --session $session"
|
PROCESSOR1+=" --session $session"
|
||||||
PROCESSOR1+=" --severity debug"
|
PROCESSOR1+=" --severity debug"
|
||||||
PROCESSOR1+=" --shm-segment-size 100000000"
|
PROCESSOR1+=" --shm-segment-size 100000000"
|
||||||
|
PROCESSOR1+=" --shm-monitor true"
|
||||||
PROCESSOR1+=" --control static --color false"
|
PROCESSOR1+=" --control static --color false"
|
||||||
PROCESSOR1+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
|
PROCESSOR1+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
|
||||||
PROCESSOR1+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
|
PROCESSOR1+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
|
||||||
|
@ -50,6 +54,7 @@ PROCESSOR2+=" --verbosity veryhigh"
|
||||||
PROCESSOR2+=" --session $session"
|
PROCESSOR2+=" --session $session"
|
||||||
PROCESSOR2+=" --severity debug"
|
PROCESSOR2+=" --severity debug"
|
||||||
PROCESSOR2+=" --shm-segment-size 100000000"
|
PROCESSOR2+=" --shm-segment-size 100000000"
|
||||||
|
PROCESSOR2+=" --shm-monitor true"
|
||||||
PROCESSOR2+=" --control static --color false"
|
PROCESSOR2+=" --control static --color false"
|
||||||
PROCESSOR2+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
|
PROCESSOR2+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
|
||||||
PROCESSOR2+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
|
PROCESSOR2+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
|
||||||
|
@ -63,6 +68,7 @@ SINK+=" --verbosity veryhigh"
|
||||||
SINK+=" --session $session"
|
SINK+=" --session $session"
|
||||||
SINK+=" --severity debug"
|
SINK+=" --severity debug"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
SINK+=" --max-iterations 2"
|
SINK+=" --max-iterations 2"
|
||||||
SINK+=" --channel-config name=$chan2,type=pull,method=bind,address=ipc://$chan2Addr,rateLogging=0"
|
SINK+=" --channel-config name=$chan2,type=pull,method=bind,address=ipc://$chan2Addr,rateLogging=0"
|
||||||
|
@ -81,4 +87,6 @@ kill -SIGINT $PROCESSOR2_PID
|
||||||
wait $PROCESSOR1_PID
|
wait $PROCESSOR1_PID
|
||||||
wait $PROCESSOR2_PID
|
wait $PROCESSOR2_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chan1Addr; rm $chan2Addr
|
rm $chan1Addr; rm $chan2Addr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,15 +1,145 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
set(exe_prefix "fairmq-ex")
|
||||||
|
set(script_prefix "fairmq-start-ex")
|
||||||
|
set(test_script_prefix "test-ex")
|
||||||
|
set(testsuite "Example")
|
||||||
|
set(transports "zeromq" "shmem")
|
||||||
|
|
||||||
|
function(add_example)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 ARG
|
||||||
|
"CONFIG;NO_TRANSPORT;NO_TEST"
|
||||||
|
"NAME"
|
||||||
|
"DEVICE;VARIANT;TRANSPORT;SCRIPT"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ARG_UNPARSED_ARGUMENTS)
|
||||||
|
message(FATAL_ERROR "Unexpected unparsed arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARG_NAME)
|
||||||
|
set(name ${ARG_NAME})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "NAME arg is required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_SANITIZER_LEAK AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
|
||||||
|
get_filename_component(lsan_supps "${CMAKE_SOURCE_DIR}/test/leak_sanitizer_suppressions.txt" ABSOLUTE)
|
||||||
|
set(lsan_options "LSAN_OPTIONS=set:suppressions=${lsan_supps}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARG_DEVICE)
|
||||||
|
set(exe_targets)
|
||||||
|
foreach(device IN LISTS ARG_DEVICE)
|
||||||
|
set(exe "${exe_prefix}-${name}-${device}")
|
||||||
|
list(APPEND exe_targets ${exe})
|
||||||
|
add_executable(${exe} "${device}.cxx")
|
||||||
|
target_link_libraries(${exe} PRIVATE FairMQ)
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARG_TRANSPORT)
|
||||||
|
set(transports ${ARG_TRANSPORT})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARG_SCRIPT)
|
||||||
|
set(scripts ${ARG_SCRIPT})
|
||||||
|
else()
|
||||||
|
set(scripts ${ARG_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
if(ARG_CONFIG)
|
||||||
|
set(EX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
endif()
|
||||||
|
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
||||||
|
foreach(script IN LISTS scripts)
|
||||||
|
set(script_file "${script_prefix}-${script}.sh")
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${script_file}.in" "${CMAKE_CURRENT_BINARY_DIR}/${script_file}" @ONLY)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(ARG_CONFIG)
|
||||||
|
set(config "ex-${name}.json")
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${config}" "${CMAKE_CURRENT_BINARY_DIR}/${config}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# test
|
||||||
|
if(NOT ARG_NO_TEST)
|
||||||
|
set(test_script "${test_script_prefix}-${name}.sh")
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${test_script}.in" "${CMAKE_CURRENT_BINARY_DIR}/${test_script}")
|
||||||
|
|
||||||
|
if(ARG_NO_TRANSPORT)
|
||||||
|
set(test "${testsuite}.${name}.${transport}")
|
||||||
|
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport})
|
||||||
|
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
|
||||||
|
if(lsan_options)
|
||||||
|
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
foreach(transport IN LISTS transports)
|
||||||
|
if(ARG_VARIANT)
|
||||||
|
foreach(variant IN LISTS ARG_VARIANT)
|
||||||
|
set(test "${testsuite}.${name}.${variant}.${transport}")
|
||||||
|
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport} ${variant})
|
||||||
|
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
|
||||||
|
if(lsan_options)
|
||||||
|
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
set(test "${testsuite}.${name}.${transport}")
|
||||||
|
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_script} ${transport})
|
||||||
|
set_tests_properties(${test} PROPERTIES TIMEOUT "30")
|
||||||
|
if(lsan_options)
|
||||||
|
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# install
|
||||||
|
install(
|
||||||
|
TARGETS ${exe_targets}
|
||||||
|
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# configure run script with different executable paths for build and for install directories
|
||||||
|
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
||||||
|
if(ARG_CONFIG)
|
||||||
|
set(EX_CONF_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_DATADIR})
|
||||||
|
endif()
|
||||||
|
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
||||||
|
foreach(script IN LISTS scripts)
|
||||||
|
set(script_file "${script_prefix}-${script}.sh")
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${script_file}.in" "${CMAKE_CURRENT_BINARY_DIR}/${script_file}_install" @ONLY)
|
||||||
|
install(
|
||||||
|
PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${script_file}_install"
|
||||||
|
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||||
|
RENAME ${script_file}
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(ARG_CONFIG)
|
||||||
|
install(
|
||||||
|
FILES ${CMAKE_CURRENT_BINARY_DIR}/${config}
|
||||||
|
DESTINATION ${PROJECT_INSTALL_DATADIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
add_subdirectory(1-1)
|
add_subdirectory(1-1)
|
||||||
add_subdirectory(1-n-1)
|
add_subdirectory(1-n-1)
|
||||||
add_subdirectory(builtin-devices)
|
add_subdirectory(builtin-devices)
|
||||||
add_subdirectory(copypush)
|
add_subdirectory(copypush)
|
||||||
|
add_subdirectory(custom-controller)
|
||||||
add_subdirectory(dds)
|
add_subdirectory(dds)
|
||||||
add_subdirectory(multipart)
|
add_subdirectory(multipart)
|
||||||
add_subdirectory(multiple-channels)
|
add_subdirectory(multiple-channels)
|
||||||
|
|
|
@ -1,40 +1,11 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
add_example(NAME builtin-devices
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
VARIANT single_msg multipart
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.BuiltinDevices.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq)
|
|
||||||
set_tests_properties(Example.BuiltinDevices.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
|
||||||
|
|
||||||
add_test(NAME Example.BuiltinDevices.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem)
|
|
||||||
set_tests_properties(Example.BuiltinDevices.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
|
||||||
|
|
||||||
add_test(NAME Example.BuiltinDevices.multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq true 2)
|
|
||||||
set_tests_properties(Example.BuiltinDevices.multipart.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
|
||||||
|
|
||||||
add_test(NAME Example.BuiltinDevices.multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem true 2)
|
|
||||||
set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
|
|
||||||
|
|
||||||
# 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(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-builtin-devices.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-builtin-devices.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -10,12 +12,9 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||||
transport=$1
|
transport=$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $2 =~ ^[a-z]+$ ]]; then
|
if [[ $2 =~ ^multipart$ ]]; then
|
||||||
multipart=$2
|
multipart="true"
|
||||||
fi
|
numParts=2
|
||||||
|
|
||||||
if [[ $3 =~ ^[0-9]+$ ]]; then
|
|
||||||
numParts=$3
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
||||||
|
@ -33,7 +32,7 @@ chan4Addr="/tmp/fmq_$session""_""$chan4""_""$transport"
|
||||||
chan5Addr="/tmp/fmq_$session""_""$chan5""_""$transport"
|
chan5Addr="/tmp/fmq_$session""_""$chan5""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SPLITTER_PID; kill -TERM $PROXY1_PID; kill -TERM $PROXY2_PID; kill -TERM $MERGER_PID; kill -TERM $MULTIPLIER_PID; kill -TERM $SINK_PID; rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SPLITTER_PID; kill -TERM $PROXY1_PID; kill -TERM $PROXY2_PID; kill -TERM $MERGER_PID; kill -TERM $MULTIPLIER_PID; kill -TERM $SINK_PID; rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-bsampler"
|
SAMPLER="fairmq-bsampler"
|
||||||
SAMPLER+=" --id bsampler1"
|
SAMPLER+=" --id bsampler1"
|
||||||
|
@ -43,6 +42,7 @@ SAMPLER+=" --color false"
|
||||||
SAMPLER+=" --control static"
|
SAMPLER+=" --control static"
|
||||||
SAMPLER+=" --verbosity veryhigh"
|
SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --severity debug"
|
SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --msg-size 100000"
|
SAMPLER+=" --msg-size 100000"
|
||||||
SAMPLER+=" --multipart $multipart"
|
SAMPLER+=" --multipart $multipart"
|
||||||
|
@ -62,6 +62,7 @@ SPLITTER+=" --color false"
|
||||||
SPLITTER+=" --control static"
|
SPLITTER+=" --control static"
|
||||||
SPLITTER+=" --verbosity veryhigh"
|
SPLITTER+=" --verbosity veryhigh"
|
||||||
SPLITTER+=" --shm-segment-size 100000000"
|
SPLITTER+=" --shm-segment-size 100000000"
|
||||||
|
SPLITTER+=" --shm-monitor true"
|
||||||
SPLITTER+=" --multipart $multipart"
|
SPLITTER+=" --multipart $multipart"
|
||||||
SPLITTER+=" --in-channel $chan1"
|
SPLITTER+=" --in-channel $chan1"
|
||||||
SPLITTER+=" --out-channel $chan2"
|
SPLITTER+=" --out-channel $chan2"
|
||||||
|
@ -78,6 +79,7 @@ PROXY1+=" --color false"
|
||||||
PROXY1+=" --control static"
|
PROXY1+=" --control static"
|
||||||
PROXY1+=" --verbosity veryhigh"
|
PROXY1+=" --verbosity veryhigh"
|
||||||
PROXY1+=" --shm-segment-size 100000000"
|
PROXY1+=" --shm-segment-size 100000000"
|
||||||
|
PROXY1+=" --shm-monitor true"
|
||||||
PROXY1+=" --multipart $multipart"
|
PROXY1+=" --multipart $multipart"
|
||||||
PROXY1+=" --in-channel $chan2"
|
PROXY1+=" --in-channel $chan2"
|
||||||
PROXY1+=" --out-channel $chan3"
|
PROXY1+=" --out-channel $chan3"
|
||||||
|
@ -94,6 +96,7 @@ PROXY2+=" --color false"
|
||||||
PROXY2+=" --control static"
|
PROXY2+=" --control static"
|
||||||
PROXY2+=" --verbosity veryhigh"
|
PROXY2+=" --verbosity veryhigh"
|
||||||
PROXY2+=" --shm-segment-size 100000000"
|
PROXY2+=" --shm-segment-size 100000000"
|
||||||
|
PROXY2+=" --shm-monitor true"
|
||||||
PROXY2+=" --multipart $multipart"
|
PROXY2+=" --multipart $multipart"
|
||||||
PROXY2+=" --in-channel $chan2"
|
PROXY2+=" --in-channel $chan2"
|
||||||
PROXY2+=" --out-channel $chan3"
|
PROXY2+=" --out-channel $chan3"
|
||||||
|
@ -110,6 +113,7 @@ MERGER+=" --color false"
|
||||||
MERGER+=" --control static"
|
MERGER+=" --control static"
|
||||||
MERGER+=" --verbosity veryhigh"
|
MERGER+=" --verbosity veryhigh"
|
||||||
MERGER+=" --shm-segment-size 100000000"
|
MERGER+=" --shm-segment-size 100000000"
|
||||||
|
MERGER+=" --shm-monitor true"
|
||||||
MERGER+=" --multipart $multipart"
|
MERGER+=" --multipart $multipart"
|
||||||
MERGER+=" --in-channel $chan3"
|
MERGER+=" --in-channel $chan3"
|
||||||
MERGER+=" --out-channel $chan4"
|
MERGER+=" --out-channel $chan4"
|
||||||
|
@ -126,6 +130,7 @@ MULTIPLIER+=" --color false"
|
||||||
MULTIPLIER+=" --control static"
|
MULTIPLIER+=" --control static"
|
||||||
MULTIPLIER+=" --verbosity veryhigh"
|
MULTIPLIER+=" --verbosity veryhigh"
|
||||||
MULTIPLIER+=" --shm-segment-size 100000000"
|
MULTIPLIER+=" --shm-segment-size 100000000"
|
||||||
|
MULTIPLIER+=" --shm-monitor true"
|
||||||
MULTIPLIER+=" --multipart $multipart"
|
MULTIPLIER+=" --multipart $multipart"
|
||||||
MULTIPLIER+=" --in-channel $chan4"
|
MULTIPLIER+=" --in-channel $chan4"
|
||||||
MULTIPLIER+=" --out-channel $chan5"
|
MULTIPLIER+=" --out-channel $chan5"
|
||||||
|
@ -143,6 +148,7 @@ SINK+=" --control static"
|
||||||
SINK+=" --verbosity veryhigh"
|
SINK+=" --verbosity veryhigh"
|
||||||
SINK+=" --severity debug"
|
SINK+=" --severity debug"
|
||||||
SINK+=" --multipart $multipart"
|
SINK+=" --multipart $multipart"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --max-iterations 2"
|
SINK+=" --max-iterations 2"
|
||||||
SINK+=" --in-channel $chan5"
|
SINK+=" --in-channel $chan5"
|
||||||
SINK+=" --channel-config name=$chan5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr"
|
SINK+=" --channel-config name=$chan5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr"
|
||||||
|
@ -165,4 +171,6 @@ wait $PROXY2_PID
|
||||||
wait $MERGER_PID
|
wait $MERGER_PID
|
||||||
wait $MULTIPLIER_PID
|
wait $MULTIPLIER_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr
|
rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,52 +1,11 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
add_example(NAME copypush
|
||||||
add_executable(fairmq-ex-copypush-sampler sampler.cxx)
|
DEVICE sampler sink
|
||||||
target_link_libraries(fairmq-ex-copypush-sampler PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-copypush-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-copypush-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleCopyPush DEPENDS fairmq-ex-copypush-sampler fairmq-ex-copypush-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
|
|
||||||
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received message: ")
|
|
||||||
|
|
||||||
add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
|
|
||||||
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received message: ")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-copypush-sampler
|
|
||||||
fairmq-ex-copypush-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-copypush.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-copypush.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -14,7 +16,7 @@ chanAddr1="/tmp/fmq_$session""_""$chan""_1""_""$transport"
|
||||||
chanAddr2="/tmp/fmq_$session""_""$chan""_2""_""$transport"
|
chanAddr2="/tmp/fmq_$session""_""$chan""_2""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK1_PID; kill -TERM $SINK2_PID; wait $SAMPLER_PID; wait $SINK1_PID; wait $SINK2_PID; rm $chanAddr1; rm $chanAddr2' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK1_PID; kill -TERM $SINK2_PID; wait $SAMPLER_PID; wait $SINK1_PID; wait $SINK2_PID; rm $chanAddr1; rm $chanAddr2; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-copypush-sampler"
|
SAMPLER="fairmq-ex-copypush-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -22,6 +24,7 @@ SAMPLER+=" --transport $transport"
|
||||||
SAMPLER+=" --verbosity veryhigh"
|
SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --severity debug"
|
SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --session $session"
|
SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --max-iterations 1"
|
SAMPLER+=" --max-iterations 1"
|
||||||
|
@ -35,6 +38,7 @@ SINK1+=" --transport $transport"
|
||||||
SINK1+=" --verbosity veryhigh"
|
SINK1+=" --verbosity veryhigh"
|
||||||
SINK1+=" --severity debug"
|
SINK1+=" --severity debug"
|
||||||
SINK1+=" --shm-segment-size 100000000"
|
SINK1+=" --shm-segment-size 100000000"
|
||||||
|
SINK1+=" --shm-monitor true"
|
||||||
SINK1+=" --session $session"
|
SINK1+=" --session $session"
|
||||||
SINK1+=" --control static --color false"
|
SINK1+=" --control static --color false"
|
||||||
SINK1+=" --max-iterations 1"
|
SINK1+=" --max-iterations 1"
|
||||||
|
@ -48,6 +52,7 @@ SINK2+=" --transport $transport"
|
||||||
SINK2+=" --verbosity veryhigh"
|
SINK2+=" --verbosity veryhigh"
|
||||||
SINK2+=" --severity debug"
|
SINK2+=" --severity debug"
|
||||||
SINK2+=" --shm-segment-size 100000000"
|
SINK2+=" --shm-segment-size 100000000"
|
||||||
|
SINK2+=" --shm-monitor true"
|
||||||
SINK2+=" --session $session"
|
SINK2+=" --session $session"
|
||||||
SINK2+=" --control static --color false"
|
SINK2+=" --control static --color false"
|
||||||
SINK2+=" --max-iterations 1"
|
SINK2+=" --max-iterations 1"
|
||||||
|
@ -60,4 +65,6 @@ wait $SAMPLER_PID
|
||||||
wait $SINK1_PID
|
wait $SINK1_PID
|
||||||
wait $SINK2_PID
|
wait $SINK2_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chanAddr1; rm $chanAddr2
|
rm $chanAddr1; rm $chanAddr2
|
||||||
|
exit 0
|
||||||
|
|
20
examples/custom-controller/CMakeLists.txt
Normal file
20
examples/custom-controller/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
################################################################################
|
||||||
|
# Copyright (C) 2022-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
|
# #
|
||||||
|
# This software is distributed under the terms of the #
|
||||||
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
|
# copied verbatim in the file "LICENSE" #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
set(name "custom-controller")
|
||||||
|
set(exe "${exe_prefix}-${name}")
|
||||||
|
add_executable(${exe} main.cxx)
|
||||||
|
target_link_libraries(${exe} PRIVATE FairMQ)
|
||||||
|
set_target_properties(${exe} PROPERTIES ENABLE_EXPORTS ON)
|
||||||
|
|
||||||
|
set(test "${testsuite}.${name}")
|
||||||
|
add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${exe})
|
||||||
|
set_tests_properties(${test} PROPERTIES TIMEOUT 30)
|
||||||
|
if(lsan_options)
|
||||||
|
set_tests_properties(${test} PROPERTIES ENVIRONMENT_MODIFICATION ${lsan_options})
|
||||||
|
endif()
|
97
examples/custom-controller/MyController.h
Normal file
97
examples/custom-controller/MyController.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN
|
||||||
|
#define FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN
|
||||||
|
|
||||||
|
#include <fairmq/Plugin.h>
|
||||||
|
#include <utility> // for std::forward
|
||||||
|
|
||||||
|
namespace example {
|
||||||
|
|
||||||
|
struct MyController : fair::mq::Plugin // NOLINT
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
MyController(Args&&... args)
|
||||||
|
: Plugin(std::forward<Args>(args)...)
|
||||||
|
{
|
||||||
|
TakeDeviceControl();
|
||||||
|
|
||||||
|
SubscribeToDeviceStateChange([this](auto state) {
|
||||||
|
auto shutdown = GetProperty<bool>("please-shut-me-down", false);
|
||||||
|
try {
|
||||||
|
switch (state) {
|
||||||
|
case DeviceState::Idle: {
|
||||||
|
ChangeDeviceState(shutdown ? DeviceStateTransition::End
|
||||||
|
: DeviceStateTransition::InitDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::InitializingDevice: {
|
||||||
|
ChangeDeviceState(DeviceStateTransition::CompleteInit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::Initialized: {
|
||||||
|
ChangeDeviceState(DeviceStateTransition::Bind);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::Bound: {
|
||||||
|
ChangeDeviceState(DeviceStateTransition::Connect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::DeviceReady: {
|
||||||
|
ChangeDeviceState(shutdown ? DeviceStateTransition::ResetDevice
|
||||||
|
: DeviceStateTransition::InitTask);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::Ready: {
|
||||||
|
ChangeDeviceState(shutdown ? DeviceStateTransition::ResetTask
|
||||||
|
: DeviceStateTransition::Run);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::Running: {
|
||||||
|
ChangeDeviceState(DeviceStateTransition::Stop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DeviceState::Exiting: {
|
||||||
|
ReleaseDeviceControl();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (fair::mq::PluginServices::DeviceControlError const&) {
|
||||||
|
// this means we do not have device control
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
~MyController() override { ReleaseDeviceControl(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// auto MyControllerProgramOptions() -> fair::mq::Plugin::ProgOptions
|
||||||
|
// {
|
||||||
|
// auto plugin_options = boost::program_options::options_description{"MyController Plugin"};
|
||||||
|
// plugin_options.add_options()
|
||||||
|
// ("custom-dummy-option", boost::program_options::value<std::string>(), "Cool custom option.")
|
||||||
|
// ("custom-dummy-option2", boost::program_options::value<std::string>(), "Another one.");
|
||||||
|
// return plugin_options;
|
||||||
|
// }
|
||||||
|
|
||||||
|
} // namespace example
|
||||||
|
|
||||||
|
REGISTER_FAIRMQ_PLUGIN(example::MyController, // Class name
|
||||||
|
mycontroller, // Plugin name (string, lower case chars only)
|
||||||
|
(fair::mq::Plugin::Version{0, 42, 0}), // Version
|
||||||
|
"Mr. Dummy <dummy@test.net>", // Maintainer
|
||||||
|
"https://git.test.net/mycontroller.git", // Homepage
|
||||||
|
// example::MyControllerProgramOptions // Free
|
||||||
|
// function which declares custom
|
||||||
|
// program options for the plugin
|
||||||
|
fair::mq::Plugin::NoProgramOptions)
|
||||||
|
|
||||||
|
#endif /* FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN */
|
21
examples/custom-controller/MyDevice.h
Normal file
21
examples/custom-controller/MyDevice.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_DEVICE
|
||||||
|
#define FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_DEVICE
|
||||||
|
|
||||||
|
#include <fairmq/Device.h>
|
||||||
|
|
||||||
|
namespace example {
|
||||||
|
|
||||||
|
using MyDevice = fair::mq::Device;
|
||||||
|
|
||||||
|
} // namespace example
|
||||||
|
|
||||||
|
#endif /* FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_DEVICE */
|
||||||
|
|
46
examples/custom-controller/main.cxx
Normal file
46
examples/custom-controller/main.cxx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include "MyController.h"
|
||||||
|
#include "MyDevice.h"
|
||||||
|
|
||||||
|
#include <chrono> // for std::chrono_literals
|
||||||
|
#include <fairlogger/Logger.h>
|
||||||
|
#include <fairmq/DeviceRunner.h>
|
||||||
|
#include <memory> // for std::make_unique
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
using namespace fair::mq;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
DeviceRunner runner(argc, argv);
|
||||||
|
|
||||||
|
runner.AddHook<hooks::LoadPlugins>([](DeviceRunner& r) {
|
||||||
|
r.fPluginManager.LoadPlugin("s:mycontroller");
|
||||||
|
// 's:' stands for static because the plugin is compiled into the executable
|
||||||
|
// 'mycontroller' is the plugin name passed as second arg to REGISTER_FAIRMQ_PLUGIN
|
||||||
|
});
|
||||||
|
|
||||||
|
fair::Logger::SetConsoleSeverity(fair::Severity::debug);
|
||||||
|
|
||||||
|
runner.AddHook<hooks::InstantiateDevice>([](DeviceRunner& r) {
|
||||||
|
r.fConfig.SetProperty<int>("catch-signals", 0);
|
||||||
|
r.fConfig.SetProperty<bool>("please-shut-me-down", false);
|
||||||
|
r.fDevice = std::make_unique<example::MyDevice>(r.fConfig);
|
||||||
|
|
||||||
|
r.fDevice->SubscribeToStateChange("example", [&r](auto state) {
|
||||||
|
if (state == State::Running) {
|
||||||
|
r.fDevice->WaitFor(3s);
|
||||||
|
r.fConfig.SetProperty<bool>("please-shut-me-down", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return runner.RunWithExceptionHandlers();
|
||||||
|
}
|
|
@ -1,56 +1,11 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-multipart-sampler sampler.cxx)
|
add_example(NAME multipart
|
||||||
target_link_libraries(fairmq-ex-multipart-sampler PRIVATE FairMQ)
|
DEVICE sampler sink
|
||||||
|
|
||||||
add_executable(fairmq-ex-multipart-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-multipart-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleMultipart DEPENDS fairmq-ex-multipart-sampler fairmq-ex-multipart-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
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" PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
|
||||||
|
|
||||||
add_test(NAME Example.Multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh shmem)
|
|
||||||
set_tests_properties(Example.Multipart.shmem PROPERTIES TIMEOUT "30" 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" PASS_REGULAR_EXPRESSION "Received message with 7 parts")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-multipart-sampler
|
|
||||||
fairmq-ex-multipart-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multipart.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-multipart.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,6 +24,10 @@ struct Sink : fair::mq::Device
|
||||||
{
|
{
|
||||||
LOG(info) << "Received message with " << parts.Size() << " parts";
|
LOG(info) << "Received message with " << parts.Size() << " parts";
|
||||||
|
|
||||||
|
if (parts.Size() != 7) {
|
||||||
|
throw std::runtime_error("Number of received parts != 7");
|
||||||
|
}
|
||||||
|
|
||||||
example_multipart::Header header;
|
example_multipart::Header header;
|
||||||
header.stopFlag = (static_cast<example_multipart::Header*>(parts.At(0)->GetData()))->stopFlag;
|
header.stopFlag = (static_cast<example_multipart::Header*>(parts.At(0)->GetData()))->stopFlag;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -12,14 +14,10 @@ session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
||||||
chan="data"
|
chan="data"
|
||||||
chanAddr=""
|
chanAddr=""
|
||||||
chanIpcFile="/tmp/fmq_$session""_""$chan""_""$transport"
|
chanIpcFile="/tmp/fmq_$session""_""$chan""_""$transport"
|
||||||
if [ $transport = "ofi" ]; then
|
chanAddr="ipc://""$chanIpcFile"
|
||||||
chanAddr="tcp://127.0.0.1:5656"
|
|
||||||
else
|
|
||||||
chanAddr="ipc://""$chanIpcFile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanIpcFile' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanIpcFile; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-multipart-sampler"
|
SAMPLER="fairmq-ex-multipart-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -27,6 +25,7 @@ SAMPLER+=" --transport $transport"
|
||||||
SAMPLER+=" --verbosity veryhigh"
|
SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --session $session"
|
SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --max-iterations 1"
|
SAMPLER+=" --max-iterations 1"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --channel-config name=$chan,type=pair,method=connect,rateLogging=0,address=$chanAddr,linger=1000"
|
SAMPLER+=" --channel-config name=$chan,type=pair,method=connect,rateLogging=0,address=$chanAddr,linger=1000"
|
||||||
|
@ -39,6 +38,7 @@ SINK+=" --transport $transport"
|
||||||
SINK+=" --verbosity veryhigh"
|
SINK+=" --verbosity veryhigh"
|
||||||
SINK+=" --session $session"
|
SINK+=" --session $session"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
SINK+=" --channel-config name=$chan,type=pair,method=bind,rateLogging=0,address=$chanAddr"
|
SINK+=" --channel-config name=$chan,type=pair,method=bind,rateLogging=0,address=$chanAddr"
|
||||||
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
|
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
|
||||||
|
@ -47,4 +47,6 @@ SINK_PID=$!
|
||||||
wait $SAMPLER_PID
|
wait $SAMPLER_PID
|
||||||
wait $SINK_PID
|
wait $SINK_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chanIpcFile
|
rm $chanIpcFile
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,52 +1,12 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-multiple-channels-sampler sampler.cxx)
|
add_example(NAME multiple-channels
|
||||||
target_link_libraries(fairmq-ex-multiple-channels-sampler PRIVATE FairMQ)
|
DEVICE sampler broadcaster sink
|
||||||
|
TRANSPORT zeromq
|
||||||
add_executable(fairmq-ex-multiple-channels-broadcaster broadcaster.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-multiple-channels-broadcaster PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-multiple-channels-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-multiple-channels-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleMultipleChannels DEPENDS fairmq-ex-multiple-channels-sampler fairmq-ex-multiple-channels-broadcaster fairmq-ex-multiple-channels-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.MultipleChannels.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
|
|
||||||
set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-multiple-channels-sampler
|
|
||||||
fairmq-ex-multiple-channels-broadcaster
|
|
||||||
fairmq-ex-multiple-channels-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-channels.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-multiple-channels.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -15,7 +17,7 @@ dataChanAddr="/tmp/fmq_$session""_""$dataChan""_""$transport"
|
||||||
broadcastChanAddr="/tmp/fmq_$session""_""$broadcastChan""_""$transport"
|
broadcastChanAddr="/tmp/fmq_$session""_""$broadcastChan""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $BROADCASTER_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $BROADCASTER_PID; rm $dataChanAddr; rm $broadcastChanAddr' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $BROADCASTER_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $BROADCASTER_PID; rm $dataChanAddr; rm $broadcastChanAddr; exit 0' TERM
|
||||||
|
|
||||||
SINK="fairmq-ex-multiple-channels-sink"
|
SINK="fairmq-ex-multiple-channels-sink"
|
||||||
SINK+=" --id sink1"
|
SINK+=" --id sink1"
|
||||||
|
@ -23,6 +25,7 @@ SINK+=" --session $session"
|
||||||
SINK+=" --transport $transport"
|
SINK+=" --transport $transport"
|
||||||
SINK+=" --verbosity veryhigh --severity debug"
|
SINK+=" --verbosity veryhigh --severity debug"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --max-iterations 1"
|
SINK+=" --max-iterations 1"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
SINK+=" --channel-config name=$dataChan,type=pull,method=connect,rateLogging=0,address=ipc://$dataChanAddr"
|
SINK+=" --channel-config name=$dataChan,type=pull,method=connect,rateLogging=0,address=ipc://$dataChanAddr"
|
||||||
|
@ -38,6 +41,7 @@ SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --transport $transport"
|
SAMPLER+=" --transport $transport"
|
||||||
SAMPLER+=" --verbosity veryhigh --severity debug"
|
SAMPLER+=" --verbosity veryhigh --severity debug"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --max-iterations 1"
|
SAMPLER+=" --max-iterations 1"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --channel-config name=$dataChan,type=push,method=bind,rateLogging=0,address=ipc://$dataChanAddr"
|
SAMPLER+=" --channel-config name=$dataChan,type=push,method=bind,rateLogging=0,address=ipc://$dataChanAddr"
|
||||||
|
@ -51,6 +55,7 @@ BROADCASTER+=" --session $session"
|
||||||
BROADCASTER+=" --transport $transport"
|
BROADCASTER+=" --transport $transport"
|
||||||
BROADCASTER+=" --verbosity veryhigh --severity debug"
|
BROADCASTER+=" --verbosity veryhigh --severity debug"
|
||||||
BROADCASTER+=" --shm-segment-size 100000000"
|
BROADCASTER+=" --shm-segment-size 100000000"
|
||||||
|
BROADCASTER+=" --shm-monitor true"
|
||||||
BROADCASTER+=" --control static --color false"
|
BROADCASTER+=" --control static --color false"
|
||||||
BROADCASTER+=" --channel-config name=$broadcastChan,type=pub,method=bind,rateLogging=0,address=ipc://$broadcastChanAddr"
|
BROADCASTER+=" --channel-config name=$broadcastChan,type=pub,method=bind,rateLogging=0,address=ipc://$broadcastChanAddr"
|
||||||
@CMAKE_CURRENT_BINARY_DIR@/$BROADCASTER &
|
@CMAKE_CURRENT_BINARY_DIR@/$BROADCASTER &
|
||||||
|
@ -65,4 +70,6 @@ kill -SIGINT $BROADCASTER_PID
|
||||||
# wait for broadcaster to finish
|
# wait for broadcaster to finish
|
||||||
wait $BROADCASTER_PID
|
wait $BROADCASTER_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $dataChanAddr; rm $broadcastChanAddr
|
rm $dataChanAddr; rm $broadcastChanAddr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,51 +1,12 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-multiple-transports-sampler1 sampler1.cxx)
|
add_example(NAME multiple-transports
|
||||||
target_link_libraries(fairmq-ex-multiple-transports-sampler1 PRIVATE FairMQ)
|
DEVICE sampler1 sampler2 sink
|
||||||
|
NO_TRANSPORT
|
||||||
add_executable(fairmq-ex-multiple-transports-sampler2 sampler2.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-multiple-transports-sampler2 PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-multiple-transports-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-multiple-transports-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleMultipleTransports DEPENDS fairmq-ex-multiple-transports-sampler1 fairmq-ex-multiple-transports-sampler2 fairmq-ex-multiple-transports-sink)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-transports.sh)
|
|
||||||
add_test(NAME Example.MultipleTransports COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-transports.sh)
|
|
||||||
set_tests_properties(Example.MultipleTransports PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-multiple-transports-sampler1
|
|
||||||
fairmq-ex-multiple-transports-sampler2
|
|
||||||
fairmq-ex-multiple-transports-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-multiple-transports.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-multiple-transports.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/runDevice.h>
|
#include <fairmq/runDevice.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace bpo = boost::program_options;
|
namespace bpo = boost::program_options;
|
||||||
|
|
||||||
struct Sink : fair::mq::Device
|
struct Sink : fair::mq::Device
|
||||||
|
@ -32,7 +34,7 @@ struct Sink : fair::mq::Device
|
||||||
// Creates a message using the transport of channel ack
|
// Creates a message using the transport of channel ack
|
||||||
fair::mq::MessagePtr ack(NewMessageFor("ack", 0));
|
fair::mq::MessagePtr ack(NewMessageFor("ack", 0));
|
||||||
if (Send(ack, "ack") < 0) {
|
if (Send(ack, "ack") < 0) {
|
||||||
return false;
|
throw std::runtime_error("could not send an ack");
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if want to be called again (otherwise go to IDLE state)
|
// return true if want to be called again (otherwise go to IDLE state)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
||||||
|
@ -10,12 +12,13 @@ chan1Addr="/tmp/fmq_$session""_""$chan1"
|
||||||
chan2Addr="/tmp/fmq_$session""_""$chan2"
|
chan2Addr="/tmp/fmq_$session""_""$chan2"
|
||||||
ackChanAddr="/tmp/fmq_$session""_""$ackChan"
|
ackChanAddr="/tmp/fmq_$session""_""$ackChan"
|
||||||
|
|
||||||
trap 'kill -TERM $SAMPLER1_PID; kill -TERM $SAMPLER2_PID; kill -TERM $SINK_PID; wait $SAMPLER1_PID; wait $SAMPLER2_PID; wait $SINK_PID; @CMAKE_BINARY_DIR@/fairmq/fairmq-shmmonitor --cleanup --session $SESSION; rm $chan1Addr; rm $chan2Addr; rm $ackChanAddr' TERM
|
trap 'set +e; kill -TERM $SAMPLER1_PID; kill -TERM $SAMPLER2_PID; kill -TERM $SINK_PID; wait $SAMPLER1_PID; wait $SAMPLER2_PID; wait $SINK_PID; @CMAKE_BINARY_DIR@/fairmq/fairmq-shmmonitor --cleanup --session $SESSION; rm $chan1Addr; rm $chan2Addr; rm $ackChanAddr; exit 0' TERM
|
||||||
|
|
||||||
SINK="fairmq-ex-multiple-transports-sink"
|
SINK="fairmq-ex-multiple-transports-sink"
|
||||||
SINK+=" --id sink1"
|
SINK+=" --id sink1"
|
||||||
SINK+=" --verbosity veryhigh --severity debug"
|
SINK+=" --verbosity veryhigh --severity debug"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --session $session"
|
SINK+=" --session $session"
|
||||||
SINK+=" --max-iterations 1"
|
SINK+=" --max-iterations 1"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
|
@ -31,6 +34,7 @@ SAMPLER1+=" --id sampler1"
|
||||||
SAMPLER1+=" --session $session"
|
SAMPLER1+=" --session $session"
|
||||||
SAMPLER1+=" --verbosity veryhigh --severity debug"
|
SAMPLER1+=" --verbosity veryhigh --severity debug"
|
||||||
SAMPLER1+=" --shm-segment-size 100000000"
|
SAMPLER1+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER1+=" --shm-monitor true"
|
||||||
SAMPLER1+=" --max-iterations 1"
|
SAMPLER1+=" --max-iterations 1"
|
||||||
SAMPLER1+=" --control static --color false"
|
SAMPLER1+=" --control static --color false"
|
||||||
SAMPLER1+=" --transport shmem"
|
SAMPLER1+=" --transport shmem"
|
||||||
|
@ -44,6 +48,7 @@ SAMPLER2+=" --id sampler2"
|
||||||
SAMPLER2+=" --session $session"
|
SAMPLER2+=" --session $session"
|
||||||
SAMPLER2+=" --verbosity veryhigh --severity debug"
|
SAMPLER2+=" --verbosity veryhigh --severity debug"
|
||||||
SAMPLER2+=" --shm-segment-size 100000000"
|
SAMPLER2+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER2+=" --shm-monitor true"
|
||||||
SAMPLER2+=" --max-iterations 1"
|
SAMPLER2+=" --max-iterations 1"
|
||||||
SAMPLER2+=" --control static --color false"
|
SAMPLER2+=" --control static --color false"
|
||||||
SAMPLER2+=" --transport zeromq"
|
SAMPLER2+=" --transport zeromq"
|
||||||
|
@ -55,4 +60,6 @@ wait $SAMPLER1_PID
|
||||||
wait $SAMPLER2_PID
|
wait $SAMPLER2_PID
|
||||||
wait $SINK_PID
|
wait $SINK_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chan1Addr; rm $chan2Addr; rm $ackChanAddr
|
rm $chan1Addr; rm $chan2Addr; rm $ackChanAddr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2020-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -54,7 +54,7 @@ struct Receiver : fair::mq::Device
|
||||||
fBuffer[h.id].start = chrono::steady_clock::now();
|
fBuffer[h.id].start = chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
// if the received ID has not previously been discarded, store the data part in the buffer
|
// if the received ID has not previously been discarded, store the data part in the buffer
|
||||||
fBuffer[h.id].parts.AddPart(move(parts.At(1)));
|
fBuffer[h.id].parts.AddPart(std::move(parts.At(1)));
|
||||||
} else {
|
} else {
|
||||||
// if received ID has been previously discarded.
|
// if received ID has been previously discarded.
|
||||||
LOG(debug) << "Received part from an already discarded timeframe with id " << h.id;
|
LOG(debug) << "Received part from an already discarded timeframe with id " << h.id;
|
||||||
|
@ -93,7 +93,7 @@ struct Receiver : fair::mq::Device
|
||||||
unordered_map<uint16_t, TFBuffer> fBuffer;
|
unordered_map<uint16_t, TFBuffer> fBuffer;
|
||||||
unordered_set<uint16_t> fDiscardedSet;
|
unordered_set<uint16_t> fDiscardedSet;
|
||||||
|
|
||||||
int fNumSenders = 0;
|
unsigned int fNumSenders = 0;
|
||||||
int fBufferTimeoutInMs = 5000;
|
int fBufferTimeoutInMs = 5000;
|
||||||
int fMaxTimeframes = 0;
|
int fMaxTimeframes = 0;
|
||||||
int fTimeframeCounter = 0;
|
int fTimeframeCounter = 0;
|
||||||
|
|
|
@ -1,59 +1,13 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-readout-readout readout.cxx)
|
add_example(NAME readout
|
||||||
target_link_libraries(fairmq-ex-readout-readout PRIVATE FairMQ)
|
DEVICE readout builder processor sender receiver
|
||||||
|
SCRIPT readout readout-processing
|
||||||
add_executable(fairmq-ex-readout-builder builder.cxx)
|
NO_TEST
|
||||||
target_link_libraries(fairmq-ex-readout-builder PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-readout-processor processor.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-readout-processor PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-readout-sender sender.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-readout-sender PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-readout-receiver receiver.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-readout-receiver PRIVATE FairMQ)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh)
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-readout-readout
|
|
||||||
fairmq-ex-readout-builder
|
|
||||||
fairmq-ex-readout-processor
|
|
||||||
fairmq-ex-readout-sender
|
|
||||||
fairmq-ex-readout-receiver
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-readout-processing.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-readout.sh
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-readout-processing.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-readout-processing.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,19 +7,19 @@ This examples shows two possible topologies (out of many) for a node connected t
|
||||||
```
|
```
|
||||||
|------------------------------- Readout Node ---------------------------| |- Processing Node -|
|
|------------------------------- Readout Node ---------------------------| |- Processing Node -|
|
||||||
| Readout --> Builder --> Sender | --> | Receiver |
|
| Readout --> Builder --> Sender | --> | Receiver |
|
||||||
| [# shared memory segment (unused in this topology) ##################] | ofi | |
|
| [# shared memory segment (unused in this topology) ##################] | zmq | |
|
||||||
| [# shmem unmanaged region (readout writes here, others read) ########] | | |
|
| [# shmem unmanaged region (readout writes here, others read) ########] | | |
|
||||||
|------------------------------------------------------------------------| |-------------------|
|
|------------------------------------------------------------------------| |-------------------|
|
||||||
```
|
```
|
||||||
|
|
||||||
The devices one the Readout Node communicate via shared memory transport. Readout device writes into shared memory unmanaged region. The data is then forwarded through Builder to Sender process, which sends it out via OFI transport.
|
The devices one the Readout Node communicate via shared memory transport. Readout device writes into shared memory unmanaged region. The data is then forwarded through Builder to Sender process, which sends it out via zeromq transport.
|
||||||
|
|
||||||
## Setup with generating new data on the Readout node
|
## Setup with generating new data on the Readout node
|
||||||
|
|
||||||
```
|
```
|
||||||
|------------------------------- Readout Node ---------------------------| |- Processing Node -|
|
|------------------------------- Readout Node ---------------------------| |- Processing Node -|
|
||||||
| Readout --> Builder --> Processor --> Sender | --> | Receiver |
|
| Readout --> Builder --> Processor --> Sender | --> | Receiver |
|
||||||
| [# shared memory segment (used between Proccessor and Sender) #######] | ofi | |
|
| [# shared memory segment (used between Proccessor and Sender) #######] | zmq | |
|
||||||
| [# shmem unmanaged region (readout writes here, builder & proc read) ] | | |
|
| [# shmem unmanaged region (readout writes here, builder & proc read) ] | | |
|
||||||
|------------------------------------------------------------------------| |-------------------|
|
|------------------------------------------------------------------------| |-------------------|
|
||||||
```
|
```
|
||||||
|
|
|
@ -31,12 +31,10 @@ SENDER="fairmq-ex-readout-sender"
|
||||||
SENDER+=" --id sender1"
|
SENDER+=" --id sender1"
|
||||||
SENDER+=" --input-name ps"
|
SENDER+=" --input-name ps"
|
||||||
SENDER+=" --channel-config name=ps,type=pair,method=bind,address=tcp://localhost:7779,transport=shmem"
|
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=zeromq"
|
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7780,transport=zeromq"
|
||||||
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
||||||
|
|
||||||
RECEIVER="fairmq-ex-readout-receiver"
|
RECEIVER="fairmq-ex-readout-receiver"
|
||||||
RECEIVER+=" --id receiver1"
|
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=zeromq"
|
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 &
|
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &
|
||||||
|
|
|
@ -25,12 +25,10 @@ SENDER="fairmq-ex-readout-sender"
|
||||||
SENDER+=" --id sender1"
|
SENDER+=" --id sender1"
|
||||||
SENDER+=" --input-name bs"
|
SENDER+=" --input-name bs"
|
||||||
SENDER+=" --channel-config name=bs,type=pair,method=bind,address=tcp://localhost:7778,transport=shmem"
|
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=zeromq"
|
SENDER+=" name=sr,type=pair,method=connect,address=tcp://localhost:7779,transport=zeromq"
|
||||||
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
xterm -geometry 80x23+1000+0 -hold -e @EX_BIN_DIR@/$SENDER &
|
||||||
|
|
||||||
RECEIVER="fairmq-ex-readout-receiver"
|
RECEIVER="fairmq-ex-readout-receiver"
|
||||||
RECEIVER+=" --id receiver1"
|
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=zeromq"
|
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 &
|
xterm -geometry 80x23+1500+0 -hold -e @EX_BIN_DIR@/$RECEIVER &
|
||||||
|
|
|
@ -1,54 +1,12 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-region-sampler sampler.cxx)
|
add_example(NAME region
|
||||||
target_link_libraries(fairmq-ex-region-sampler PRIVATE FairMQ)
|
DEVICE sampler processor sink keep-alive
|
||||||
|
SCRIPT region region-advanced region-advanced-external
|
||||||
add_executable(fairmq-ex-region-sink sink.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-region-sink PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-region-keep-alive keep-alive.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-region-keep-alive PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleRegion DEPENDS fairmq-ex-region-sampler fairmq-ex-region-sink fairmq-ex-region-keep-alive)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.Region.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh zeromq)
|
|
||||||
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
|
|
||||||
|
|
||||||
add_test(NAME Example.Region.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh shmem)
|
|
||||||
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-region-sampler
|
|
||||||
fairmq-ex-region-sink
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-region.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-region.sh
|
|
||||||
)
|
)
|
||||||
|
|
95
examples/region/fairmq-start-ex-region-advanced-external.sh.in
Executable file
95
examples/region/fairmq-start-ex-region-advanced-external.sh.in
Executable file
|
@ -0,0 +1,95 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
|
transport=${1:-shmem}
|
||||||
|
msgSize=${2:-1000000}
|
||||||
|
|
||||||
|
SAMPLER="fairmq-ex-region-sampler"
|
||||||
|
SAMPLER+=" --id sampler1"
|
||||||
|
# SAMPLER+=" --sampling-rate 10"
|
||||||
|
SAMPLER+=" --severity debug"
|
||||||
|
SAMPLER+=" --msg-size $msgSize"
|
||||||
|
SAMPLER+=" --transport $transport"
|
||||||
|
SAMPLER+=" --shmid 1"
|
||||||
|
SAMPLER+=" --shm-monitor false"
|
||||||
|
SAMPLER+=" --rc-segment-size 200000000"
|
||||||
|
SAMPLER+=" --external-region true"
|
||||||
|
SAMPLER+=" --shm-no-cleanup true"
|
||||||
|
SAMPLER+=" --chan-name data1"
|
||||||
|
SAMPLER+=" --channel-config name=data1,type=push,method=bind,address=tcp://127.0.0.1:7777"
|
||||||
|
xterm -geometry 90x60+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
|
||||||
|
|
||||||
|
PROCESSOR1="fairmq-ex-region-processor"
|
||||||
|
PROCESSOR1+=" --id processor1"
|
||||||
|
PROCESSOR1+=" --severity debug"
|
||||||
|
PROCESSOR1+=" --transport $transport"
|
||||||
|
PROCESSOR1+=" --shmid 1"
|
||||||
|
PROCESSOR1+=" --shm-segment-id 1"
|
||||||
|
PROCESSOR1+=" --shm-monitor false"
|
||||||
|
PROCESSOR1+=" --shm-no-cleanup true"
|
||||||
|
PROCESSOR1+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:7777"
|
||||||
|
PROCESSOR1+=" name=data2,type=push,method=bind,address=tcp://127.0.0.1:7778"
|
||||||
|
PROCESSOR1+=" name=data3,type=push,method=bind,address=tcp://127.0.0.1:7779"
|
||||||
|
xterm -geometry 90x40+550+40 -hold -e @EX_BIN_DIR@/$PROCESSOR1 &
|
||||||
|
|
||||||
|
PROCESSOR2="fairmq-ex-region-processor"
|
||||||
|
PROCESSOR2+=" --id processor2"
|
||||||
|
PROCESSOR2+=" --severity debug"
|
||||||
|
PROCESSOR2+=" --transport $transport"
|
||||||
|
PROCESSOR2+=" --shmid 1"
|
||||||
|
PROCESSOR2+=" --shm-segment-id 2"
|
||||||
|
PROCESSOR2+=" --shm-monitor false"
|
||||||
|
PROCESSOR2+=" --shm-no-cleanup true"
|
||||||
|
PROCESSOR2+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:7777"
|
||||||
|
PROCESSOR2+=" name=data2,type=push,method=bind,address=tcp://127.0.0.1:7788"
|
||||||
|
PROCESSOR2+=" name=data3,type=push,method=bind,address=tcp://127.0.0.1:7789"
|
||||||
|
xterm -geometry 90x40+550+600 -hold -e @EX_BIN_DIR@/$PROCESSOR2 &
|
||||||
|
|
||||||
|
SINK1_1="fairmq-ex-region-sink"
|
||||||
|
SINK1_1+=" --id sink1_1"
|
||||||
|
SINK1_1+=" --severity debug"
|
||||||
|
SINK1_1+=" --chan-name data2"
|
||||||
|
SINK1_1+=" --transport $transport"
|
||||||
|
SINK1_1+=" --shmid 1"
|
||||||
|
SINK1_1+=" --shm-segment-id 1"
|
||||||
|
SINK1_1+=" --shm-monitor false"
|
||||||
|
SINK1_1+=" --shm-no-cleanup true"
|
||||||
|
SINK1_1+=" --channel-config name=data2,type=pull,method=connect,address=tcp://127.0.0.1:7778"
|
||||||
|
xterm -geometry 90x20+1100+0 -hold -e @EX_BIN_DIR@/$SINK1_1 &
|
||||||
|
|
||||||
|
SINK1_2="fairmq-ex-region-sink"
|
||||||
|
SINK1_2+=" --id sink1_2"
|
||||||
|
SINK1_2+=" --severity debug"
|
||||||
|
SINK1_2+=" --chan-name data3"
|
||||||
|
SINK1_2+=" --transport $transport"
|
||||||
|
SINK1_2+=" --shmid 1"
|
||||||
|
SINK1_2+=" --shm-segment-id 1"
|
||||||
|
SINK1_2+=" --shm-monitor false"
|
||||||
|
SINK1_2+=" --shm-no-cleanup true"
|
||||||
|
SINK1_2+=" --channel-config name=data3,type=pull,method=connect,address=tcp://127.0.0.1:7779"
|
||||||
|
xterm -geometry 90x20+1100+300 -hold -e @EX_BIN_DIR@/$SINK1_2 &
|
||||||
|
|
||||||
|
SINK2_1="fairmq-ex-region-sink"
|
||||||
|
SINK2_1+=" --id sink2_1"
|
||||||
|
SINK2_1+=" --severity debug"
|
||||||
|
SINK2_1+=" --chan-name data2"
|
||||||
|
SINK2_1+=" --transport $transport"
|
||||||
|
SINK2_1+=" --shmid 1"
|
||||||
|
SINK2_1+=" --shm-segment-id 2"
|
||||||
|
SINK2_1+=" --shm-monitor false"
|
||||||
|
SINK2_1+=" --shm-no-cleanup true"
|
||||||
|
SINK2_1+=" --channel-config name=data2,type=pull,method=connect,address=tcp://127.0.0.1:7788"
|
||||||
|
xterm -geometry 90x20+1100+600 -hold -e @EX_BIN_DIR@/$SINK2_1 &
|
||||||
|
|
||||||
|
SINK2_2="fairmq-ex-region-sink"
|
||||||
|
SINK2_2+=" --id sink2_2"
|
||||||
|
SINK2_2+=" --severity debug"
|
||||||
|
SINK2_2+=" --chan-name data3"
|
||||||
|
SINK2_2+=" --transport $transport"
|
||||||
|
SINK2_2+=" --shmid 1"
|
||||||
|
SINK2_2+=" --shm-segment-id 2"
|
||||||
|
SINK2_2+=" --shm-monitor false"
|
||||||
|
SINK2_2+=" --shm-no-cleanup true"
|
||||||
|
SINK2_2+=" --channel-config name=data3,type=pull,method=connect,address=tcp://127.0.0.1:7789"
|
||||||
|
xterm -geometry 90x20+1100+900 -hold -e @EX_BIN_DIR@/$SINK2_2 &
|
80
examples/region/fairmq-start-ex-region-advanced.sh.in
Executable file
80
examples/region/fairmq-start-ex-region-advanced.sh.in
Executable file
|
@ -0,0 +1,80 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
|
transport=${1:-shmem}
|
||||||
|
msgSize=${2:-1000000}
|
||||||
|
|
||||||
|
SAMPLER="fairmq-ex-region-sampler"
|
||||||
|
SAMPLER+=" --id sampler1"
|
||||||
|
# SAMPLER+=" --sampling-rate 10"
|
||||||
|
SAMPLER+=" --severity debug"
|
||||||
|
SAMPLER+=" --msg-size $msgSize"
|
||||||
|
SAMPLER+=" --transport $transport"
|
||||||
|
#SAMPLER+=" --rc-segment-size 0"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
|
SAMPLER+=" --chan-name data1"
|
||||||
|
SAMPLER+=" --channel-config name=data1,type=push,method=bind,address=tcp://127.0.0.1:7777"
|
||||||
|
xterm -geometry 90x60+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
|
||||||
|
|
||||||
|
PROCESSOR1="fairmq-ex-region-processor"
|
||||||
|
PROCESSOR1+=" --id processor1"
|
||||||
|
PROCESSOR1+=" --severity debug"
|
||||||
|
PROCESSOR1+=" --transport $transport"
|
||||||
|
PROCESSOR1+=" --shm-segment-id 1"
|
||||||
|
PROCESSOR1+=" --shm-monitor true"
|
||||||
|
PROCESSOR1+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:7777"
|
||||||
|
PROCESSOR1+=" name=data2,type=push,method=bind,address=tcp://127.0.0.1:7778"
|
||||||
|
PROCESSOR1+=" name=data3,type=push,method=bind,address=tcp://127.0.0.1:7779"
|
||||||
|
xterm -geometry 90x40+550+40 -hold -e @EX_BIN_DIR@/$PROCESSOR1 &
|
||||||
|
|
||||||
|
PROCESSOR2="fairmq-ex-region-processor"
|
||||||
|
PROCESSOR2+=" --id processor2"
|
||||||
|
PROCESSOR2+=" --severity debug"
|
||||||
|
PROCESSOR2+=" --transport $transport"
|
||||||
|
PROCESSOR2+=" --shm-segment-id 2"
|
||||||
|
PROCESSOR2+=" --shm-monitor true"
|
||||||
|
PROCESSOR2+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:7777"
|
||||||
|
PROCESSOR2+=" name=data2,type=push,method=bind,address=tcp://127.0.0.1:7788"
|
||||||
|
PROCESSOR2+=" name=data3,type=push,method=bind,address=tcp://127.0.0.1:7789"
|
||||||
|
xterm -geometry 90x40+550+600 -hold -e @EX_BIN_DIR@/$PROCESSOR2 &
|
||||||
|
|
||||||
|
SINK1_1="fairmq-ex-region-sink"
|
||||||
|
SINK1_1+=" --id sink1_1"
|
||||||
|
SINK1_1+=" --severity debug"
|
||||||
|
SINK1_1+=" --chan-name data2"
|
||||||
|
SINK1_1+=" --transport $transport"
|
||||||
|
SINK1_1+=" --shm-segment-id 1"
|
||||||
|
SINK1_1+=" --shm-monitor true"
|
||||||
|
SINK1_1+=" --channel-config name=data2,type=pull,method=connect,address=tcp://127.0.0.1:7778"
|
||||||
|
xterm -geometry 90x20+1100+0 -hold -e @EX_BIN_DIR@/$SINK1_1 &
|
||||||
|
|
||||||
|
SINK1_2="fairmq-ex-region-sink"
|
||||||
|
SINK1_2+=" --id sink1_2"
|
||||||
|
SINK1_2+=" --severity debug"
|
||||||
|
SINK1_2+=" --chan-name data3"
|
||||||
|
SINK1_2+=" --transport $transport"
|
||||||
|
SINK1_2+=" --shm-segment-id 1"
|
||||||
|
SINK1_2+=" --shm-monitor true"
|
||||||
|
SINK1_2+=" --channel-config name=data3,type=pull,method=connect,address=tcp://127.0.0.1:7779"
|
||||||
|
xterm -geometry 90x20+1100+300 -hold -e @EX_BIN_DIR@/$SINK1_2 &
|
||||||
|
|
||||||
|
SINK2_1="fairmq-ex-region-sink"
|
||||||
|
SINK2_1+=" --id sink2_1"
|
||||||
|
SINK2_1+=" --severity debug"
|
||||||
|
SINK2_1+=" --chan-name data2"
|
||||||
|
SINK2_1+=" --transport $transport"
|
||||||
|
SINK2_1+=" --shm-segment-id 2"
|
||||||
|
SINK2_1+=" --shm-monitor true"
|
||||||
|
SINK2_1+=" --channel-config name=data2,type=pull,method=connect,address=tcp://127.0.0.1:7788"
|
||||||
|
xterm -geometry 90x20+1100+600 -hold -e @EX_BIN_DIR@/$SINK2_1 &
|
||||||
|
|
||||||
|
SINK2_2="fairmq-ex-region-sink"
|
||||||
|
SINK2_2+=" --id sink2_2"
|
||||||
|
SINK2_2+=" --severity debug"
|
||||||
|
SINK2_2+=" --chan-name data3"
|
||||||
|
SINK2_2+=" --transport $transport"
|
||||||
|
SINK2_2+=" --shm-segment-id 2"
|
||||||
|
SINK2_2+=" --shm-monitor true"
|
||||||
|
SINK2_2+=" --channel-config name=data3,type=pull,method=connect,address=tcp://127.0.0.1:7789"
|
||||||
|
xterm -geometry 90x20+1100+900 -hold -e @EX_BIN_DIR@/$SINK2_2 &
|
|
@ -2,16 +2,8 @@
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="shmem"
|
transport=${1:-shmem}
|
||||||
msgSize="1000000"
|
msgSize=${2:-1000000}
|
||||||
|
|
||||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
|
||||||
transport=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $2 =~ ^[0-9]+$ ]]; then
|
|
||||||
msgSize=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-region-sampler"
|
SAMPLER="fairmq-ex-region-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -19,6 +11,10 @@ SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --msg-size $msgSize"
|
SAMPLER+=" --msg-size $msgSize"
|
||||||
# SAMPLER+=" --rate 10"
|
# SAMPLER+=" --rate 10"
|
||||||
SAMPLER+=" --transport $transport"
|
SAMPLER+=" --transport $transport"
|
||||||
|
# SAMPLER+=" --external-region true"
|
||||||
|
# SAMPLER+=" --shm-no-cleaup true"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
|
# SAMPLER+=" --shmid 1"
|
||||||
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777,sndKernelSize=212992"
|
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777,sndKernelSize=212992"
|
||||||
xterm -geometry 120x60+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
|
xterm -geometry 120x60+0+0 -hold -e @EX_BIN_DIR@/$SAMPLER &
|
||||||
|
|
||||||
|
@ -26,5 +22,8 @@ SINK="fairmq-ex-region-sink"
|
||||||
SINK+=" --id sink1"
|
SINK+=" --id sink1"
|
||||||
SINK+=" --severity debug"
|
SINK+=" --severity debug"
|
||||||
SINK+=" --transport $transport"
|
SINK+=" --transport $transport"
|
||||||
|
# SINK+=" --shm-no-cleaup true"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
|
# SINK+=" --shmid 1"
|
||||||
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:7777,rcvKernelSize=212992"
|
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:7777,rcvKernelSize=212992"
|
||||||
xterm -geometry 120x60+750+0 -hold -e @EX_BIN_DIR@/$SINK &
|
xterm -geometry 120x60+750+0 -hold -e @EX_BIN_DIR@/$SINK &
|
||||||
|
|
|
@ -6,10 +6,9 @@
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
#include <fairmq/shmem/Common.h>
|
#include <fairmq/shmem/Common.h>
|
||||||
#include <fairmq/shmem/UnmanagedRegion.h>
|
|
||||||
#include <fairmq/shmem/Segment.h>
|
|
||||||
#include <fairmq/shmem/Monitor.h>
|
#include <fairmq/shmem/Monitor.h>
|
||||||
|
#include <fairmq/shmem/Segment.h>
|
||||||
|
#include <fairmq/shmem/UnmanagedRegion.h>
|
||||||
#include <fairmq/tools/Unique.h>
|
#include <fairmq/tools/Unique.h>
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
@ -17,75 +16,130 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <csignal>
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <csignal>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::program_options;
|
using namespace boost::program_options;
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
volatile sig_atomic_t gStopping = 0;
|
||||||
volatile sig_atomic_t gStopping = 0;
|
volatile sig_atomic_t gResetContent = 0;
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
void signalHandler(int /* signal */)
|
void signalHandler(int /* signal */) { gStopping = 1; }
|
||||||
{
|
|
||||||
gStopping = 1;
|
void resetContentHandler(int /* signal */) { gResetContent = 1; }
|
||||||
}
|
|
||||||
|
|
||||||
struct ShmManager
|
struct ShmManager
|
||||||
{
|
{
|
||||||
ShmManager(uint64_t _shmId, const vector<string>& _segments, const vector<string>& _regions)
|
ShmManager(uint64_t _shmId, const vector<string>& _segments, const vector<string>& _regions, bool zero = true)
|
||||||
: shmId(fair::mq::shmem::makeShmIdStr(_shmId))
|
: shmId(fair::mq::shmem::makeShmIdStr(_shmId))
|
||||||
{
|
{
|
||||||
for (const auto& s : _segments) {
|
LOG(info) << "Starting ShmManager for shmId: " << shmId;
|
||||||
vector<string> segmentConf;
|
LOG(info) << "Performing full reset...";
|
||||||
boost::algorithm::split(segmentConf, s, boost::algorithm::is_any_of(","));
|
FullReset();
|
||||||
if (segmentConf.size() != 2) {
|
LOG(info) << "Done.";
|
||||||
LOG(error) << "incorrect format for --segments. Expecting pairs of <id>,<size>.";
|
LOG(info) << "Adding managed segments...";
|
||||||
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
|
AddSegments(_segments, zero);
|
||||||
throw runtime_error("incorrect format for --segments. Expecting pairs of <id>,<size>.");
|
LOG(info) << "Done.";
|
||||||
|
LOG(info) << "Adding unmanaged regions...";
|
||||||
|
AddRegions(_regions, zero);
|
||||||
|
LOG(info) << "Done.";
|
||||||
|
LOG(info) << "Shared memory is ready for use.";
|
||||||
}
|
}
|
||||||
uint16_t id = stoi(segmentConf.at(0));
|
|
||||||
uint64_t size = stoull(segmentConf.at(1));
|
void AddSegments(const vector<string>& _segments, bool zero)
|
||||||
|
{
|
||||||
|
for (const auto& s : _segments) {
|
||||||
|
vector<string> conf;
|
||||||
|
boost::algorithm::split(conf, s, boost::algorithm::is_any_of(","));
|
||||||
|
if (conf.size() != 3) {
|
||||||
|
LOG(error) << "incorrect format for --segments. Expecting pairs of <id>,<size><numaid>.";
|
||||||
|
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
|
||||||
|
throw runtime_error("incorrect format for --segments. Expecting pairs of <id>,<size>,<numaid>.");
|
||||||
|
}
|
||||||
|
uint16_t id = stoi(conf.at(0));
|
||||||
|
uint64_t size = stoull(conf.at(1));
|
||||||
|
segmentCfgs.emplace_back(fair::mq::shmem::SegmentConfig{id, size, "rbtree_best_fit"});
|
||||||
|
|
||||||
auto ret = segments.emplace(id, fair::mq::shmem::Segment(shmId, id, size, fair::mq::shmem::rbTreeBestFit));
|
auto ret = segments.emplace(id, fair::mq::shmem::Segment(shmId, id, size, fair::mq::shmem::rbTreeBestFit));
|
||||||
fair::mq::shmem::Segment& segment = ret.first->second;
|
fair::mq::shmem::Segment& segment = ret.first->second;
|
||||||
LOG(info) << "Created segment " << id << " of size " << segment.GetSize() << ", starting at " << segment.GetData() << ". Locking...";
|
LOG(info) << "Created segment " << id << " of size " << segment.GetSize()
|
||||||
|
<< ", starting at " << segment.GetData() << ". Locking...";
|
||||||
segment.Lock();
|
segment.Lock();
|
||||||
LOG(info) << "Done.";
|
LOG(info) << "Done.";
|
||||||
|
if (zero) {
|
||||||
LOG(info) << "Zeroing...";
|
LOG(info) << "Zeroing...";
|
||||||
segment.Zero();
|
segment.Zero();
|
||||||
LOG(info) << "Done.";
|
LOG(info) << "Done.";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& r : _regions) {
|
|
||||||
vector<string> regionConf;
|
|
||||||
boost::algorithm::split(regionConf, r, boost::algorithm::is_any_of(","));
|
|
||||||
if (regionConf.size() != 2) {
|
|
||||||
LOG(error) << "incorrect format for --regions. Expecting pairs of <id>,<size>.";
|
|
||||||
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
|
|
||||||
throw runtime_error("incorrect format for --regions. Expecting pairs of <id>,<size>.");
|
|
||||||
}
|
}
|
||||||
uint16_t id = stoi(regionConf.at(0));
|
}
|
||||||
uint64_t size = stoull(regionConf.at(1));
|
|
||||||
auto ret = regions.emplace(id, make_unique<fair::mq::shmem::UnmanagedRegion>(shmId, id, size));
|
void AddRegions(const vector<string>& _regions, bool zero)
|
||||||
|
{
|
||||||
|
for (const auto& r : _regions) {
|
||||||
|
vector<string> conf;
|
||||||
|
boost::algorithm::split(conf, r, boost::algorithm::is_any_of(","));
|
||||||
|
if (conf.size() != 3) {
|
||||||
|
LOG(error) << "incorrect format for --regions. Expecting pairs of <id>,<size>,<numaid>.";
|
||||||
|
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
|
||||||
|
throw runtime_error("incorrect format for --regions. Expecting pairs of <id>,<size>,<numaid>.");
|
||||||
|
}
|
||||||
|
uint16_t id = stoi(conf.at(0));
|
||||||
|
uint64_t size = stoull(conf.at(1));
|
||||||
|
fair::mq::RegionConfig cfg;
|
||||||
|
cfg.id = id;
|
||||||
|
cfg.rcSegmentSize = 0;
|
||||||
|
cfg.size = size;
|
||||||
|
regionCfgs.push_back(cfg);
|
||||||
|
|
||||||
|
auto ret = regions.emplace(id, make_unique<fair::mq::shmem::UnmanagedRegion>(shmId, cfg));
|
||||||
fair::mq::shmem::UnmanagedRegion& region = *(ret.first->second);
|
fair::mq::shmem::UnmanagedRegion& region = *(ret.first->second);
|
||||||
LOG(info) << "Created unamanged region " << id << " of size " << region.GetSize() << ", starting at " << region.GetData() << ". Locking...";
|
LOG(info) << "Created unamanged region " << id << " of size " << region.GetSize()
|
||||||
|
<< ", starting at " << region.GetData() << ". Locking...";
|
||||||
region.Lock();
|
region.Lock();
|
||||||
LOG(info) << "Done.";
|
LOG(info) << "Done.";
|
||||||
|
if (zero) {
|
||||||
LOG(info) << "Zeroing...";
|
LOG(info) << "Zeroing...";
|
||||||
region.Zero();
|
region.Zero();
|
||||||
LOG(info) << "Done.";
|
LOG(info) << "Done.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckPresence()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(localMtx);
|
||||||
|
for (const auto& sc : segmentCfgs) {
|
||||||
|
if (!(fair::mq::shmem::Monitor::SegmentIsPresent(fair::mq::shmem::ShmId{shmId}, sc.id))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& rc : regionCfgs) {
|
||||||
|
if (!(fair::mq::shmem::Monitor::RegionIsPresent(fair::mq::shmem::ShmId{shmId}, rc.id.value()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ResetContent()
|
void ResetContent()
|
||||||
{
|
{
|
||||||
fair::mq::shmem::Monitor::ResetContent(fair::mq::shmem::ShmId{shmId});
|
std::lock_guard<std::mutex> lock(localMtx);
|
||||||
|
fair::mq::shmem::Monitor::ResetContent(fair::mq::shmem::ShmId{shmId}, segmentCfgs, regionCfgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FullReset()
|
||||||
|
{
|
||||||
|
segments.clear();
|
||||||
|
regions.clear();
|
||||||
|
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
|
||||||
}
|
}
|
||||||
|
|
||||||
~ShmManager()
|
~ShmManager()
|
||||||
|
@ -95,8 +149,11 @@ struct ShmManager
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string shmId;
|
std::string shmId;
|
||||||
|
std::mutex localMtx;
|
||||||
map<uint16_t, fair::mq::shmem::Segment> segments;
|
map<uint16_t, fair::mq::shmem::Segment> segments;
|
||||||
map<uint16_t, unique_ptr<fair::mq::shmem::UnmanagedRegion>> regions;
|
map<uint16_t, unique_ptr<fair::mq::shmem::UnmanagedRegion>> regions;
|
||||||
|
std::vector<fair::mq::shmem::SegmentConfig> segmentCfgs;
|
||||||
|
std::vector<fair::mq::RegionConfig> regionCfgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
@ -105,8 +162,11 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
signal(SIGINT, signalHandler);
|
signal(SIGINT, signalHandler);
|
||||||
signal(SIGTERM, signalHandler);
|
signal(SIGTERM, signalHandler);
|
||||||
|
signal(SIGUSR1, resetContentHandler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
bool nozero = false;
|
||||||
|
bool checkPresence = true;
|
||||||
uint64_t shmId = 0;
|
uint64_t shmId = 0;
|
||||||
vector<string> segments;
|
vector<string> segments;
|
||||||
vector<string> regions;
|
vector<string> regions;
|
||||||
|
@ -114,8 +174,10 @@ int main(int argc, char** argv)
|
||||||
options_description desc("Options");
|
options_description desc("Options");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("shmid", value<uint64_t>(&shmId)->required(), "Shm id")
|
("shmid", value<uint64_t>(&shmId)->required(), "Shm id")
|
||||||
("segments", value<vector<string>>(&segments)->multitoken()->composing(), "Segments, as <id>,<size> <id>,<size> <id>,<size> ...")
|
("segments", value<vector<string>>(&segments)->multitoken()->composing(), "Segments, as <id>,<size>,<numaid> <id>,<size>,<numaid> <id>,<size>,<numaid> ... (numaid: -2 disabled, -1 interleave, >=0 node)")
|
||||||
("regions", value<vector<string>>(®ions)->multitoken()->composing(), "Regions, as <id>,<size> <id>,<size> <id>,<size> ...")
|
("regions", value<vector<string>>(®ions)->multitoken()->composing(), "Regions, as <id>,<size> <id>,<size>,<numaid> <id>,<size>,<numaid> ...")
|
||||||
|
("nozero", value<bool>(&nozero)->default_value(false)->implicit_value(true), "Do not zero segments after initialization")
|
||||||
|
("check-presence", value<bool>(&checkPresence)->default_value(true)->implicit_value(true), "Check periodically if configured segments/regions are still present, and cleanup and leave if they are not")
|
||||||
("help,h", "Print help");
|
("help,h", "Print help");
|
||||||
|
|
||||||
variables_map vm;
|
variables_map vm;
|
||||||
|
@ -128,15 +190,35 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
notify(vm);
|
notify(vm);
|
||||||
|
|
||||||
ShmManager shmManager(shmId, segments, regions);
|
ShmManager shmManager(shmId, segments, regions, !nozero);
|
||||||
|
|
||||||
|
std::thread resetContentThread([&shmManager]() {
|
||||||
while (!gStopping) {
|
while (!gStopping) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
if (gResetContent == 1) {
|
||||||
|
LOG(info) << "Resetting content for shmId " << shmManager.shmId;
|
||||||
|
shmManager.ResetContent();
|
||||||
|
gResetContent = 0;
|
||||||
|
LOG(info) << "Done resetting content for shmId " << shmManager.shmId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkPresence) {
|
||||||
|
while (!gStopping) {
|
||||||
|
if (shmManager.CheckPresence() == false) {
|
||||||
|
LOG(error) << "Failed to find segments, exiting.";
|
||||||
|
gStopping = true;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetContentThread.join();
|
||||||
|
|
||||||
LOG(info) << "stopping.";
|
LOG(info) << "stopping.";
|
||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
LOG(error) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit";
|
LOG(error) << "Exception reached the top of main: " << e.what() << ", exiting";
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
80
examples/region/processor.cxx
Normal file
80
examples/region/processor.cxx
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include <fairmq/Device.h>
|
||||||
|
#include <fairmq/runDevice.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace bpo = boost::program_options;
|
||||||
|
using namespace std;
|
||||||
|
using namespace fair::mq;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Processor : Device
|
||||||
|
{
|
||||||
|
void InitTask() override
|
||||||
|
{
|
||||||
|
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||||
|
GetChannel("data1", 0).Transport()->SubscribeToRegionEvents([](RegionInfo info) {
|
||||||
|
LOG(info) << "Region event: " << info.event << ": "
|
||||||
|
<< (info.managed ? "managed" : "unmanaged") << ", id: " << info.id
|
||||||
|
<< ", ptr: " << info.ptr << ", size: " << info.size
|
||||||
|
<< ", flags: " << info.flags;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Run() override
|
||||||
|
{
|
||||||
|
Channel& dataIn = GetChannel("data1", 0);
|
||||||
|
Channel& dataOut1 = GetChannel("data2", 0);
|
||||||
|
Channel& dataOut2 = GetChannel("data3", 0);
|
||||||
|
|
||||||
|
while (!NewStatePending()) {
|
||||||
|
fair::mq::Parts inParts;
|
||||||
|
dataIn.Receive(inParts);
|
||||||
|
|
||||||
|
fair::mq::Parts outParts1;
|
||||||
|
fair::mq::Parts outParts2;
|
||||||
|
|
||||||
|
for (const auto& inPart : inParts) {
|
||||||
|
outParts1.AddPart(NewMessage());
|
||||||
|
outParts1.fParts.back()->Copy(*inPart);
|
||||||
|
|
||||||
|
outParts2.AddPart(NewMessage());
|
||||||
|
outParts2.fParts.back()->Copy(*inPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataOut1.Send(outParts1);
|
||||||
|
dataOut2.Send(outParts2);
|
||||||
|
|
||||||
|
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||||
|
LOG(info) << "Configured max number of iterations reached. Leaving RUNNING state.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetTask() override
|
||||||
|
{
|
||||||
|
GetChannel("data1", 0).Transport()->UnsubscribeFromRegionEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t fMaxIterations = 0;
|
||||||
|
uint64_t fNumIterations = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void addCustomOptions(bpo::options_description& options)
|
||||||
|
{
|
||||||
|
options.add_options()("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<Device> getDevice(ProgOptions& /*config*/) { return make_unique<Processor>(); }
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/runDevice.h>
|
#include <fairmq/runDevice.h>
|
||||||
|
#include <fairmq/tools/RateLimit.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -19,11 +20,15 @@ struct Sampler : fair::mq::Device
|
||||||
{
|
{
|
||||||
void InitTask() override
|
void InitTask() override
|
||||||
{
|
{
|
||||||
|
fExternalRegion = fConfig->GetProperty<bool>("external-region");
|
||||||
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
fMsgSize = fConfig->GetProperty<int>("msg-size");
|
||||||
fLinger = fConfig->GetProperty<uint32_t>("region-linger");
|
fLinger = fConfig->GetProperty<uint32_t>("region-linger");
|
||||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||||
|
fChanName = fConfig->GetProperty<std::string>("chan-name");
|
||||||
|
fSamplingRate = fConfig->GetProperty<float>("sampling-rate");
|
||||||
|
fRCSegmentSize = fConfig->GetProperty<uint64_t>("rc-segment-size");
|
||||||
|
|
||||||
GetChannel("data", 0).Transport()->SubscribeToRegionEvents([](fair::mq::RegionInfo info) {
|
GetChannel(fChanName, 0).Transport()->SubscribeToRegionEvents([](fair::mq::RegionInfo info) {
|
||||||
LOG(info) << "Region event: " << info.event << ": "
|
LOG(info) << "Region event: " << info.event << ": "
|
||||||
<< (info.managed ? "managed" : "unmanaged")
|
<< (info.managed ? "managed" : "unmanaged")
|
||||||
<< ", id: " << info.id
|
<< ", id: " << info.id
|
||||||
|
@ -34,9 +39,16 @@ struct Sampler : fair::mq::Device
|
||||||
|
|
||||||
fair::mq::RegionConfig regionCfg;
|
fair::mq::RegionConfig regionCfg;
|
||||||
regionCfg.linger = fLinger; // delay in ms before region destruction to collect outstanding events
|
regionCfg.linger = fLinger; // delay in ms before region destruction to collect outstanding events
|
||||||
regionCfg.lock = true; // mlock region after creation
|
// options for testing with an externally-created -region
|
||||||
regionCfg.zero = true; // zero region content after creation
|
if (fExternalRegion) {
|
||||||
fRegion = fair::mq::UnmanagedRegionPtr(NewUnmanagedRegionFor("data", // region is created using the transport of this channel...
|
regionCfg.id = 1;
|
||||||
|
regionCfg.removeOnDestruction = false;
|
||||||
|
}
|
||||||
|
regionCfg.lock = !fExternalRegion; // mlock region after creation
|
||||||
|
regionCfg.zero = !fExternalRegion; // zero region content after creation
|
||||||
|
regionCfg.rcSegmentSize = fRCSegmentSize; // size of the corresponding reference count segment
|
||||||
|
fRegion = fair::mq::UnmanagedRegionPtr(NewUnmanagedRegionFor(
|
||||||
|
fChanName, // region is created using the transport of this channel...
|
||||||
0, // ... and this sub-channel
|
0, // ... and this sub-channel
|
||||||
10000000, // region size
|
10000000, // region size
|
||||||
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
|
[this](const std::vector<fair::mq::RegionBlock>& blocks) { // callback to be called when message buffers no longer needed by transport
|
||||||
|
@ -45,65 +57,91 @@ struct Sampler : fair::mq::Device
|
||||||
if (fMaxIterations > 0) {
|
if (fMaxIterations > 0) {
|
||||||
LOG(info) << "Received " << blocks.size() << " acks";
|
LOG(info) << "Received " << blocks.size() << " acks";
|
||||||
}
|
}
|
||||||
}, regionCfg));
|
},
|
||||||
|
regionCfg
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConditionalRun() override
|
void Run() override
|
||||||
{
|
{
|
||||||
fair::mq::MessagePtr msg(NewMessageFor("data", // channel
|
|
||||||
|
fair::mq::tools::RateLimiter rateLimiter(fSamplingRate);
|
||||||
|
|
||||||
|
while (!NewStatePending()) {
|
||||||
|
fair::mq::Parts parts;
|
||||||
|
// make 64 parts
|
||||||
|
for (int i = 0; i < 64; ++i) {
|
||||||
|
parts.AddPart(NewMessageFor(
|
||||||
|
fChanName, // channel
|
||||||
0, // sub-channel
|
0, // sub-channel
|
||||||
fRegion, // region
|
fRegion, // region
|
||||||
fRegion->GetData(), // ptr within region
|
fRegion->GetData(), // ptr within region
|
||||||
fMsgSize, // offset from ptr
|
fMsgSize, // offset from ptr
|
||||||
nullptr // hint
|
nullptr // hint
|
||||||
));
|
));
|
||||||
|
}
|
||||||
// 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));
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(fMtx);
|
std::lock_guard<std::mutex> lock(fMtx);
|
||||||
++fNumUnackedMsgs;
|
fNumUnackedMsgs += parts.Size();
|
||||||
if (Send(msg, "data", 0) > 0) {
|
if (Send(parts, fChanName, 0) > 0) {
|
||||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||||
LOG(info) << "Configured maximum number of iterations reached. Leaving RUNNING state.";
|
LOG(info) << "Configured maximum number of iterations reached. Stopping sending.";
|
||||||
return false;
|
break;
|
||||||
|
}
|
||||||
|
if (fSamplingRate > 0.001) {
|
||||||
|
rateLimiter.maybe_sleep();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// wait for all acks to arrive
|
||||||
}
|
while (!NewStatePending()) {
|
||||||
|
|
||||||
void ResetTask() override
|
|
||||||
{
|
|
||||||
fRegion.reset();
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(fMtx);
|
std::lock_guard<std::mutex> lock(fMtx);
|
||||||
|
if (fNumUnackedMsgs == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
||||||
|
}
|
||||||
|
|
||||||
if (fNumUnackedMsgs != 0) {
|
if (fNumUnackedMsgs != 0) {
|
||||||
LOG(info) << "Done, still not acknowledged: " << fNumUnackedMsgs;
|
LOG(info) << "Done, still not acknowledged: " << fNumUnackedMsgs;
|
||||||
} else {
|
} else {
|
||||||
LOG(info) << "All acknowledgements received.";
|
LOG(info) << "All acknowledgements received.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GetChannel("data", 0).Transport()->UnsubscribeFromRegionEvents();
|
|
||||||
|
void ResetTask() override
|
||||||
|
{
|
||||||
|
fRegion.reset();
|
||||||
|
GetChannel(fChanName, 0).Transport()->UnsubscribeFromRegionEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int fExternalRegion = false;
|
||||||
int fMsgSize = 10000;
|
int fMsgSize = 10000;
|
||||||
uint32_t fLinger = 100;
|
uint32_t fLinger = 100;
|
||||||
uint64_t fMaxIterations = 0;
|
uint64_t fMaxIterations = 0;
|
||||||
uint64_t fNumIterations = 0;
|
uint64_t fNumIterations = 0;
|
||||||
|
uint64_t fRCSegmentSize = 10000000;
|
||||||
fair::mq::UnmanagedRegionPtr fRegion = nullptr;
|
fair::mq::UnmanagedRegionPtr fRegion = nullptr;
|
||||||
std::mutex fMtx;
|
std::mutex fMtx;
|
||||||
uint64_t fNumUnackedMsgs = 0;
|
uint64_t fNumUnackedMsgs = 0;
|
||||||
|
std::string fChanName;
|
||||||
|
float fSamplingRate = 0.;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addCustomOptions(bpo::options_description& options)
|
void addCustomOptions(bpo::options_description& options)
|
||||||
{
|
{
|
||||||
options.add_options()
|
options.add_options()
|
||||||
|
("chan-name", bpo::value<std::string>()->default_value("data"), "name of the output channel")
|
||||||
("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
|
("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
|
||||||
|
("sampling-rate", bpo::value<float>()->default_value(0.), "Sampling rate (Hz).")
|
||||||
("region-linger", bpo::value<uint32_t>()->default_value(100), "Linger period for regions")
|
("region-linger", bpo::value<uint32_t>()->default_value(100), "Linger period for regions")
|
||||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)")
|
||||||
|
("external-region", bpo::value<bool>()->default_value(false), "Use region created by another process")
|
||||||
|
("rc-segment-size", bpo::value<uint64_t>()->default_value(10000000), "Size of the reference count segment for Unamanged Region");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
|
std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /*config*/)
|
||||||
|
|
|
@ -22,7 +22,8 @@ struct Sink : Device
|
||||||
{
|
{
|
||||||
// Get the fMaxIterations value from the command line options (via fConfig)
|
// Get the fMaxIterations value from the command line options (via fConfig)
|
||||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||||
GetChannel("data", 0).Transport()->SubscribeToRegionEvents([](RegionInfo info) {
|
fChanName = fConfig->GetProperty<std::string>("chan-name");
|
||||||
|
GetChannel(fChanName, 0).Transport()->SubscribeToRegionEvents([](RegionInfo info) {
|
||||||
LOG(info) << "Region event: " << info.event << ": "
|
LOG(info) << "Region event: " << info.event << ": "
|
||||||
<< (info.managed ? "managed" : "unmanaged") << ", id: " << info.id
|
<< (info.managed ? "managed" : "unmanaged") << ", id: " << info.id
|
||||||
<< ", ptr: " << info.ptr << ", size: " << info.size
|
<< ", ptr: " << info.ptr << ", size: " << info.size
|
||||||
|
@ -32,15 +33,11 @@ struct Sink : Device
|
||||||
|
|
||||||
void Run() override
|
void Run() override
|
||||||
{
|
{
|
||||||
Channel& dataInChannel = GetChannel("data", 0);
|
Channel& dataIn = GetChannel(fChanName, 0);
|
||||||
|
|
||||||
while (!NewStatePending()) {
|
while (!NewStatePending()) {
|
||||||
auto msg(dataInChannel.Transport()->CreateMessage());
|
fair::mq::Parts parts;
|
||||||
dataInChannel.Receive(msg);
|
dataIn.Receive(parts);
|
||||||
|
|
||||||
// void* ptr = msg->GetData();
|
|
||||||
// char* cptr = static_cast<char*>(ptr);
|
|
||||||
// LOG(info) << "check: " << cptr[3];
|
|
||||||
|
|
||||||
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
if (fMaxIterations > 0 && ++fNumIterations >= fMaxIterations) {
|
||||||
LOG(info) << "Configured max number of iterations reached. Leaving RUNNING state.";
|
LOG(info) << "Configured max number of iterations reached. Leaving RUNNING state.";
|
||||||
|
@ -51,22 +48,22 @@ struct Sink : Device
|
||||||
|
|
||||||
void ResetTask() override
|
void ResetTask() override
|
||||||
{
|
{
|
||||||
GetChannel("data", 0).Transport()->UnsubscribeFromRegionEvents();
|
GetChannel(fChanName, 0).Transport()->UnsubscribeFromRegionEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t fMaxIterations = 0;
|
uint64_t fMaxIterations = 0;
|
||||||
uint64_t fNumIterations = 0;
|
uint64_t fNumIterations = 0;
|
||||||
|
std::string fChanName;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void addCustomOptions(bpo::options_description& options)
|
void addCustomOptions(bpo::options_description& options)
|
||||||
{
|
{
|
||||||
options.add_options()(
|
options.add_options()
|
||||||
"max-iterations",
|
("chan-name", bpo::value<std::string>()->default_value("data"), "name of the input channel")
|
||||||
bpo::value<uint64_t>()->default_value(0),
|
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
||||||
"Maximum number of iterations of Run/ConditionalRun/OnData (0 - infinite)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Device> getDevice(ProgOptions& /*config*/) { return make_unique<Sink>(); }
|
unique_ptr<Device> getDevice(ProgOptions& /*config*/) { return make_unique<Sink>(); }
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -14,7 +16,7 @@ chan="data"
|
||||||
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; @CMAKE_BINARY_DIR@/fairmq/fairmq-shmmonitor --cleanup --session $SESSION; rm $chanAddr' TERM
|
trap 'set +e; kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; @CMAKE_BINARY_DIR@/fairmq/fairmq-shmmonitor --cleanup --session $SESSION; rm $chanAddr; exit 0' TERM
|
||||||
|
|
||||||
SAMPLER="fairmq-ex-region-sampler"
|
SAMPLER="fairmq-ex-region-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
|
@ -22,6 +24,7 @@ SAMPLER+=" --transport $transport"
|
||||||
SAMPLER+=" --severity debug"
|
SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --session $session"
|
SAMPLER+=" --session $session"
|
||||||
SAMPLER+=" --shm-segment-size 100000000"
|
SAMPLER+=" --shm-segment-size 100000000"
|
||||||
|
SAMPLER+=" --shm-monitor true"
|
||||||
SAMPLER+=" --verbosity veryhigh"
|
SAMPLER+=" --verbosity veryhigh"
|
||||||
SAMPLER+=" --control static --color false"
|
SAMPLER+=" --control static --color false"
|
||||||
SAMPLER+=" --max-iterations 1"
|
SAMPLER+=" --max-iterations 1"
|
||||||
|
@ -37,6 +40,7 @@ SINK+=" --transport $transport"
|
||||||
SINK+=" --severity debug"
|
SINK+=" --severity debug"
|
||||||
SINK+=" --session $session"
|
SINK+=" --session $session"
|
||||||
SINK+=" --shm-segment-size 100000000"
|
SINK+=" --shm-segment-size 100000000"
|
||||||
|
SINK+=" --shm-monitor true"
|
||||||
SINK+=" --verbosity veryhigh"
|
SINK+=" --verbosity veryhigh"
|
||||||
SINK+=" --control static --color false"
|
SINK+=" --control static --color false"
|
||||||
SINK+=" --max-iterations 1"
|
SINK+=" --max-iterations 1"
|
||||||
|
@ -48,4 +52,6 @@ SINK_PID=$!
|
||||||
wait $SAMPLER_PID
|
wait $SAMPLER_PID
|
||||||
wait $SINK_PID
|
wait $SINK_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chanAddr
|
rm $chanAddr
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,52 +1,11 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
add_executable(fairmq-ex-req-rep-client client.cxx)
|
add_example(NAME req-rep
|
||||||
target_link_libraries(fairmq-ex-req-rep-client PRIVATE FairMQ)
|
DEVICE client server
|
||||||
|
|
||||||
|
|
||||||
add_executable(fairmq-ex-req-rep-server server.cxx)
|
|
||||||
target_link_libraries(fairmq-ex-req-rep-server PRIVATE FairMQ)
|
|
||||||
|
|
||||||
add_custom_target(ExampleReqRep DEPENDS fairmq-ex-req-rep-client fairmq-ex-req-rep-server)
|
|
||||||
|
|
||||||
set(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh)
|
|
||||||
|
|
||||||
# test
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh)
|
|
||||||
|
|
||||||
add_test(NAME Example.ReqRep.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh zeromq)
|
|
||||||
set_tests_properties(Example.ReqRep.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
|
||||||
|
|
||||||
add_test(NAME Example.ReqRep.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh shmem)
|
|
||||||
set_tests_properties(Example.ReqRep.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
|
||||||
|
|
||||||
# install
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS
|
|
||||||
fairmq-ex-req-rep-client
|
|
||||||
fairmq-ex-req-rep-server
|
|
||||||
|
|
||||||
LIBRARY DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# configure run script with different executable paths for build and for install directories
|
|
||||||
set(EX_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR})
|
|
||||||
set(FAIRMQ_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_BINDIR}/fairmq)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install)
|
|
||||||
|
|
||||||
install(
|
|
||||||
PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fairmq-start-ex-req-rep.sh_install
|
|
||||||
DESTINATION ${PROJECT_INSTALL_BINDIR}
|
|
||||||
RENAME fairmq-start-ex-req-rep.sh
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||||
|
|
||||||
transport="zeromq"
|
transport="zeromq"
|
||||||
|
@ -13,7 +15,7 @@ chan="data"
|
||||||
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
chanAddr="/tmp/fmq_$session""_""$chan""_""$transport"
|
||||||
|
|
||||||
# setup a trap to kill everything if the test fails/timeouts
|
# setup a trap to kill everything if the test fails/timeouts
|
||||||
trap 'kill -TERM $CLIENT_PID; kill -TERM $SERVER_PID; wait $CLIENT_PID; wait $SERVER_PID; rm $chanAddr' TERM
|
trap 'set +e; kill -TERM $CLIENT_PID; kill -TERM $SERVER_PID; wait $CLIENT_PID; wait $SERVER_PID; rm $chanAddr; exit 0' TERM
|
||||||
|
|
||||||
CLIENT="fairmq-ex-req-rep-client"
|
CLIENT="fairmq-ex-req-rep-client"
|
||||||
CLIENT+=" --id client"
|
CLIENT+=" --id client"
|
||||||
|
@ -21,6 +23,7 @@ CLIENT+=" --transport $transport"
|
||||||
CLIENT+=" --verbosity veryhigh"
|
CLIENT+=" --verbosity veryhigh"
|
||||||
CLIENT+=" --session $session"
|
CLIENT+=" --session $session"
|
||||||
CLIENT+=" --shm-segment-size 100000000"
|
CLIENT+=" --shm-segment-size 100000000"
|
||||||
|
CLIENT+=" --shm-monitor true"
|
||||||
CLIENT+=" --control static --color false"
|
CLIENT+=" --control static --color false"
|
||||||
CLIENT+=" --max-iterations 1"
|
CLIENT+=" --max-iterations 1"
|
||||||
CLIENT+=" --channel-config name=$chan,type=req,method=connect,rateLogging=0,address=ipc://$chanAddr"
|
CLIENT+=" --channel-config name=$chan,type=req,method=connect,rateLogging=0,address=ipc://$chanAddr"
|
||||||
|
@ -33,6 +36,7 @@ SERVER+=" --transport $transport"
|
||||||
SERVER+=" --verbosity veryhigh"
|
SERVER+=" --verbosity veryhigh"
|
||||||
SERVER+=" --session $session"
|
SERVER+=" --session $session"
|
||||||
SERVER+=" --shm-segment-size 100000000"
|
SERVER+=" --shm-segment-size 100000000"
|
||||||
|
SERVER+=" --shm-monitor true"
|
||||||
SERVER+=" --control static --color false"
|
SERVER+=" --control static --color false"
|
||||||
SERVER+=" --max-iterations 1"
|
SERVER+=" --max-iterations 1"
|
||||||
SERVER+=" --channel-config name=$chan,type=rep,method=bind,rateLogging=0,address=ipc://$chanAddr"
|
SERVER+=" --channel-config name=$chan,type=rep,method=bind,rateLogging=0,address=ipc://$chanAddr"
|
||||||
|
@ -43,4 +47,6 @@ SERVER_PID=$!
|
||||||
wait $CLIENT_PID
|
wait $CLIENT_PID
|
||||||
wait $SERVER_PID
|
wait $SERVER_PID
|
||||||
|
|
||||||
|
set +e
|
||||||
rm $chanAddr
|
rm $chanAddr
|
||||||
|
exit 0
|
||||||
|
|
2
extern/googletest
vendored
2
extern/googletest
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit f5e592d8ee5ffb1d9af5be7f715ce3576b8bf9c4
|
Subproject commit 7d76a231b0e29caf86e68d1df858308cd53b2a66
|
|
@ -1,12 +1,12 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
# Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
# Copyright (C) 2012-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||||
# #
|
# #
|
||||||
# This software is distributed under the terms of the #
|
# This software is distributed under the terms of the #
|
||||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||||
# copied verbatim in the file "LICENSE" #
|
# copied verbatim in the file "LICENSE" #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
if(BUILD_FAIRMQ)
|
||||||
|
|
||||||
if(BUILD_TIDY_TOOL)
|
if(BUILD_TIDY_TOOL)
|
||||||
include(FairMQTidy)
|
include(FairMQTidy)
|
||||||
|
@ -23,135 +23,6 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||||
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
#########
|
|
||||||
# Tools #
|
|
||||||
#########
|
|
||||||
set(target Tools)
|
|
||||||
|
|
||||||
set(TOOLS_PUBLIC_HEADER_FILES
|
|
||||||
tools/CppSTL.h
|
|
||||||
tools/Exceptions.h
|
|
||||||
tools/InstanceLimit.h
|
|
||||||
tools/IO.h
|
|
||||||
tools/Network.h
|
|
||||||
tools/Process.h
|
|
||||||
tools/RateLimit.h
|
|
||||||
tools/Semaphore.h
|
|
||||||
tools/Strings.h
|
|
||||||
tools/Unique.h
|
|
||||||
tools/Version.h
|
|
||||||
Error.h
|
|
||||||
Tools.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(TOOLS_SOURCE_FILES
|
|
||||||
Error.cxx
|
|
||||||
tools/Network.cxx
|
|
||||||
tools/Process.cxx
|
|
||||||
tools/Semaphore.cxx
|
|
||||||
tools/Unique.cxx
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(${target}
|
|
||||||
${TOOLS_SOURCE_FILES}
|
|
||||||
${TOOLS_PUBLIC_HEADER_FILES}
|
|
||||||
)
|
|
||||||
target_compile_features(${target} PUBLIC cxx_std_17)
|
|
||||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
|
||||||
target_include_directories(${target}
|
|
||||||
PUBLIC
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
||||||
)
|
|
||||||
target_link_libraries(${target}
|
|
||||||
PRIVATE
|
|
||||||
FairLogger::FairLogger
|
|
||||||
Threads::Threads
|
|
||||||
Boost::boost
|
|
||||||
)
|
|
||||||
set_target_properties(${target} PROPERTIES
|
|
||||||
VERSION ${PROJECT_VERSION}
|
|
||||||
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
|
|
||||||
OUTPUT_NAME FairMQ${target}
|
|
||||||
)
|
|
||||||
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
|
||||||
fairmq_target_tidy(TARGET ${target})
|
|
||||||
endif()
|
|
||||||
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_features(${target} PUBLIC cxx_std_17)
|
|
||||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
|
||||||
target_include_directories(${target}
|
|
||||||
PUBLIC
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
||||||
)
|
|
||||||
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}
|
|
||||||
)
|
|
||||||
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
|
||||||
fairmq_target_tidy(TARGET ${target})
|
|
||||||
endif()
|
|
||||||
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 #
|
# libFairMQ header files #
|
||||||
##########################
|
##########################
|
||||||
|
@ -159,6 +30,7 @@ if(BUILD_FAIRMQ)
|
||||||
Channel.h
|
Channel.h
|
||||||
Device.h
|
Device.h
|
||||||
DeviceRunner.h
|
DeviceRunner.h
|
||||||
|
Error.h
|
||||||
EventManager.h
|
EventManager.h
|
||||||
FairMQChannel.h
|
FairMQChannel.h
|
||||||
FairMQDevice.h
|
FairMQDevice.h
|
||||||
|
@ -184,17 +56,40 @@ if(BUILD_FAIRMQ)
|
||||||
Properties.h
|
Properties.h
|
||||||
PropertyOutput.h
|
PropertyOutput.h
|
||||||
Socket.h
|
Socket.h
|
||||||
|
StateMachine.h
|
||||||
|
States.h
|
||||||
|
StateQueue.h
|
||||||
SuboptParser.h
|
SuboptParser.h
|
||||||
|
Tools.h
|
||||||
TransportFactory.h
|
TransportFactory.h
|
||||||
Transports.h
|
Transports.h
|
||||||
|
TransportEnum.h
|
||||||
UnmanagedRegion.h
|
UnmanagedRegion.h
|
||||||
options/FairMQProgOptions.h
|
options/FairMQProgOptions.h
|
||||||
runDevice.h
|
runDevice.h
|
||||||
runFairMQDevice.h
|
runFairMQDevice.h
|
||||||
shmem/Monitor.h
|
|
||||||
shmem/Common.h
|
shmem/Common.h
|
||||||
shmem/UnmanagedRegion.h
|
shmem/Manager.h
|
||||||
|
shmem/Message.h
|
||||||
|
shmem/Monitor.h
|
||||||
|
shmem/Poller.h
|
||||||
shmem/Segment.h
|
shmem/Segment.h
|
||||||
|
shmem/Socket.h
|
||||||
|
shmem/TransportFactory.h
|
||||||
|
shmem/UnmanagedRegion.h
|
||||||
|
shmem/UnmanagedRegionImpl.h
|
||||||
|
tools/Compiler.h
|
||||||
|
tools/CppSTL.h
|
||||||
|
tools/Exceptions.h
|
||||||
|
tools/IO.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
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FAIRMQ_PRIVATE_HEADER_FILES
|
set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||||
|
@ -207,12 +102,6 @@ if(BUILD_FAIRMQ)
|
||||||
plugins/Builtin.h
|
plugins/Builtin.h
|
||||||
plugins/config/Config.h
|
plugins/config/Config.h
|
||||||
plugins/control/Control.h
|
plugins/control/Control.h
|
||||||
shmem/Message.h
|
|
||||||
shmem/Poller.h
|
|
||||||
shmem/UnmanagedRegionImpl.h
|
|
||||||
shmem/Socket.h
|
|
||||||
shmem/TransportFactory.h
|
|
||||||
shmem/Manager.h
|
|
||||||
zeromq/Common.h
|
zeromq/Common.h
|
||||||
zeromq/Context.h
|
zeromq/Context.h
|
||||||
zeromq/Message.h
|
zeromq/Message.h
|
||||||
|
@ -220,18 +109,9 @@ if(BUILD_FAIRMQ)
|
||||||
zeromq/UnmanagedRegion.h
|
zeromq/UnmanagedRegion.h
|
||||||
zeromq/Socket.h
|
zeromq/Socket.h
|
||||||
zeromq/TransportFactory.h
|
zeromq/TransportFactory.h
|
||||||
|
zeromq/ZMsg.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(BUILD_OFI_TRANSPORT)
|
|
||||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
|
||||||
ofi/Context.h
|
|
||||||
ofi/ControlMessages.h
|
|
||||||
ofi/Message.h
|
|
||||||
ofi/Socket.h
|
|
||||||
ofi/TransportFactory.h
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# libFairMQ source files #
|
# libFairMQ source files #
|
||||||
##########################
|
##########################
|
||||||
|
@ -239,6 +119,7 @@ if(BUILD_FAIRMQ)
|
||||||
Channel.cxx
|
Channel.cxx
|
||||||
Device.cxx
|
Device.cxx
|
||||||
DeviceRunner.cxx
|
DeviceRunner.cxx
|
||||||
|
EventManager.cxx
|
||||||
JSONParser.cxx
|
JSONParser.cxx
|
||||||
MemoryResources.cxx
|
MemoryResources.cxx
|
||||||
Plugin.cxx
|
Plugin.cxx
|
||||||
|
@ -246,6 +127,8 @@ if(BUILD_FAIRMQ)
|
||||||
PluginServices.cxx
|
PluginServices.cxx
|
||||||
ProgOptions.cxx
|
ProgOptions.cxx
|
||||||
Properties.cxx
|
Properties.cxx
|
||||||
|
StateMachine.cxx
|
||||||
|
States.cxx
|
||||||
SuboptParser.cxx
|
SuboptParser.cxx
|
||||||
TransportFactory.cxx
|
TransportFactory.cxx
|
||||||
plugins/config/Config.cxx
|
plugins/config/Config.cxx
|
||||||
|
@ -253,16 +136,12 @@ if(BUILD_FAIRMQ)
|
||||||
shmem/Common.cxx
|
shmem/Common.cxx
|
||||||
shmem/Manager.cxx
|
shmem/Manager.cxx
|
||||||
shmem/Monitor.cxx
|
shmem/Monitor.cxx
|
||||||
|
tools/Network.cxx
|
||||||
|
tools/Process.cxx
|
||||||
|
tools/Semaphore.cxx
|
||||||
|
tools/Unique.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
if(BUILD_OFI_TRANSPORT)
|
|
||||||
set(FAIRMQ_SOURCE_FILES ${FAIRMQ_SOURCE_FILES}
|
|
||||||
ofi/Context.cxx
|
|
||||||
ofi/Message.cxx
|
|
||||||
ofi/Socket.cxx
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# configure files #
|
# configure files #
|
||||||
|
@ -286,14 +165,26 @@ if(BUILD_FAIRMQ)
|
||||||
############################
|
############################
|
||||||
# preprocessor definitions #
|
# preprocessor definitions #
|
||||||
############################
|
############################
|
||||||
target_compile_definitions(${target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
|
target_compile_definitions(${target} PUBLIC
|
||||||
|
BOOST_ERROR_CODE_HEADER_ONLY
|
||||||
|
BOOST_ASIO_HAS_HAS_STD_CHRONO
|
||||||
|
)
|
||||||
if(FAIRMQ_DEBUG_MODE)
|
if(FAIRMQ_DEBUG_MODE)
|
||||||
target_compile_definitions(${target} PUBLIC FAIRMQ_DEBUG_MODE)
|
target_compile_definitions(${target} PUBLIC FAIRMQ_DEBUG_MODE)
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_OFI_TRANSPORT)
|
target_compile_definitions(${target} PUBLIC
|
||||||
target_compile_definitions(${target} PRIVATE BUILD_OFI_TRANSPORT)
|
FAIRMQ_HAS_STD_FILESYSTEM=${FAIRMQ_HAS_STD_FILESYSTEM}
|
||||||
|
FAIRMQ_HAS_STD_PMR=${FAIRMQ_HAS_STD_PMR}
|
||||||
|
)
|
||||||
|
if(DEFINED FAIRMQ_CHANNEL_DEFAULT_AUTOBIND)
|
||||||
|
# translate CMake boolean (TRUE, FALSE, 0, 1, OFF, ON) into C++ boolean literal (true, false)
|
||||||
|
if(FAIRMQ_CHANNEL_DEFAULT_AUTOBIND)
|
||||||
|
set(value "true")
|
||||||
|
else()
|
||||||
|
set(value "false")
|
||||||
|
endif()
|
||||||
|
target_compile_definitions(${target} PUBLIC FAIRMQ_CHANNEL_DEFAULT_AUTOBIND=${value})
|
||||||
endif()
|
endif()
|
||||||
target_compile_definitions(${target} PUBLIC FAIRMQ_HAS_STD_FILESYSTEM=${FAIRMQ_HAS_STD_FILESYSTEM})
|
|
||||||
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
|
@ -311,13 +202,6 @@ if(BUILD_FAIRMQ)
|
||||||
##################
|
##################
|
||||||
# link libraries #
|
# link libraries #
|
||||||
##################
|
##################
|
||||||
if(BUILD_OFI_TRANSPORT)
|
|
||||||
set(OFI_DEPS
|
|
||||||
asio::asio
|
|
||||||
asiofi::asiofi
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(${target}
|
target_link_libraries(${target}
|
||||||
INTERFACE # only consumers link against interface dependencies
|
INTERFACE # only consumers link against interface dependencies
|
||||||
Boost::container
|
Boost::container
|
||||||
|
@ -328,20 +212,17 @@ if(BUILD_FAIRMQ)
|
||||||
$<$<PLATFORM_ID:Linux>:rt>
|
$<$<PLATFORM_ID:Linux>:rt>
|
||||||
Boost::boost
|
Boost::boost
|
||||||
Boost::program_options
|
Boost::program_options
|
||||||
Boost::filesystem
|
Boost::filesystem # still needed for Boost.DLL
|
||||||
Boost::regex
|
Boost::regex
|
||||||
FairLogger::FairLogger
|
FairLogger::FairLogger
|
||||||
Tools
|
|
||||||
StateMachine
|
|
||||||
|
|
||||||
PRIVATE # only libFairMQ links against private dependencies
|
PRIVATE # only libFairMQ links against private dependencies
|
||||||
libzmq
|
libzmq
|
||||||
PicoSHA2
|
PicoSHA2
|
||||||
${OFI_DEPS}
|
|
||||||
)
|
)
|
||||||
set_target_properties(${target} PROPERTIES
|
set_target_properties(${target} PROPERTIES
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
|
OUTPUT_NAME ${PROJECT_NAME_LOWER}
|
||||||
)
|
)
|
||||||
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
||||||
fairmq_target_tidy(TARGET ${target})
|
fairmq_target_tidy(TARGET ${target})
|
||||||
|
@ -414,7 +295,7 @@ if(BUILD_FAIRMQ)
|
||||||
add_executable(fairmq-uuid-gen tools/runUuidGenerator.cxx)
|
add_executable(fairmq-uuid-gen tools/runUuidGenerator.cxx)
|
||||||
target_link_libraries(fairmq-uuid-gen PUBLIC
|
target_link_libraries(fairmq-uuid-gen PUBLIC
|
||||||
Boost::program_options
|
Boost::program_options
|
||||||
Tools
|
FairMQ
|
||||||
)
|
)
|
||||||
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
if(BUILD_TIDY_TOOL AND RUN_FAIRMQ_TIDY)
|
||||||
fairmq_target_tidy(TARGET fairmq-uuid-gen)
|
fairmq_target_tidy(TARGET fairmq-uuid-gen)
|
||||||
|
@ -451,21 +332,3 @@ if(BUILD_FAIRMQ)
|
||||||
)
|
)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_SDK_COMMANDS)
|
|
||||||
add_subdirectory(sdk/commands)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_SDK)
|
|
||||||
add_subdirectory(sdk)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
####################
|
|
||||||
# external plugins #
|
|
||||||
####################
|
|
||||||
if(BUILD_DDS_PLUGIN)
|
|
||||||
add_subdirectory(plugins/DDS)
|
|
||||||
endif()
|
|
||||||
if(BUILD_PMIX_PLUGIN)
|
|
||||||
add_subdirectory(plugins/PMIx)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <fairmq/Channel.h>
|
#include <fairmq/Channel.h>
|
||||||
#include <fairmq/Properties.h>
|
#include <fairmq/Properties.h>
|
||||||
#include <fairmq/Tools.h>
|
#include <fairmq/Tools.h>
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -383,4 +384,10 @@ bool Channel::BindEndpoint(string& endpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Channel::GetTransportName() const { return TransportName(fTransportType); }
|
||||||
|
|
||||||
|
Transport Channel::GetTransportType() const { return fTransportType; }
|
||||||
|
|
||||||
|
void Channel::UpdateTransport(const std::string& transport) { fTransportType = TransportType(transport); Invalidate(); }
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2021-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -14,11 +14,12 @@
|
||||||
#include <fairmq/Properties.h>
|
#include <fairmq/Properties.h>
|
||||||
#include <fairmq/Socket.h>
|
#include <fairmq/Socket.h>
|
||||||
#include <fairmq/TransportFactory.h>
|
#include <fairmq/TransportFactory.h>
|
||||||
#include <fairmq/Transports.h>
|
#include <fairmq/TransportEnum.h>
|
||||||
#include <fairmq/UnmanagedRegion.h>
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
|
||||||
#include <cstdint> // int64_t
|
#include <cstdint> // int64_t
|
||||||
#include <memory> // unique_ptr, shared_ptr
|
#include <memory> // unique_ptr, shared_ptr
|
||||||
|
#include <ostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility> // std::move
|
#include <utility> // std::move
|
||||||
|
@ -144,11 +145,11 @@ class Channel
|
||||||
|
|
||||||
/// Get channel transport name ("default", "zeromq" or "shmem")
|
/// Get channel transport name ("default", "zeromq" or "shmem")
|
||||||
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
|
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
|
||||||
std::string GetTransportName() const { return TransportName(fTransportType); }
|
std::string GetTransportName() const;
|
||||||
|
|
||||||
/// Get channel transport type
|
/// Get channel transport type
|
||||||
/// @return Returns channel transport type
|
/// @return Returns channel transport type
|
||||||
mq::Transport GetTransportType() const { return fTransportType; }
|
mq::Transport GetTransportType() const;
|
||||||
|
|
||||||
/// Get socket send buffer size (in number of messages)
|
/// Get socket send buffer size (in number of messages)
|
||||||
/// @return Returns socket send buffer size (in number of messages)
|
/// @return Returns socket send buffer size (in number of messages)
|
||||||
|
@ -220,7 +221,7 @@ class Channel
|
||||||
|
|
||||||
/// Set channel transport
|
/// Set channel transport
|
||||||
/// @param transport transport string ("default", "zeromq" or "shmem")
|
/// @param transport transport string ("default", "zeromq" or "shmem")
|
||||||
void UpdateTransport(const std::string& transport) { fTransportType = TransportType(transport); Invalidate(); }
|
void UpdateTransport(const std::string& transport);
|
||||||
|
|
||||||
/// Set socket send buffer size
|
/// Set socket send buffer size
|
||||||
/// @param sndBufSize Socket send buffer size (in number of messages)
|
/// @param sndBufSize Socket send buffer size (in number of messages)
|
||||||
|
@ -378,7 +379,19 @@ class Channel
|
||||||
static constexpr int DefaultRateLogging = 1;
|
static constexpr int DefaultRateLogging = 1;
|
||||||
static constexpr int DefaultPortRangeMin = 22000;
|
static constexpr int DefaultPortRangeMin = 22000;
|
||||||
static constexpr int DefaultPortRangeMax = 23000;
|
static constexpr int DefaultPortRangeMax = 23000;
|
||||||
|
#ifdef FAIRMQ_CHANNEL_DEFAULT_AUTOBIND
|
||||||
|
static constexpr bool DefaultAutoBind = FAIRMQ_CHANNEL_DEFAULT_AUTOBIND;
|
||||||
|
#else
|
||||||
static constexpr bool DefaultAutoBind = true;
|
static constexpr bool DefaultAutoBind = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Channel& ch)
|
||||||
|
{
|
||||||
|
return os << "name: " << ch.fName
|
||||||
|
<< ", type: " << ch.fType
|
||||||
|
<< ", method: " << ch.fMethod
|
||||||
|
<< ", address: " << ch.fAddress;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<TransportFactory> fTransportFactory;
|
std::shared_ptr<TransportFactory> fTransportFactory;
|
||||||
|
@ -416,16 +429,16 @@ class Channel
|
||||||
msg.get()
|
msg.get()
|
||||||
));
|
));
|
||||||
msg.release();
|
msg.release();
|
||||||
msg = move(msgWrapper);
|
msg = std::move(msgWrapper);
|
||||||
} else {
|
} else {
|
||||||
MessagePtr newMsg(NewMessage());
|
MessagePtr newMsg(NewMessage());
|
||||||
msg = move(newMsg);
|
msg = std::move(newMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckSendCompatibility(Parts& parts) { CheckSendCompatibility(parts.fParts); }
|
void CheckSendCompatibility(Parts& parts) { CheckSendCompatibility(parts.fParts); }
|
||||||
void CheckSendCompatibility(std::vector<MessagePtr>& msgVec)
|
void CheckSendCompatibility(Parts::container & msgVec)
|
||||||
{
|
{
|
||||||
for (auto& msg : msgVec) {
|
for (auto& msg : msgVec) {
|
||||||
if (fTransportType != msg->GetType()) {
|
if (fTransportType != msg->GetType()) {
|
||||||
|
@ -437,10 +450,10 @@ class Channel
|
||||||
msg.get()
|
msg.get()
|
||||||
));
|
));
|
||||||
msg.release();
|
msg.release();
|
||||||
msg = move(msgWrapper);
|
msg = std::move(msgWrapper);
|
||||||
} else {
|
} else {
|
||||||
MessagePtr newMsg(NewMessage());
|
MessagePtr newMsg(NewMessage());
|
||||||
msg = move(newMsg);
|
msg = std::move(newMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,18 +463,18 @@ class Channel
|
||||||
{
|
{
|
||||||
if (fTransportType != msg->GetType()) {
|
if (fTransportType != msg->GetType()) {
|
||||||
MessagePtr newMsg(NewMessage());
|
MessagePtr newMsg(NewMessage());
|
||||||
msg = move(newMsg);
|
msg = std::move(newMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckReceiveCompatibility(Parts& parts) { CheckReceiveCompatibility(parts.fParts); }
|
void CheckReceiveCompatibility(Parts& parts) { CheckReceiveCompatibility(parts.fParts); }
|
||||||
void CheckReceiveCompatibility(std::vector<MessagePtr>& msgVec)
|
void CheckReceiveCompatibility(Parts::container& msgVec)
|
||||||
{
|
{
|
||||||
for (auto& msg : msgVec) {
|
for (auto& msg : msgVec) {
|
||||||
if (fTransportType != msg->GetType()) {
|
if (fTransportType != msg->GetType()) {
|
||||||
|
|
||||||
MessagePtr newMsg(NewMessage());
|
MessagePtr newMsg(NewMessage());
|
||||||
msg = move(newMsg);
|
msg = std::move(newMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,7 +488,6 @@ class Channel
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using FairMQChannel [[deprecated("Use fair::mq::Channel")]] = fair::mq::Channel;
|
using FairMQChannel [[deprecated("Use fair::mq::Channel")]] = fair::mq::Channel;
|
||||||
using FairMQChannel = fair::mq::Channel;
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_CHANNEL_H
|
#endif // FAIR_MQ_CHANNEL_H
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2012-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2012-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <algorithm> // std::max, std::any_of
|
// FairMQ
|
||||||
#include <boost/algorithm/string.hpp> // join/split
|
|
||||||
#include <chrono>
|
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
#include <fairmq/Tools.h>
|
#include <fairmq/Tools.h>
|
||||||
|
#include <fairmq/Transports.h>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/algorithm/string.hpp> // join/split
|
||||||
|
|
||||||
|
// std
|
||||||
|
#include <algorithm> // std::max, std::any_of
|
||||||
|
#include <chrono>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory> // std::make_unique
|
#include <memory> // std::make_unique
|
||||||
|
@ -72,6 +78,9 @@ Device::Device(ProgOptions& config, tools::Version version)
|
||||||
: Device(&config, version)
|
: Device(&config, version)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/// TODO: Remove this once Device::fChannels is no longer public
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
Device::Device(ProgOptions* config, tools::Version version)
|
Device::Device(ProgOptions* config, tools::Version version)
|
||||||
: fTransportFactory(nullptr)
|
: fTransportFactory(nullptr)
|
||||||
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
|
, fInternalConfig(config ? nullptr : make_unique<ProgOptions>())
|
||||||
|
@ -83,18 +92,15 @@ Device::Device(ProgOptions* config, tools::Version version)
|
||||||
, fVersion(version)
|
, fVersion(version)
|
||||||
, fRate(DefaultRate)
|
, fRate(DefaultRate)
|
||||||
, fInitializationTimeoutInS(DefaultInitTimeout)
|
, fInitializationTimeoutInS(DefaultInitTimeout)
|
||||||
, fTransitioning(false)
|
|
||||||
{
|
{
|
||||||
SubscribeToNewTransition("device", [&](Transition transition) {
|
SubscribeToNewTransition("device", [&](Transition transition) {
|
||||||
LOG(trace) << "device notified on new transition: " << transition;
|
LOG(trace) << "device notified on new transition: " << transition;
|
||||||
|
InterruptTransports();
|
||||||
|
});
|
||||||
|
|
||||||
switch (transition) {
|
fStateMachine.PrepareState([&](State state) {
|
||||||
case Transition::Stop:
|
LOG(trace) << "Resuming transports for " << state << " state";
|
||||||
UnblockTransports();
|
ResumeTransports();
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fStateMachine.HandleStates([&](State state) {
|
fStateMachine.HandleStates([&](State state) {
|
||||||
|
@ -135,73 +141,7 @@ Device::Device(ProgOptions* config, tools::Version version)
|
||||||
|
|
||||||
fStateMachine.Start();
|
fStateMachine.Start();
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
void Device::TransitionTo(State s)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
using mq::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentState = sq.WaitForNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
lock_guard<mutex> lock(fTransitionMtx);
|
|
||||||
fTransitioning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::InitWrapper()
|
void Device::InitWrapper()
|
||||||
{
|
{
|
||||||
|
@ -226,7 +166,7 @@ void Device::InitWrapper()
|
||||||
unordered_map<string, int> infos = fConfig->GetChannelInfo();
|
unordered_map<string, int> infos = fConfig->GetChannelInfo();
|
||||||
for (const auto& info : infos) {
|
for (const auto& info : infos) {
|
||||||
for (int i = 0; i < info.second; ++i) {
|
for (int i = 0; i < info.second; ++i) {
|
||||||
fChannels[info.first].emplace_back(info.first, i, fConfig->GetPropertiesStartingWith(tools::ToString("chans.", info.first, ".", i, ".")));
|
GetChannels()[info.first].emplace_back(info.first, i, fConfig->GetPropertiesStartingWith(tools::ToString("chans.", info.first, ".", i, ".")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,8 +176,7 @@ void Device::InitWrapper()
|
||||||
string networkInterface = fConfig->GetProperty<string>("network-interface", DefaultNetworkInterface);
|
string networkInterface = fConfig->GetProperty<string>("network-interface", DefaultNetworkInterface);
|
||||||
|
|
||||||
// Fill the uninitialized channel containers
|
// Fill the uninitialized channel containers
|
||||||
for (auto& channel : fChannels) {
|
for (auto& channel : GetChannels()) {
|
||||||
int subChannelIndex = 0;
|
|
||||||
for (auto& subChannel : channel.second) {
|
for (auto& subChannel : channel.second) {
|
||||||
// set channel transport
|
// set channel transport
|
||||||
LOG(debug) << "Initializing transport for channel " << subChannel.fName << ": " << TransportNames.at(subChannel.fTransportType);
|
LOG(debug) << "Initializing transport for channel " << subChannel.fName << ": " << TransportNames.at(subChannel.fTransportType);
|
||||||
|
@ -269,12 +208,10 @@ void Device::InitWrapper()
|
||||||
LOG(error) << "Cannot update configuration. Socket method (bind/connect) for channel '" << subChannel.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."));
|
throw runtime_error(tools::ToString("Cannot update configuration. Socket method (bind/connect) for channel ", subChannel.fName, " not specified."));
|
||||||
}
|
}
|
||||||
|
|
||||||
subChannelIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeState(Transition::Auto);
|
// ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::BindWrapper()
|
void Device::BindWrapper()
|
||||||
|
@ -291,7 +228,7 @@ void Device::BindWrapper()
|
||||||
Bind();
|
Bind();
|
||||||
|
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
ChangeState(Transition::Auto);
|
ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +241,7 @@ void Device::ConnectWrapper()
|
||||||
// first attempt
|
// first attempt
|
||||||
AttachChannels(fUninitializedConnectingChannels);
|
AttachChannels(fUninitializedConnectingChannels);
|
||||||
// if not all channels could be connected, update their address values from config and retry
|
// if not all channels could be connected, update their address values from config and retry
|
||||||
while (!fUninitializedConnectingChannels.empty()) {
|
while (!fUninitializedConnectingChannels.empty() && !NewStatePending()) {
|
||||||
this_thread::sleep_for(chrono::milliseconds(sleepTimeInMS));
|
this_thread::sleep_for(chrono::milliseconds(sleepTimeInMS));
|
||||||
|
|
||||||
for (auto& chan : fUninitializedConnectingChannels) {
|
for (auto& chan : fUninitializedConnectingChannels) {
|
||||||
|
@ -317,20 +254,24 @@ void Device::ConnectWrapper()
|
||||||
|
|
||||||
if (numAttempts++ > maxAttempts) {
|
if (numAttempts++ > maxAttempts) {
|
||||||
LOG(error) << "could not connect all channels after " << fInitializationTimeoutInS << " attempts";
|
LOG(error) << "could not connect all channels after " << fInitializationTimeoutInS << " attempts";
|
||||||
|
LOG(error) << "following channels are still invalid:";
|
||||||
|
for (auto& chan : fUninitializedConnectingChannels) {
|
||||||
|
LOG(error) << "channel: " << *chan;
|
||||||
|
}
|
||||||
throw runtime_error(tools::ToString("could not connect all channels after ", fInitializationTimeoutInS, " attempts"));
|
throw runtime_error(tools::ToString("could not connect all channels after ", fInitializationTimeoutInS, " attempts"));
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachChannels(fUninitializedConnectingChannels);
|
AttachChannels(fUninitializedConnectingChannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fChannels.empty()) {
|
if (GetChannels().empty()) {
|
||||||
LOG(warn) << "No channels created after finishing initialization";
|
LOG(warn) << "No channels created after finishing initialization";
|
||||||
}
|
}
|
||||||
|
|
||||||
Connect();
|
Connect();
|
||||||
|
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
ChangeState(Transition::Auto);
|
ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +286,7 @@ void Device::AttachChannels(vector<Channel*>& chans)
|
||||||
// remove the channel from the uninitialized container
|
// remove the channel from the uninitialized container
|
||||||
itr = chans.erase(itr);
|
itr = chans.erase(itr);
|
||||||
} else {
|
} else {
|
||||||
LOG(error) << "failed to attach channel " << (*itr)->fName << " (" << (*itr)->fMethod << ")";
|
LOG(error) << "failed to attach channel " << (*itr)->fName << " (" << (*itr)->fMethod << " on " << (*itr)->fAddress << ")";
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -432,7 +373,7 @@ void Device::InitTaskWrapper()
|
||||||
InitTask();
|
InitTask();
|
||||||
|
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
ChangeState(Transition::Auto);
|
ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +383,7 @@ void Device::RunWrapper()
|
||||||
|
|
||||||
unique_ptr<thread> rateLogger;
|
unique_ptr<thread> rateLogger;
|
||||||
// Check if rate logging thread is needed
|
// Check if rate logging thread is needed
|
||||||
const bool rateLogging = any_of(fChannels.cbegin(), fChannels.cend(), [](auto ch) {
|
const bool rateLogging = any_of(GetChannels().cbegin(), GetChannels().cend(), [](auto ch) {
|
||||||
return any_of(ch.second.cbegin(), ch.second.cend(), [](auto sub) { return sub.fRateLogging > 0; });
|
return any_of(ch.second.cbegin(), ch.second.cend(), [](auto sub) { return sub.fRateLogging > 0; });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -453,15 +394,9 @@ void Device::RunWrapper()
|
||||||
if (rateLogging && rateLogger->joinable()) { rateLogger->join(); }
|
if (rateLogging && rateLogger->joinable()) { rateLogger->join(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// notify transports to resume transfers
|
|
||||||
for (auto& t : fTransports) {
|
|
||||||
t.second->Resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
// change to Error state in case of an exception, to release LogSocketRates
|
// change to Error state in case of an exception, to release LogSocketRates
|
||||||
tools::CallOnDestruction cod([&](){
|
tools::CallOnDestruction cod([&](){
|
||||||
ChangeState(Transition::ErrorFound);
|
ChangeStateOrThrow(Transition::ErrorFound);
|
||||||
});
|
});
|
||||||
|
|
||||||
PreRun();
|
PreRun();
|
||||||
|
@ -469,7 +404,7 @@ void Device::RunWrapper()
|
||||||
// process either data callbacks or ConditionalRun/Run
|
// process either data callbacks or ConditionalRun/Run
|
||||||
if (fDataCallbacks) {
|
if (fDataCallbacks) {
|
||||||
// if only one input channel, do lightweight handling without additional polling.
|
// if only one input channel, do lightweight handling without additional polling.
|
||||||
if (fInputChannelKeys.size() == 1 && fChannels.at(fInputChannelKeys.at(0)).size() == 1) {
|
if (fInputChannelKeys.size() == 1 && GetChannels().at(fInputChannelKeys.at(0)).size() == 1) {
|
||||||
HandleSingleChannelInput();
|
HandleSingleChannelInput();
|
||||||
} else {// otherwise do full handling with polling
|
} else {// otherwise do full handling with polling
|
||||||
HandleMultipleChannelInput();
|
HandleMultipleChannelInput();
|
||||||
|
@ -488,8 +423,7 @@ void Device::RunWrapper()
|
||||||
|
|
||||||
// if Run() exited and the state is still RUNNING, transition to READY.
|
// if Run() exited and the state is still RUNNING, transition to READY.
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
UnblockTransports();
|
ChangeStateOrThrow(Transition::Stop);
|
||||||
ChangeState(Transition::Stop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostRun();
|
PostRun();
|
||||||
|
@ -517,7 +451,7 @@ void Device::HandleMultipleChannelInput()
|
||||||
// check if more than one transport is used
|
// check if more than one transport is used
|
||||||
fMultitransportInputs.clear();
|
fMultitransportInputs.clear();
|
||||||
for (const auto& k : fInputChannelKeys) {
|
for (const auto& k : fInputChannelKeys) {
|
||||||
mq::Transport t = fChannels.at(k).at(0).fTransportType;
|
mq::Transport t = GetChannel(k, 0).fTransportType;
|
||||||
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
|
if (fMultitransportInputs.find(t) == fMultitransportInputs.end()) {
|
||||||
fMultitransportInputs.insert(pair<mq::Transport, vector<string>>(t, vector<string>()));
|
fMultitransportInputs.insert(pair<mq::Transport, vector<string>>(t, vector<string>()));
|
||||||
fMultitransportInputs.at(t).push_back(k);
|
fMultitransportInputs.at(t).push_back(k);
|
||||||
|
@ -527,13 +461,13 @@ void Device::HandleMultipleChannelInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& mi : fMsgInputs) {
|
for (const auto& mi : fMsgInputs) {
|
||||||
for (auto& i : fChannels.at(mi.first)) {
|
for (auto& i : GetChannels().at(mi.first)) {
|
||||||
i.fMultipart = false;
|
i.fMultipart = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& mi : fMultipartInputs) {
|
for (const auto& mi : fMultipartInputs) {
|
||||||
for (auto& i : fChannels.at(mi.first)) {
|
for (auto& i : GetChannels().at(mi.first)) {
|
||||||
i.fMultipart = true;
|
i.fMultipart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,16 +478,16 @@ void Device::HandleMultipleChannelInput()
|
||||||
} else { // otherwise poll directly
|
} else { // otherwise poll directly
|
||||||
bool proceed = true;
|
bool proceed = true;
|
||||||
|
|
||||||
PollerPtr poller(fChannels.at(fInputChannelKeys.at(0)).at(0).fTransportFactory->CreatePoller(fChannels, fInputChannelKeys));
|
PollerPtr poller(GetChannel(fInputChannelKeys.at(0), 0).fTransportFactory->CreatePoller(GetChannels(), fInputChannelKeys));
|
||||||
|
|
||||||
while (!NewStatePending() && proceed) {
|
while (!NewStatePending() && proceed) {
|
||||||
poller->Poll(200);
|
poller->Poll(200);
|
||||||
|
|
||||||
// check which inputs are ready and call their data handlers if they are.
|
// check which inputs are ready and call their data handlers if they are.
|
||||||
for (const auto& ch : fInputChannelKeys) {
|
for (const auto& ch : fInputChannelKeys) {
|
||||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
|
for (unsigned int i = 0; i < GetChannels().at(ch).size(); ++i) {
|
||||||
if (poller->CheckInput(ch, i)) {
|
if (poller->CheckInput(ch, i)) {
|
||||||
if (fChannels.at(ch).at(i).fMultipart) {
|
if (GetChannel(ch, i).fMultipart) {
|
||||||
proceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
proceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
||||||
} else {
|
} else {
|
||||||
proceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
proceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
||||||
|
@ -590,13 +524,13 @@ void Device::HandleMultipleTransportInput()
|
||||||
void Device::PollForTransport(const TransportFactory* factory, const vector<string>& channelKeys)
|
void Device::PollForTransport(const TransportFactory* factory, const vector<string>& channelKeys)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
PollerPtr poller(factory->CreatePoller(fChannels, channelKeys));
|
PollerPtr poller(factory->CreatePoller(GetChannels(), channelKeys));
|
||||||
|
|
||||||
while (!NewStatePending() && fMultitransportProceed) {
|
while (!NewStatePending() && fMultitransportProceed) {
|
||||||
poller->Poll(500);
|
poller->Poll(500);
|
||||||
|
|
||||||
for (const auto& ch : channelKeys) {
|
for (const auto& ch : channelKeys) {
|
||||||
for (unsigned int i = 0; i < fChannels.at(ch).size(); ++i) {
|
for (unsigned int i = 0; i < GetChannels().at(ch).size(); ++i) {
|
||||||
if (poller->CheckInput(ch, i)) {
|
if (poller->CheckInput(ch, i)) {
|
||||||
lock_guard<mutex> lock(fMultitransportMutex);
|
lock_guard<mutex> lock(fMultitransportMutex);
|
||||||
|
|
||||||
|
@ -604,7 +538,7 @@ void Device::PollForTransport(const TransportFactory* factory, const vector<stri
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fChannels.at(ch).at(i).fMultipart) {
|
if (GetChannel(ch, i).fMultipart) {
|
||||||
fMultitransportProceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
fMultitransportProceed = HandleMultipartInput(ch, fMultipartInputs.at(ch), i);
|
||||||
} else {
|
} else {
|
||||||
fMultitransportProceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
fMultitransportProceed = HandleMsgInput(ch, fMsgInputs.at(ch), i);
|
||||||
|
@ -628,7 +562,7 @@ void Device::PollForTransport(const TransportFactory* factory, const vector<stri
|
||||||
|
|
||||||
bool Device::HandleMsgInput(const string& chName, const InputMsgCallback& callback, int i)
|
bool Device::HandleMsgInput(const string& chName, const InputMsgCallback& callback, int i)
|
||||||
{
|
{
|
||||||
unique_ptr<Message> input(fChannels.at(chName).at(i).fTransportFactory->CreateMessage());
|
unique_ptr<Message> input(GetChannel(chName, i).fTransportFactory->CreateMessage());
|
||||||
|
|
||||||
if (Receive(input, chName, i) >= 0) {
|
if (Receive(input, chName, i) >= 0) {
|
||||||
return callback(input, i);
|
return callback(input, i);
|
||||||
|
@ -650,6 +584,8 @@ bool Device::HandleMultipartInput(const string& chName, const InputMultipartCall
|
||||||
|
|
||||||
shared_ptr<TransportFactory> Device::AddTransport(mq::Transport transport)
|
shared_ptr<TransportFactory> Device::AddTransport(mq::Transport transport)
|
||||||
{
|
{
|
||||||
|
lock_guard<mutex> lock(fTransportMtx);
|
||||||
|
|
||||||
if (transport == mq::Transport::DEFAULT) {
|
if (transport == mq::Transport::DEFAULT) {
|
||||||
transport = fDefaultTransportType;
|
transport = fDefaultTransportType;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +619,7 @@ void Device::LogSocketRates()
|
||||||
size_t chanNameLen = 0;
|
size_t chanNameLen = 0;
|
||||||
|
|
||||||
// iterate over the channels map
|
// iterate over the channels map
|
||||||
for (auto& channel : fChannels) {
|
for (auto& channel : GetChannels()) {
|
||||||
// iterate over the channels vector
|
// iterate over the channels vector
|
||||||
for (auto& subChannel : channel.second) {
|
for (auto& subChannel : channel.second) {
|
||||||
if (subChannel.fRateLogging > 0) {
|
if (subChannel.fRateLogging > 0) {
|
||||||
|
@ -767,10 +703,19 @@ void Device::LogSocketRates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::UnblockTransports()
|
void Device::InterruptTransports()
|
||||||
{
|
{
|
||||||
for (auto& transport : fTransports) {
|
lock_guard<mutex> lock(fTransportMtx);
|
||||||
transport.second->Interrupt();
|
for (auto& [transportType, transport] : fTransports) {
|
||||||
|
transport->Interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::ResumeTransports()
|
||||||
|
{
|
||||||
|
lock_guard<mutex> lock(fTransportMtx);
|
||||||
|
for (auto& [transportType, transport] : fTransports) {
|
||||||
|
transport->Resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,31 +724,38 @@ void Device::ResetTaskWrapper()
|
||||||
ResetTask();
|
ResetTask();
|
||||||
|
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
ChangeState(Transition::Auto);
|
ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::ResetWrapper()
|
void Device::ResetWrapper()
|
||||||
{
|
{
|
||||||
for (auto& transport : fTransports) {
|
{
|
||||||
transport.second->Reset();
|
lock_guard<mutex> lock(fTransportMtx);
|
||||||
|
for (auto& [transportType, transport] : fTransports) {
|
||||||
|
transport->Reset();
|
||||||
|
}
|
||||||
|
fTransports.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
fChannels.clear();
|
GetChannels().clear();
|
||||||
fTransports.clear();
|
|
||||||
fTransportFactory.reset();
|
fTransportFactory.reset();
|
||||||
if (!NewStatePending()) {
|
if (!NewStatePending()) {
|
||||||
ChangeState(Transition::Auto);
|
ChangeStateOrThrow(Transition::Auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TODO: Remove this once Device::fChannels is no longer public
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
{
|
{
|
||||||
UnsubscribeFromNewTransition("device");
|
UnsubscribeFromNewTransition("device");
|
||||||
fStateMachine.StopHandlingStates();
|
fStateMachine.StopHandlingStates();
|
||||||
LOG(debug) << "Shutting down device " << fId;
|
LOG(debug) << "Shutting down device " << fId;
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
102
fairmq/Device.h
102
fairmq/Device.h
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2021-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2021-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,12 +9,9 @@
|
||||||
#ifndef FAIR_MQ_DEVICE_H
|
#ifndef FAIR_MQ_DEVICE_H
|
||||||
#define FAIR_MQ_DEVICE_H
|
#define FAIR_MQ_DEVICE_H
|
||||||
|
|
||||||
#include <algorithm> // find
|
// FairMQ
|
||||||
#include <atomic>
|
|
||||||
#include <chrono>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <fairlogger/Logger.h>
|
|
||||||
#include <fairmq/Channel.h>
|
#include <fairmq/Channel.h>
|
||||||
|
#include <fairmq/Error.h>
|
||||||
#include <fairmq/Message.h>
|
#include <fairmq/Message.h>
|
||||||
#include <fairmq/Parts.h>
|
#include <fairmq/Parts.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
@ -22,8 +19,17 @@
|
||||||
#include <fairmq/StateQueue.h>
|
#include <fairmq/StateQueue.h>
|
||||||
#include <fairmq/Tools.h>
|
#include <fairmq/Tools.h>
|
||||||
#include <fairmq/TransportFactory.h>
|
#include <fairmq/TransportFactory.h>
|
||||||
#include <fairmq/Transports.h>
|
#include <fairmq/TransportEnum.h>
|
||||||
#include <fairmq/UnmanagedRegion.h>
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
|
||||||
|
// logger
|
||||||
|
#include <fairlogger/Logger.h>
|
||||||
|
|
||||||
|
// std
|
||||||
|
#include <algorithm> // find
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory> // unique_ptr
|
#include <memory> // unique_ptr
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -228,7 +234,7 @@ class Device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetChannel(chans.at(0), 0).Transport()->CreatePoller(fChannels, chans);
|
return GetChannel(chans.at(0), 0).Transport()->CreatePoller(GetChannels(), chans);
|
||||||
}
|
}
|
||||||
|
|
||||||
PollerPtr NewPoller(const std::vector<Channel*>& channels)
|
PollerPtr NewPoller(const std::vector<Channel*>& channels)
|
||||||
|
@ -316,7 +322,7 @@ class Device
|
||||||
|
|
||||||
Channel& GetChannel(const std::string& channelName, const int index = 0)
|
Channel& GetChannel(const std::string& channelName, const int index = 0)
|
||||||
try {
|
try {
|
||||||
return fChannels.at(channelName).at(index);
|
return GetChannels().at(channelName).at(index);
|
||||||
} catch (const std::out_of_range& oor) {
|
} catch (const std::out_of_range& oor) {
|
||||||
LOG(error) << "GetChannel(): '" << channelName << "[" << index << "]' does not exist.";
|
LOG(error) << "GetChannel(): '" << channelName << "[" << index << "]' does not exist.";
|
||||||
throw;
|
throw;
|
||||||
|
@ -324,7 +330,7 @@ class Device
|
||||||
|
|
||||||
size_t GetNumSubChannels(const std::string& channelName)
|
size_t GetNumSubChannels(const std::string& channelName)
|
||||||
try {
|
try {
|
||||||
return fChannels.at(channelName).size();
|
return GetChannels().at(channelName).size();
|
||||||
} catch (const std::out_of_range& oor) {
|
} catch (const std::out_of_range& oor) {
|
||||||
LOG(error) << "GetNumSubChannels(): '" << channelName << "' does not exist.";
|
LOG(error) << "GetNumSubChannels(): '" << channelName << "' does not exist.";
|
||||||
throw;
|
throw;
|
||||||
|
@ -335,7 +341,7 @@ class Device
|
||||||
/// @param index sub-channel
|
/// @param index sub-channel
|
||||||
unsigned long GetNumberOfConnectedPeers(const std::string& channelName, int index = 0)
|
unsigned long GetNumberOfConnectedPeers(const std::string& channelName, int index = 0)
|
||||||
{
|
{
|
||||||
return fChannels.at(channelName).at(index).GetNumberOfConnectedPeers();
|
return GetChannel(channelName, index).GetNumberOfConnectedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void RegisterChannelEndpoints() {}
|
virtual void RegisterChannelEndpoints() {}
|
||||||
|
@ -433,7 +439,23 @@ class Device
|
||||||
fTransports; ///< Container for transports
|
fTransports; ///< Container for transports
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
[[deprecated("Use GetChannels() instead.")]]
|
||||||
std::unordered_map<std::string, std::vector<Channel>> fChannels; ///< Device channels
|
std::unordered_map<std::string, std::vector<Channel>> fChannels; ///< Device channels
|
||||||
|
std::unordered_map<std::string, std::vector<Channel>>& GetChannels()
|
||||||
|
{
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
return fChannels;
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
}
|
||||||
|
std::unordered_map<std::string, std::vector<Channel>> const& GetChannels() const
|
||||||
|
{
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
return fChannels;
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ProgOptions> fInternalConfig; ///< Internal program options configuration
|
std::unique_ptr<ProgOptions> fInternalConfig; ///< Internal program options configuration
|
||||||
ProgOptions* fConfig; ///< Pointer to config (internal or external)
|
ProgOptions* fConfig; ///< Pointer to config (internal or external)
|
||||||
|
|
||||||
|
@ -477,21 +499,49 @@ class Device
|
||||||
public:
|
public:
|
||||||
/// @brief Request a device state transition
|
/// @brief Request a device state transition
|
||||||
/// @param transition state transition
|
/// @param transition state transition
|
||||||
|
/// @return whether the transition was successfully scheduled
|
||||||
///
|
///
|
||||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||||
/// pending transition event and terminates. In other words, the device states are scheduled
|
/// pending transition event and terminates. In other words, the device states are scheduled
|
||||||
/// cooperatively.
|
/// cooperatively.
|
||||||
bool ChangeState(const Transition transition) { return fStateMachine.ChangeState(transition); }
|
[[nodiscard]] bool ChangeState(const Transition transition)
|
||||||
|
{
|
||||||
|
return fStateMachine.ChangeState(transition);
|
||||||
|
}
|
||||||
/// @brief Request a device state transition
|
/// @brief Request a device state transition
|
||||||
/// @param transition state transition
|
/// @param transition state transition
|
||||||
|
/// @return whether the transition was successfully scheduled
|
||||||
///
|
///
|
||||||
/// The state transition may not happen immediately, but when the current state evaluates the
|
/// The state transition may not happen immediately, but when the current state evaluates the
|
||||||
/// pending transition event and terminates. In other words, the device states are scheduled
|
/// pending transition event and terminates. In other words, the device states are scheduled
|
||||||
/// cooperatively.
|
/// cooperatively.
|
||||||
bool ChangeState(const std::string& transition)
|
[[nodiscard]] bool ChangeState(const std::string& transition)
|
||||||
{
|
{
|
||||||
return fStateMachine.ChangeState(GetTransition(transition));
|
return fStateMachine.ChangeState(GetTransition(transition));
|
||||||
}
|
}
|
||||||
|
/// @brief Request a device state transition
|
||||||
|
/// @param transition state transition
|
||||||
|
/// @throws when the transition could not have been scheduled
|
||||||
|
///
|
||||||
|
/// Throwing version of Device::ChangeState().
|
||||||
|
void ChangeStateOrThrow(Transition transition)
|
||||||
|
{
|
||||||
|
if(!ChangeState(transition)) {
|
||||||
|
auto const err = MakeErrorCode(ErrorCode::DeviceChangeStateFailed);
|
||||||
|
throw std::system_error(err.value(),
|
||||||
|
err.category(),
|
||||||
|
tools::ToString("Invalid transition: ", transition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// @brief Request a device state transition
|
||||||
|
/// @param transition state transition
|
||||||
|
/// @throws when the transition could not have been scheduled
|
||||||
|
///
|
||||||
|
/// Throwing version of Device::ChangeState().
|
||||||
|
void ChangeStateOrThrow(std::string const& transition)
|
||||||
|
{
|
||||||
|
ChangeStateOrThrow(GetTransition(transition));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief waits for the next state (any) to occur
|
/// @brief waits for the next state (any) to occur
|
||||||
State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
State WaitForNextState() { return fStateQueue.WaitForNext(); }
|
||||||
|
@ -502,8 +552,6 @@ class Device
|
||||||
/// @param state state to wait for
|
/// @param state state to wait for
|
||||||
void WaitForState(const std::string& state) { WaitForState(GetState(state)); }
|
void WaitForState(const std::string& state) { WaitForState(GetState(state)); }
|
||||||
|
|
||||||
void TransitionTo(State state);
|
|
||||||
|
|
||||||
/// @brief Subscribe with a callback to state changes
|
/// @brief Subscribe with a callback to state changes
|
||||||
/// @param key id to identify your subscription
|
/// @param key id to identify your subscription
|
||||||
/// @param callback callback (called with the new state as the parameter)
|
/// @param callback callback (called with the new state as the parameter)
|
||||||
|
@ -588,7 +636,10 @@ class Device
|
||||||
void ResetWrapper();
|
void ResetWrapper();
|
||||||
|
|
||||||
/// Notifies transports to cease any blocking activity
|
/// Notifies transports to cease any blocking activity
|
||||||
void UnblockTransports();
|
void InterruptTransports();
|
||||||
|
|
||||||
|
/// Notifies transports to resume any blocking activity
|
||||||
|
void ResumeTransports();
|
||||||
|
|
||||||
/// Shuts down the transports and the device
|
/// Shuts down the transports and the device
|
||||||
void Exit() {}
|
void Exit() {}
|
||||||
|
@ -622,28 +673,19 @@ class Device
|
||||||
|
|
||||||
const tools::Version fVersion;
|
const tools::Version fVersion;
|
||||||
float fRate; ///< Rate limiting for ConditionalRun
|
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;
|
int fInitializationTimeoutInS;
|
||||||
std::vector<std::string> fRawCmdLineArgs;
|
std::vector<std::string> fRawCmdLineArgs;
|
||||||
|
|
||||||
StateQueue fStateQueue;
|
StateQueue fStateQueue;
|
||||||
|
|
||||||
std::mutex fTransitionMtx;
|
std::mutex fTransportMtx; ///< guards access to transports container
|
||||||
bool fTransitioning;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using FairMQChannelMap [[deprecated("Use fair::mq::ChannelMap")]] = fair::mq::ChannelMap;
|
using FairMQChannelMap [[deprecated("Use fair::mq::ChannelMap")]] = fair::mq::ChannelMap;
|
||||||
// using InputMsgCallback [[deprecated("Use fair::mq::InputMsgCallback")]] =
|
using InputMsgCallback [[deprecated("Use fair::mq::InputMsgCallback")]] = fair::mq::InputMsgCallback;
|
||||||
// fair::mq::InputMsgCallback;
|
using InputMultipartCallback [[deprecated("Use fair::mq::InputMultipartCallback")]] = fair::mq::InputMultipartCallback;
|
||||||
// using InputMultipartCallback [[deprecated("Use fair::mq::InputMultipartCallback")]] =
|
using FairMQDevice [[deprecated("Use fair::mq::Device")]] = fair::mq::Device;
|
||||||
// fair::mq::InputMultipartCallback;
|
|
||||||
// using FairMQDevice [[deprecated("Use fair::mq::Device")]] = fair::mq::Device;
|
|
||||||
using FairMQChannelMap = fair::mq::ChannelMap;
|
|
||||||
using InputMsgCallback = fair::mq::InputMsgCallback;
|
|
||||||
using InputMultipartCallback = fair::mq::InputMultipartCallback;
|
|
||||||
using FairMQDevice = fair::mq::Device;
|
|
||||||
|
|
||||||
#endif /* FAIR_MQ_DEVICE_H */
|
#endif /* FAIR_MQ_DEVICE_H */
|
||||||
|
|
|
@ -152,7 +152,7 @@ auto DeviceRunner::Run() -> int
|
||||||
fDevice->RegisterChannelEndpoints();
|
fDevice->RegisterChannelEndpoints();
|
||||||
if (fConfig.Count("print-channels")) {
|
if (fConfig.Count("print-channels")) {
|
||||||
fDevice->PrintRegisteredChannels();
|
fDevice->PrintRegisteredChannels();
|
||||||
fDevice->ChangeState(fair::mq::Transition::End);
|
fDevice->ChangeStateOrThrow(fair::mq::Transition::End);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ auto DeviceRunner::Run() -> int
|
||||||
if (fConfig.Count("version")) {
|
if (fConfig.Count("version")) {
|
||||||
LOGV(info, verylow) << "FairMQ version: " << FAIRMQ_GIT_VERSION;
|
LOGV(info, verylow) << "FairMQ version: " << FAIRMQ_GIT_VERSION;
|
||||||
LOGV(info, verylow) << "User device version: " << fDevice->GetVersion();
|
LOGV(info, verylow) << "User device version: " << fDevice->GetVersion();
|
||||||
fDevice->ChangeState(fair::mq::Transition::End);
|
fDevice->ChangeStateOrThrow(fair::mq::Transition::End);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace fair::mq
|
||||||
* Each hook has access to all members of the DeviceRunner and really only differs by the point in
|
* Each hook has access to all members of the DeviceRunner and really only differs by the point in
|
||||||
* time it is called.
|
* time it is called.
|
||||||
*
|
*
|
||||||
* For an example usage of this class see the fairmq/runFairMQDevice.h header.
|
* For an example usage of this class see the <fairmq/runDevice.h> header.
|
||||||
*/
|
*/
|
||||||
class DeviceRunner
|
class DeviceRunner
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include "Error.h"
|
|
||||||
|
|
||||||
namespace fair::mq {
|
|
||||||
|
|
||||||
const char* ErrorCategory::name() const noexcept { return "fairmq"; }
|
|
||||||
|
|
||||||
std::string ErrorCategory::message(int ev) const
|
|
||||||
{
|
|
||||||
switch (static_cast<ErrorCode>(ev)) {
|
|
||||||
case ErrorCode::OperationInProgress:
|
|
||||||
return "async operation already in progress";
|
|
||||||
case ErrorCode::OperationTimeout:
|
|
||||||
return "async operation timed out";
|
|
||||||
case ErrorCode::OperationCanceled:
|
|
||||||
return "async operation canceled";
|
|
||||||
case ErrorCode::DeviceChangeStateFailed:
|
|
||||||
return "failed to change state of a fairmq device";
|
|
||||||
case ErrorCode::DeviceGetPropertiesFailed:
|
|
||||||
return "failed to get fairmq device properties";
|
|
||||||
case ErrorCode::DeviceSetPropertiesFailed:
|
|
||||||
return "failed to set fairmq device properties";
|
|
||||||
default:
|
|
||||||
return "(unrecognized error)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ErrorCategory errorCategory{};
|
|
||||||
|
|
||||||
std::error_code MakeErrorCode(ErrorCode e) { return {static_cast<int>(e), errorCategory}; }
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
|
|
@ -38,14 +38,34 @@ enum class ErrorCode
|
||||||
DeviceSetPropertiesFailed
|
DeviceSetPropertiesFailed
|
||||||
};
|
};
|
||||||
|
|
||||||
std::error_code MakeErrorCode(ErrorCode);
|
|
||||||
|
|
||||||
struct ErrorCategory : std::error_category
|
struct ErrorCategory : std::error_category
|
||||||
{
|
{
|
||||||
const char* name() const noexcept override;
|
const char* name() const noexcept override { return "fairmq"; }
|
||||||
std::string message(int ev) const override;
|
std::string message(int ev) const override
|
||||||
|
{
|
||||||
|
switch (static_cast<ErrorCode>(ev)) {
|
||||||
|
case ErrorCode::OperationInProgress:
|
||||||
|
return "async operation already in progress";
|
||||||
|
case ErrorCode::OperationTimeout:
|
||||||
|
return "async operation timed out";
|
||||||
|
case ErrorCode::OperationCanceled:
|
||||||
|
return "async operation canceled";
|
||||||
|
case ErrorCode::DeviceChangeStateFailed:
|
||||||
|
return "failed to change state of a fairmq device";
|
||||||
|
case ErrorCode::DeviceGetPropertiesFailed:
|
||||||
|
return "failed to get fairmq device properties";
|
||||||
|
case ErrorCode::DeviceSetPropertiesFailed:
|
||||||
|
return "failed to set fairmq device properties";
|
||||||
|
default:
|
||||||
|
return "(unrecognized error)";
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ErrorCategory ec;
|
||||||
|
|
||||||
|
inline std::error_code MakeErrorCode(ErrorCode e) { return {static_cast<int>(e), ec}; }
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
20
fairmq/EventManager.cxx
Normal file
20
fairmq/EventManager.cxx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
#include "EventManager.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
|
template std::shared_ptr<
|
||||||
|
fair::mq::EventManager::Signal<fair::mq::PropertyChangeAsString, std::string>>
|
||||||
|
fair::mq::EventManager::GetSignal<fair::mq::PropertyChangeAsString, std::string>(
|
||||||
|
const std::pair<std::type_index, std::type_index>& key) const;
|
||||||
|
|
||||||
|
template void fair::mq::EventManager::Subscribe<fair::mq::PropertyChangeAsString, std::string>(
|
||||||
|
const std::string& subscriber,
|
||||||
|
std::function<void(typename fair::mq::PropertyChangeAsString::KeyType, std::string)>);
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -57,27 +57,8 @@ class EventManager
|
||||||
template<typename E, typename ...Args>
|
template<typename E, typename ...Args>
|
||||||
using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>;
|
using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>;
|
||||||
|
|
||||||
template<typename E, typename ...Args>
|
template<typename E, typename... Args>
|
||||||
auto Subscribe(const std::string& subscriber, std::function<void(typename E::KeyType, Args...)> callback) -> void
|
auto Subscribe(const std::string& subscriber, std::function<void(typename E::KeyType, Args...)> callback) -> void;
|
||||||
{
|
|
||||||
const std::type_index event_type_index{typeid(E)};
|
|
||||||
const std::type_index callback_type_index{typeid(std::function<void(typename E::KeyType, Args...)>)};
|
|
||||||
const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
|
|
||||||
const auto connectionsKey = std::make_pair(subscriber, signalsKey);
|
|
||||||
|
|
||||||
const auto connection = GetSignal<E, Args...>(signalsKey)->connect(callback);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock{fMutex};
|
|
||||||
|
|
||||||
if (fConnections.find(connectionsKey) != fConnections.end())
|
|
||||||
{
|
|
||||||
fConnections.at(connectionsKey).disconnect();
|
|
||||||
fConnections.erase(connectionsKey);
|
|
||||||
}
|
|
||||||
fConnections.insert({connectionsKey, connection});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename E, typename ...Args>
|
template<typename E, typename ...Args>
|
||||||
auto Unsubscribe(const std::string& subscriber) -> void
|
auto Unsubscribe(const std::string& subscriber) -> void
|
||||||
|
@ -119,12 +100,17 @@ class EventManager
|
||||||
mutable std::mutex fMutex;
|
mutable std::mutex fMutex;
|
||||||
|
|
||||||
template<typename E, typename ...Args>
|
template<typename E, typename ...Args>
|
||||||
auto GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>
|
auto GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>;
|
||||||
{
|
}; /* class EventManager */
|
||||||
|
|
||||||
|
struct PropertyChangeAsString : Event<std::string> {};
|
||||||
|
|
||||||
|
template<typename E, typename... Args>
|
||||||
|
auto EventManager::GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> lock{fMutex};
|
std::lock_guard<std::mutex> lock{fMutex};
|
||||||
|
|
||||||
if (fSignals.find(key) == fSignals.end())
|
if (fSignals.find(key) == fSignals.end()) {
|
||||||
{
|
|
||||||
// wrapper is needed because boost::signals2::signal is neither copyable nor movable
|
// wrapper is needed because boost::signals2::signal is neither copyable nor movable
|
||||||
// and I don't know how else to insert it into the map
|
// and I don't know how else to insert it into the map
|
||||||
auto signal = std::make_shared<Signal<E, Args...>>();
|
auto signal = std::make_shared<Signal<E, Args...>>();
|
||||||
|
@ -132,8 +118,40 @@ class EventManager
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::any_cast<std::shared_ptr<Signal<E, Args...>>>(fSignals.at(key));
|
return boost::any_cast<std::shared_ptr<Signal<E, Args...>>>(fSignals.at(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, typename... Args>
|
||||||
|
auto EventManager::Subscribe(const std::string& subscriber,
|
||||||
|
std::function<void(typename E::KeyType, Args...)> callback) -> void
|
||||||
|
{
|
||||||
|
const std::type_index event_type_index{typeid(E)};
|
||||||
|
const std::type_index callback_type_index{
|
||||||
|
typeid(std::function<void(typename E::KeyType, Args...)>)};
|
||||||
|
const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
|
||||||
|
const auto connectionsKey = std::make_pair(subscriber, signalsKey);
|
||||||
|
|
||||||
|
const auto connection = GetSignal<E, Args...>(signalsKey)->connect(callback);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock{fMutex};
|
||||||
|
|
||||||
|
if (fConnections.find(connectionsKey) != fConnections.end()) {
|
||||||
|
fConnections.at(connectionsKey).disconnect();
|
||||||
|
fConnections.erase(connectionsKey);
|
||||||
}
|
}
|
||||||
}; /* class EventManager */
|
fConnections.insert({connectionsKey, connection});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern template std::shared_ptr<
|
||||||
|
fair::mq::EventManager::Signal<fair::mq::PropertyChangeAsString, std::string>>
|
||||||
|
fair::mq::EventManager::GetSignal<fair::mq::PropertyChangeAsString, std::string>(
|
||||||
|
const std::pair<std::type_index, std::type_index>& key) const;
|
||||||
|
|
||||||
|
extern template void
|
||||||
|
fair::mq::EventManager::Subscribe<fair::mq::PropertyChangeAsString, std::string>(
|
||||||
|
const std::string& subscriber,
|
||||||
|
std::function<void(typename fair::mq::PropertyChangeAsString::KeyType, std::string)>);
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQCHANNEL_H_
|
#ifndef FAIRMQCHANNEL_H_
|
||||||
#define FAIRMQCHANNEL_H_
|
#define FAIRMQCHANNEL_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_CHANNEL_H
|
#ifndef FAIR_MQ_CHANNEL_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Channel.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Channel.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Channel.h>
|
#include <fairmq/Channel.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2012-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQDEVICE_H_
|
#ifndef FAIRMQDEVICE_H_
|
||||||
#define FAIRMQDEVICE_H_
|
#define FAIRMQDEVICE_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_DEVICE_H
|
#ifndef FAIR_MQ_DEVICE_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Device.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Device.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Device.h>
|
#include <fairmq/Device.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,6 +9,8 @@
|
||||||
#ifndef FAIRMQLOGGER_H_
|
#ifndef FAIRMQLOGGER_H_
|
||||||
#define FAIRMQLOGGER_H_
|
#define FAIRMQLOGGER_H_
|
||||||
|
|
||||||
|
#pragma GCC warning "Deprecated header: Use <fairlogger/Logger.h> instead"
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
|
||||||
#endif /* FAIRMQLOGGER_H_ */
|
#endif /* FAIRMQLOGGER_H_ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQMESSAGE_H_
|
#ifndef FAIRMQMESSAGE_H_
|
||||||
#define FAIRMQMESSAGE_H_
|
#define FAIRMQMESSAGE_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_MESSAGE_H
|
#ifndef FAIR_MQ_MESSAGE_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Message.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Message.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Message.h>
|
#include <fairmq/Message.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQPARTS_H_
|
#ifndef FAIRMQPARTS_H_
|
||||||
#define FAIRMQPARTS_H_
|
#define FAIRMQPARTS_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_PARTS_H
|
#ifndef FAIR_MQ_PARTS_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Parts.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Parts.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Parts.h>
|
#include <fairmq/Parts.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQPOLLER_H_
|
#ifndef FAIRMQPOLLER_H_
|
||||||
#define FAIRMQPOLLER_H_
|
#define FAIRMQPOLLER_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_POLLER_H
|
#ifndef FAIR_MQ_POLLER_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Poller.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Poller.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Poller.h>
|
#include <fairmq/Poller.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQSOCKET_H_
|
#ifndef FAIRMQSOCKET_H_
|
||||||
#define FAIRMQSOCKET_H_
|
#define FAIRMQSOCKET_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_SOCKET_H
|
#ifndef FAIR_MQ_SOCKET_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/Socket.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/Socket.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/Socket.h>
|
#include <fairmq/Socket.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQTRANSPORTFACTORY_H_
|
#ifndef FAIRMQTRANSPORTFACTORY_H_
|
||||||
#define FAIRMQTRANSPORTFACTORY_H_
|
#define FAIRMQTRANSPORTFACTORY_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_TRANSPORTFACTORY_H
|
#ifndef FAIR_MQ_TRANSPORTFACTORY_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/TransportFactory.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/TransportFactory.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/TransportFactory.h>
|
#include <fairmq/TransportFactory.h>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,11 +9,9 @@
|
||||||
#ifndef FAIRMQUNMANAGEDREGION_H_
|
#ifndef FAIRMQUNMANAGEDREGION_H_
|
||||||
#define FAIRMQUNMANAGEDREGION_H_
|
#define FAIRMQUNMANAGEDREGION_H_
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifndef FAIR_MQ_UNMANAGEDREGION_H
|
#ifndef FAIR_MQ_UNMANAGEDREGION_H
|
||||||
#pragma GCC warning "Deprecated header: Use <fairmq/UnmanagedRegion.h> instead"
|
#pragma GCC warning "Deprecated header: Use <fairmq/UnmanagedRegion.h> instead"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fairmq/UnmanagedRegion.h>
|
#include <fairmq/UnmanagedRegion.h>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
||||||
* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2018-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
///
|
///
|
||||||
/// @author Mikolaj Krzewicki, mkrzewic@cern.ch
|
/// @author Mikolaj Krzewicki, mkrzewic@cern.ch
|
||||||
|
|
||||||
#include <fairmq/FairMQTransportFactory.h>
|
#include <fairmq/TransportFactory.h>
|
||||||
#include <fairmq/MemoryResources.h>
|
#include <fairmq/MemoryResources.h>
|
||||||
|
|
||||||
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t alignment)
|
void *fair::mq::ChannelResource::do_allocate(std::size_t bytes, std::size_t alignment)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
* Copyright (C) 2018 CERN and copyright holders of ALICE O2 *
|
||||||
* Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2018-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <boost/container/container_fwd.hpp>
|
#include <boost/container/container_fwd.hpp>
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
#include <boost/container/pmr/memory_resource.hpp>
|
#include <memory_resource>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fairmq/Message.h>
|
#include <fairmq/Message.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -27,7 +27,7 @@ namespace fair::mq {
|
||||||
|
|
||||||
class TransportFactory;
|
class TransportFactory;
|
||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
namespace pmr = boost::container::pmr;
|
namespace pmr = std::pmr;
|
||||||
|
|
||||||
/// All FairMQ related memory resources need to inherit from this interface
|
/// All FairMQ related memory resources need to inherit from this interface
|
||||||
/// class for the
|
/// class for the
|
||||||
|
@ -103,9 +103,7 @@ class ChannelResource : public MemoryResource
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// using FairMQMemoryResource [[deprecated("Use fair::mq::MemoryResource")]] =
|
using FairMQMemoryResource [[deprecated("Use fair::mq::MemoryResource")]] = MemoryResource;
|
||||||
// MemoryResource;
|
|
||||||
using FairMQMemoryResource = MemoryResource;
|
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2021-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
#define FAIR_MQ_MESSAGE_H
|
#define FAIR_MQ_MESSAGE_H
|
||||||
|
|
||||||
#include <cstddef> // for size_t
|
#include <cstddef> // for size_t
|
||||||
#include <fairmq/Transports.h>
|
#include <fairmq/TransportEnum.h>
|
||||||
#include <memory> // unique_ptr
|
#include <memory> // unique_ptr
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ struct Message
|
||||||
virtual void* GetData() const = 0;
|
virtual void* GetData() const = 0;
|
||||||
virtual size_t GetSize() const = 0;
|
virtual size_t GetSize() const = 0;
|
||||||
|
|
||||||
virtual bool SetUsedSize(size_t size) = 0;
|
virtual bool SetUsedSize(size_t size, Alignment alignment = Alignment{0}) = 0;
|
||||||
|
|
||||||
virtual Transport GetType() const = 0;
|
virtual Transport GetType() const = 0;
|
||||||
TransportFactory* GetTransport() { return fTransport; }
|
TransportFactory* GetTransport() { return fTransport; }
|
||||||
|
@ -76,13 +76,15 @@ struct MessageBadAlloc : std::runtime_error
|
||||||
using std::runtime_error::runtime_error;
|
using std::runtime_error::runtime_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RefCountBadAlloc : std::runtime_error
|
||||||
|
{
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using fairmq_free_fn [[deprecated("Use fair::mq::FreeFn")]] = fair::mq::FreeFn;
|
using fairmq_free_fn [[deprecated("Use fair::mq::FreeFn")]] = fair::mq::FreeFn;
|
||||||
// using FairMQMessage [[deprecated("Use fair::mq::Message")]] = fair::mq::Message;
|
using FairMQMessage [[deprecated("Use fair::mq::Message")]] = fair::mq::Message;
|
||||||
// using FairMQMessagePtr [[deprecated("Use fair::mq::MessagePtr")]] = fair::mq::MessagePtr;
|
using FairMQMessagePtr [[deprecated("Use fair::mq::MessagePtr")]] = fair::mq::MessagePtr;
|
||||||
using fairmq_free_fn = fair::mq::FreeFn;
|
|
||||||
using FairMQMessage = fair::mq::Message;
|
|
||||||
using FairMQMessagePtr = fair::mq::MessagePtr;
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_MESSAGE_H
|
#endif // FAIR_MQ_MESSAGE_H
|
||||||
|
|
101
fairmq/Parts.h
101
fairmq/Parts.h
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -9,84 +9,89 @@
|
||||||
#ifndef FAIR_MQ_PARTS_H
|
#ifndef FAIR_MQ_PARTS_H
|
||||||
#define FAIR_MQ_PARTS_H
|
#define FAIR_MQ_PARTS_H
|
||||||
|
|
||||||
#include <fairmq/Message.h>
|
#include <algorithm> // std::move
|
||||||
#include <memory> // unique_ptr
|
#include <fairmq/Message.h> // fair::mq::MessagePtr
|
||||||
#include <vector>
|
#include <iterator> // std::back_inserter
|
||||||
|
#include <utility> // std::move, std::forward
|
||||||
|
#include <vector> // std::vector
|
||||||
|
|
||||||
namespace fair::mq {
|
namespace fair::mq {
|
||||||
|
|
||||||
/// fair::mq::Parts is a lightweight convenience wrapper around a vector of unique pointers to
|
/// fair::mq::Parts is a lightweight move-only convenience wrapper around a vector of unique pointers to
|
||||||
/// Message, used for sending multi-part messages
|
/// Message, used for sending multi-part messages
|
||||||
class Parts
|
struct Parts
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
using container = std::vector<MessagePtr>;
|
using container = std::vector<MessagePtr>;
|
||||||
|
using size_type = container::size_type;
|
||||||
|
using reference = container::reference;
|
||||||
|
using const_reference = container::const_reference;
|
||||||
|
using iterator = container::iterator;
|
||||||
|
using const_iterator = container::const_iterator;
|
||||||
|
|
||||||
public:
|
Parts() noexcept(noexcept(container())) = default;
|
||||||
Parts() = default;
|
|
||||||
Parts(const Parts&) = delete;
|
Parts(const Parts&) = delete;
|
||||||
Parts(Parts&&) = default;
|
|
||||||
template<typename... Ts>
|
|
||||||
Parts(Ts&&... messages) { AddPart(std::forward<Ts>(messages)...); }
|
|
||||||
Parts& operator=(const Parts&) = delete;
|
Parts& operator=(const Parts&) = delete;
|
||||||
|
Parts(Parts&&) = default;
|
||||||
Parts& operator=(Parts&&) = default;
|
Parts& operator=(Parts&&) = default;
|
||||||
~Parts() = default;
|
~Parts() = default;
|
||||||
|
|
||||||
/// Adds part (Message) to the container
|
template<typename... Ps>
|
||||||
/// @param msg message pointer (for example created with NewMessage() method of Device)
|
Parts(Ps&&... parts)
|
||||||
|
{
|
||||||
|
fParts.reserve(sizeof...(Ps));
|
||||||
|
AddPart(std::forward<Ps>(parts)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[deprecated("Avoid owning raw pointer args, use AddPart(MessagePtr) instead.")]]
|
||||||
void AddPart(Message* msg) { fParts.push_back(MessagePtr(msg)); }
|
void AddPart(Message* msg) { fParts.push_back(MessagePtr(msg)); }
|
||||||
|
void AddPart(MessagePtr msg) { fParts.push_back(std::move(msg)); }
|
||||||
|
|
||||||
/// Adds part to the container (move)
|
|
||||||
/// @param msg unique pointer to Message
|
|
||||||
/// rvalue ref (move required when passing argument)
|
|
||||||
void AddPart(MessagePtr&& msg) { fParts.push_back(std::move(msg)); }
|
|
||||||
|
|
||||||
/// Add variable list of parts to the container (move)
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
void AddPart(MessagePtr&& first, Ts&&... remaining)
|
void AddPart(MessagePtr first, Ts&&... remaining)
|
||||||
{
|
{
|
||||||
AddPart(std::move(first));
|
AddPart(std::move(first));
|
||||||
AddPart(std::forward<Ts>(remaining)...);
|
AddPart(std::forward<Ts>(remaining)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add content of another object by move
|
void AddPart(Parts parts)
|
||||||
void AddPart(Parts&& other)
|
|
||||||
{
|
{
|
||||||
container parts = std::move(other.fParts);
|
if (fParts.empty()) {
|
||||||
for (auto& part : parts) {
|
fParts = std::move(parts.fParts);
|
||||||
fParts.push_back(std::move(part));
|
} else {
|
||||||
|
fParts.reserve(parts.Size() + fParts.size());
|
||||||
|
std::move(std::begin(parts), std::end(parts), std::back_inserter(fParts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get reference to part in the container at index (without bounds check)
|
Message& operator[](size_type index) { return *(fParts[index]); }
|
||||||
/// @param index container index
|
Message const& operator[](size_type index) const { return *(fParts[index]); }
|
||||||
Message& operator[](const int index) { return *(fParts[index]); }
|
// TODO: For consistency with the STL interfaces, operator[] should not dereference,
|
||||||
|
// but I have no good idea how to fix this.
|
||||||
|
// reference operator[](size_type index) { return fParts[index]; }
|
||||||
|
// const_reference operator[](size_type index) const { return fParts[index]; }
|
||||||
|
|
||||||
/// Get reference to unique pointer to part in the container at index (with bounds check)
|
[[deprecated("Redundant, dereference at call site e.g. '*(parts.At(index))' instead.")]]
|
||||||
/// @param index container index
|
Message& AtRef(size_type index) { return *(fParts.at(index)); }
|
||||||
MessagePtr& At(const int index) { return fParts.at(index); }
|
reference At(size_type index) { return fParts.at(index); }
|
||||||
|
const_reference At(size_type index) const { return fParts.at(index); }
|
||||||
|
|
||||||
// ref version
|
size_type Size() const noexcept { return fParts.size(); }
|
||||||
Message& AtRef(const int index) { return *(fParts.at(index)); }
|
bool Empty() const noexcept { return fParts.empty(); }
|
||||||
|
void Clear() noexcept { fParts.clear(); }
|
||||||
|
|
||||||
/// Get number of parts in the container
|
// range access
|
||||||
/// @return number of parts in the container
|
iterator begin() noexcept { return fParts.begin(); }
|
||||||
int Size() const { return fParts.size(); }
|
const_iterator begin() const noexcept { return fParts.begin(); }
|
||||||
|
const_iterator cbegin() const noexcept { return fParts.cbegin(); }
|
||||||
|
iterator end() noexcept { return fParts.end(); }
|
||||||
|
const_iterator end() const noexcept { return fParts.end(); }
|
||||||
|
const_iterator cend() const noexcept { return fParts.cend(); }
|
||||||
|
|
||||||
container fParts;
|
container fParts{};
|
||||||
|
|
||||||
// forward container iterators
|
|
||||||
using iterator = container::iterator;
|
|
||||||
using const_iterator = container::const_iterator;
|
|
||||||
auto begin() -> decltype(fParts.begin()) { return fParts.begin(); }
|
|
||||||
auto end() -> decltype(fParts.end()) { return fParts.end(); }
|
|
||||||
auto cbegin() -> decltype(fParts.cbegin()) { return fParts.cbegin(); }
|
|
||||||
auto cend() -> decltype(fParts.cend()) { return fParts.cend(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using FairMQParts [[deprecated("Use fair::mq::Parts")]] = fair::mq::Parts;
|
using FairMQParts [[deprecated("Use fair::mq::Parts")]] = fair::mq::Parts;
|
||||||
using FairMQParts = fair::mq::Parts;
|
|
||||||
|
|
||||||
#endif /* FAIR_MQ_PARTS_H */
|
#endif /* FAIR_MQ_PARTS_H */
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include <fairmq/plugins/Builtin.h>
|
|
||||||
#include <fairmq/PluginManager.h>
|
|
||||||
#include <fairmq/tools/Strings.h>
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <fairlogger/Logger.h>
|
||||||
|
#include <fairmq/PluginManager.h>
|
||||||
|
#include <fairmq/plugins/Builtin.h>
|
||||||
|
#include <fairmq/tools/Strings.h>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -18,22 +19,22 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using fair::mq::Plugin;
|
||||||
using fair::mq::tools::ToString;
|
using fair::mq::tools::ToString;
|
||||||
using fair::mq::tools::ToStrVector;
|
using fair::mq::tools::ToStrVector;
|
||||||
using fair::mq::Plugin;
|
|
||||||
namespace fs = boost::filesystem;
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
namespace dll = boost::dll;
|
namespace dll = boost::dll;
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
|
|
||||||
const std::string fair::mq::PluginManager::fgkLibPrefix = "FairMQPlugin_";
|
const std::string fair::mq::PluginManager::fgkLibPrefix = "fairmq-plugin-";
|
||||||
|
const std::string fair::mq::PluginManager::fgkLibPrefixAlt = "FairMQPlugin_";
|
||||||
|
|
||||||
std::vector<boost::dll::shared_library> fair::mq::PluginManager::fgDLLKeepAlive = std::vector<boost::dll::shared_library>();
|
std::vector<boost::dll::shared_library> fair::mq::PluginManager::fgDLLKeepAlive =
|
||||||
|
std::vector<boost::dll::shared_library>();
|
||||||
|
|
||||||
fair::mq::PluginManager::PluginManager()
|
fair::mq::PluginManager::PluginManager()
|
||||||
: fPluginServices()
|
: fPluginServices()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
fair::mq::PluginManager::PluginManager(const vector<string>& args)
|
fair::mq::PluginManager::PluginManager(const vector<string>& args)
|
||||||
: fPluginServices()
|
: fPluginServices()
|
||||||
|
@ -46,7 +47,8 @@ fair::mq::PluginManager::PluginManager(const vector<string>& args)
|
||||||
po::store(parsed, vm);
|
po::store(parsed, vm);
|
||||||
po::notify(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())};
|
throw ProgramOptionsParseError{ToString(
|
||||||
|
"Error occured while parsing the 'Plugin Manager' program options: ", e.what())};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process plugin search paths
|
// Process plugin search paths
|
||||||
|
@ -55,24 +57,38 @@ fair::mq::PluginManager::PluginManager(const vector<string>& args)
|
||||||
auto searchPaths = vector<fs::path>{};
|
auto searchPaths = vector<fs::path>{};
|
||||||
if (vm.count("plugin-search-path")) {
|
if (vm.count("plugin-search-path")) {
|
||||||
for (const auto& path : vm["plugin-search-path"].as<vector<string>>()) {
|
for (const auto& path : vm["plugin-search-path"].as<vector<string>>()) {
|
||||||
if (path.substr(0, 1) == "<") { prepend.emplace_back(path.substr(1)); }
|
if (path.substr(0, 1) == "<") {
|
||||||
else if (path.substr(0, 1) == ">") { append.emplace_back(path.substr(1)); }
|
prepend.emplace_back(path.substr(1));
|
||||||
else { searchPaths.emplace_back(path); }
|
} else if (path.substr(0, 1) == ">") {
|
||||||
|
append.emplace_back(path.substr(1));
|
||||||
|
} else {
|
||||||
|
searchPaths.emplace_back(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set supplied options
|
// Set supplied options
|
||||||
SetSearchPaths(searchPaths);
|
SetSearchPaths(searchPaths);
|
||||||
for(const auto& path : prepend) { PrependSearchPath(path); }
|
for (const auto& path : prepend) {
|
||||||
for(const auto& path : append) { AppendSearchPath(path); }
|
PrependSearchPath(path);
|
||||||
if (vm.count("plugin")) { LoadPlugins(vm["plugin"].as<vector<string>>()); }
|
}
|
||||||
|
for (const auto& path : append) {
|
||||||
|
AppendSearchPath(path);
|
||||||
|
}
|
||||||
|
if (vm.count("plugin")) {
|
||||||
|
LoadPlugins(vm["plugin"].as<vector<string>>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fair::mq::PluginManager::ValidateSearchPath(const fs::path& path) -> void
|
auto fair::mq::PluginManager::ValidateSearchPath(const fs::path& path) -> void
|
||||||
{
|
{
|
||||||
if (path.empty()) throw BadSearchPath{"Specified path is empty."};
|
if (path.empty()) {
|
||||||
|
throw BadSearchPath{"Specified path is empty."};
|
||||||
|
}
|
||||||
// we ignore non-existing search paths
|
// we ignore non-existing search paths
|
||||||
if (fs::exists(path) && !fs::is_directory(path)) throw BadSearchPath{ToString(path, " is not a directory.")};
|
if (fs::exists(path) && !fs::is_directory(path)) {
|
||||||
|
throw BadSearchPath{ToString(path, " is not a directory.")};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fair::mq::PluginManager::SetSearchPaths(const vector<fs::path>& searchPaths) -> void
|
auto fair::mq::PluginManager::SetSearchPaths(const vector<fs::path>& searchPaths) -> void
|
||||||
|
@ -96,17 +112,24 @@ auto fair::mq::PluginManager::PrependSearchPath(const fs::path& path) -> void
|
||||||
auto fair::mq::PluginManager::ProgramOptions() -> po::options_description
|
auto fair::mq::PluginManager::ProgramOptions() -> po::options_description
|
||||||
{
|
{
|
||||||
auto plugin_options = po::options_description{"Plugin Manager"};
|
auto plugin_options = po::options_description{"Plugin Manager"};
|
||||||
plugin_options.add_options()
|
plugin_options.add_options()("plugin-search-path,S",
|
||||||
("plugin-search-path,S", po::value<vector<string>>()->multitoken(), "List of plugin search paths.\n\n"
|
po::value<vector<string>>()->multitoken(),
|
||||||
|
"List of plugin search paths.\n\n"
|
||||||
"* Override default search path, e.g.\n"
|
"* Override default search path, e.g.\n"
|
||||||
" -S /home/user/lib /lib\n"
|
" -S /home/user/lib /lib\n"
|
||||||
"* Append(>) or prepend(<) to default search path, e.g.\n"
|
"* Append(>) or prepend(<) to default search path, e.g.\n"
|
||||||
" -S >/lib </home/user/lib\n"
|
" -S >/lib </home/user/lib\n"
|
||||||
"* If you mix the overriding and appending/prepending syntaxes, the overriding paths act as default search path, e.g.\n"
|
"* If you mix the overriding and appending/prepending syntaxes, "
|
||||||
" -S /usr/lib >/lib </home/user/lib /usr/local/lib results in /home/user/lib,/usr/local/lib,/usr/lib/,/lib\n"
|
"the overriding paths act as default search path, e.g.\n"
|
||||||
"If nothing is found, the default dynamic library lookup is performed, see man ld.so(8) for details.")
|
" -S /usr/lib >/lib </home/user/lib /usr/local/lib results in "
|
||||||
("plugin,P", po::value<vector<string>>(), "List of plugin names to load in order,"
|
"/home/user/lib,/usr/local/lib,/usr/lib/,/lib\n"
|
||||||
"e.g. if the file is called 'libFairMQPlugin_example.so', just list 'example' or 'd:example' here."
|
"If nothing is found, the default dynamic library lookup is "
|
||||||
|
"performed, see man ld.so(8) for details.")(
|
||||||
|
"plugin,P",
|
||||||
|
po::value<vector<string>>(),
|
||||||
|
"List of plugin names to load in order,"
|
||||||
|
"e.g. if the file is called 'libfairmq-plugin-example.so', just list 'example' or "
|
||||||
|
"'d:example' here."
|
||||||
"To load a prelinked plugin, list 'p:example' here.");
|
"To load a prelinked plugin, list 'p:example' here.");
|
||||||
|
|
||||||
return plugin_options;
|
return plugin_options;
|
||||||
|
@ -114,13 +137,13 @@ auto fair::mq::PluginManager::ProgramOptions() -> po::options_description
|
||||||
|
|
||||||
auto fair::mq::PluginManager::LoadPlugin(const string& pluginName) -> void
|
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
|
// Mechanism A: prelinked dynamic
|
||||||
LoadPluginPrelinkedDynamic(pluginName.substr(2));
|
LoadPluginPrelinkedDynamic(pluginName.substr(2));
|
||||||
} else if (pluginName.substr(0,2) == "d:") {
|
} else if (pluginName.substr(0, 2) == "d:") {
|
||||||
// Mechanism B: dynamic
|
// Mechanism B: dynamic
|
||||||
LoadPluginDynamic(pluginName.substr(2));
|
LoadPluginDynamic(pluginName.substr(2));
|
||||||
} else if (pluginName.substr(0,2) == "s:") {
|
} else if (pluginName.substr(0, 2) == "s:") {
|
||||||
// Mechanism C: static (builtin)
|
// Mechanism C: static (builtin)
|
||||||
LoadPluginStatic(pluginName.substr(2));
|
LoadPluginStatic(pluginName.substr(2));
|
||||||
} else {
|
} else {
|
||||||
|
@ -137,33 +160,54 @@ auto fair::mq::PluginManager::LoadPluginPrelinkedDynamic(const string& pluginNam
|
||||||
LoadSymbols(pluginName, dll::program_location());
|
LoadSymbols(pluginName, dll::program_location());
|
||||||
fPluginOrder.push_back(pluginName);
|
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()));
|
throw PluginLoadError(
|
||||||
|
ToString("An error occurred while loading prelinked dynamic plugin ",
|
||||||
|
pluginName,
|
||||||
|
": ",
|
||||||
|
e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto fair::mq::PluginManager::SearchPluginFile(const string& pluginName) const
|
||||||
|
-> fs::path
|
||||||
|
{
|
||||||
|
for (const auto& searchPath : SearchPaths()) {
|
||||||
|
for (const auto& libPrefix : {fgkLibPrefix, fgkLibPrefixAlt}) {
|
||||||
|
auto const file =
|
||||||
|
searchPath
|
||||||
|
/ ToString("lib",
|
||||||
|
libPrefix,
|
||||||
|
pluginName,
|
||||||
|
boost::dll::detail::shared_library_impl::suffix().native());
|
||||||
|
auto const found = fs::exists(file);
|
||||||
|
if (found) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw PluginNotFound(ToString("Could not find plugin file for plugin ", pluginName));
|
||||||
|
}
|
||||||
|
|
||||||
auto fair::mq::PluginManager::LoadPluginDynamic(const string& pluginName) -> void
|
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()) {
|
return; // already loaded, nothing to do
|
||||||
auto success = false;
|
|
||||||
for (const auto& searchPath : SearchPaths()) {
|
|
||||||
try {
|
|
||||||
LoadSymbols(pluginName, searchPath / ToString(LibPrefix(), pluginName),
|
|
||||||
dll::load_mode::append_decorations | dll::load_mode::rtld_global);
|
|
||||||
fPluginOrder.push_back(pluginName);
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} catch (boost::system::system_error& e) {
|
|
||||||
if (string{e.what()}.find("No such file or directory") == string::npos) {
|
|
||||||
throw PluginLoadError(
|
|
||||||
ToString("An error occurred while loading dynamic plugin ",
|
|
||||||
pluginName, ": ", e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
// Search in configured search path
|
||||||
|
try {
|
||||||
|
LoadSymbols(pluginName, SearchPluginFile(pluginName), dll::load_mode::rtld_global);
|
||||||
|
fPluginOrder.push_back(pluginName);
|
||||||
|
return;
|
||||||
|
} catch (PluginNotFound& e) {
|
||||||
|
// ignore
|
||||||
|
} catch (boost::system::system_error& e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search with system logic (including RPATH, LD_LIBRARY_PATH)
|
||||||
|
for (const auto& libPrefix : {fgkLibPrefix, fgkLibPrefixAlt}) {
|
||||||
try {
|
try {
|
||||||
// LoadSymbols(pluginName,
|
// LoadSymbols(pluginName,
|
||||||
// ToString(LibPrefix(), pluginName),
|
// ToString(LibPrefix(), pluginName),
|
||||||
|
@ -171,18 +215,21 @@ auto fair::mq::PluginManager::LoadPluginDynamic(const string& pluginName) -> voi
|
||||||
// Not sure, why the above does not work. Workaround for now:
|
// Not sure, why the above does not work. Workaround for now:
|
||||||
LoadSymbols(pluginName,
|
LoadSymbols(pluginName,
|
||||||
ToString("lib",
|
ToString("lib",
|
||||||
LibPrefix(),
|
libPrefix,
|
||||||
pluginName,
|
pluginName,
|
||||||
boost::dll::detail::shared_library_impl::suffix().native()),
|
boost::dll::detail::shared_library_impl::suffix().native()),
|
||||||
dll::load_mode::search_system_folders | dll::load_mode::rtld_global);
|
dll::load_mode::search_system_folders | dll::load_mode::rtld_global);
|
||||||
fPluginOrder.push_back(pluginName);
|
fPluginOrder.push_back(pluginName);
|
||||||
|
return;
|
||||||
} catch (boost::system::system_error& e) {
|
} catch (boost::system::system_error& e) {
|
||||||
throw PluginLoadError(
|
// ignore
|
||||||
ToString("An error occurred while loading dynamic plugin ",
|
|
||||||
pluginName, ": ", e.what()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw PluginLoadError(ToString("Could not load dynamic plugin ",
|
||||||
|
pluginName,
|
||||||
|
" from configured search paths (-S) nor with ",
|
||||||
|
"system lookup (system libdirs, RUNPATH, $LD_LIBRARY_PATH)."));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
|
auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
|
||||||
|
@ -192,20 +239,25 @@ auto fair::mq::PluginManager::LoadPluginStatic(const string& pluginName) -> void
|
||||||
try {
|
try {
|
||||||
if ("control" == pluginName) {
|
if ("control" == pluginName) {
|
||||||
try {
|
try {
|
||||||
fPluginProgOptions.insert({pluginName, plugins::ControlPluginProgramOptions().value()});
|
fPluginProgOptions.insert(
|
||||||
|
{pluginName, plugins::ControlPluginProgramOptions().value()});
|
||||||
|
} catch (const boost::bad_optional_access&) {
|
||||||
|
/* just ignore, if no prog options are declared */
|
||||||
}
|
}
|
||||||
catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
|
|
||||||
} else if ("config" == pluginName) {
|
} else if ("config" == pluginName) {
|
||||||
try {
|
try {
|
||||||
fPluginProgOptions.insert({pluginName, plugins::ConfigPluginProgramOptions().value()});
|
fPluginProgOptions.insert(
|
||||||
|
{pluginName, plugins::ConfigPluginProgramOptions().value()});
|
||||||
|
} catch (const boost::bad_optional_access&) {
|
||||||
|
/* just ignore, if no prog options are declared */
|
||||||
}
|
}
|
||||||
catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
|
|
||||||
} else {
|
} else {
|
||||||
LoadSymbols(pluginName, dll::program_location());
|
LoadSymbols(pluginName, dll::program_location());
|
||||||
}
|
}
|
||||||
fPluginOrder.push_back(pluginName);
|
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()));
|
throw PluginLoadError(ToString(
|
||||||
|
"An error occurred while loading static plugin ", pluginName, ": ", e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,11 +277,12 @@ auto fair::mq::PluginManager::InstantiatePlugin(const string& pluginName) -> voi
|
||||||
|
|
||||||
auto fair::mq::PluginManager::InstantiatePlugins() -> void
|
auto fair::mq::PluginManager::InstantiatePlugins() -> void
|
||||||
{
|
{
|
||||||
for(const auto& pluginName : fPluginOrder) {
|
for (const auto& pluginName : fPluginOrder) {
|
||||||
try {
|
try {
|
||||||
InstantiatePlugin(pluginName);
|
InstantiatePlugin(pluginName);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
throw PluginInstantiationError(ToString("An error occurred while instantiating plugin ", pluginName, ": ", e.what()));
|
throw PluginInstantiationError(ToString(
|
||||||
|
"An error occurred while instantiating plugin ", pluginName, ": ", e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -13,9 +13,16 @@
|
||||||
#include <fairmq/PluginServices.h>
|
#include <fairmq/PluginServices.h>
|
||||||
#include <fairmq/tools/Strings.h>
|
#include <fairmq/tools/Strings.h>
|
||||||
|
|
||||||
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
#else
|
||||||
#define BOOST_FILESYSTEM_VERSION 3
|
#define BOOST_FILESYSTEM_VERSION 3
|
||||||
#define BOOST_FILESYSTEM_NO_DEPRECATED
|
#define BOOST_FILESYSTEM_NO_DEPRECATED
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
namespace fs = ::boost::filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/dll/import.hpp>
|
#include <boost/dll/import.hpp>
|
||||||
|
@ -60,12 +67,14 @@ class PluginManager
|
||||||
LOG(debug) << "Shutting down Plugin Manager";
|
LOG(debug) << "Shutting down Plugin Manager";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
|
auto SetSearchPaths(const std::vector<fs::path>&) -> void;
|
||||||
auto AppendSearchPath(const boost::filesystem::path&) -> void;
|
auto AppendSearchPath(const fs::path&) -> void;
|
||||||
auto PrependSearchPath(const boost::filesystem::path&) -> void;
|
auto PrependSearchPath(const fs::path&) -> void;
|
||||||
auto SearchPaths() const -> const std::vector<boost::filesystem::path>& { return fSearchPaths; }
|
auto SearchPaths() const -> const std::vector<fs::path>& { return fSearchPaths; }
|
||||||
struct BadSearchPath : std::invalid_argument { using std::invalid_argument::invalid_argument; };
|
struct BadSearchPath : std::invalid_argument { using std::invalid_argument::invalid_argument; };
|
||||||
|
|
||||||
|
auto SearchPluginFile(const std::string&) const -> fs::path;
|
||||||
|
struct PluginNotFound : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
auto LoadPlugin(const std::string& pluginName) -> void;
|
auto LoadPlugin(const std::string& pluginName) -> void;
|
||||||
auto LoadPlugins(const std::vector<std::string>& pluginNames) -> void { for(const auto& pluginName : pluginNames) { LoadPlugin(pluginName); } }
|
auto LoadPlugins(const std::vector<std::string>& pluginNames) -> void { for(const auto& pluginName : pluginNames) { LoadPlugin(pluginName); } }
|
||||||
struct PluginLoadError : std::runtime_error { using std::runtime_error::runtime_error; };
|
struct PluginLoadError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
@ -86,18 +95,33 @@ class PluginManager
|
||||||
auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
|
auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static auto ValidateSearchPath(const boost::filesystem::path&) -> void;
|
static auto ValidateSearchPath(const fs::path&) -> void;
|
||||||
|
|
||||||
auto LoadPluginPrelinkedDynamic(const std::string& pluginName) -> void;
|
auto LoadPluginPrelinkedDynamic(const std::string& pluginName) -> void;
|
||||||
auto LoadPluginDynamic(const std::string& pluginName) -> void;
|
auto LoadPluginDynamic(const std::string& pluginName) -> void;
|
||||||
auto LoadPluginStatic(const std::string& pluginName) -> void;
|
auto LoadPluginStatic(const std::string& pluginName) -> void;
|
||||||
template<typename... Args>
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
auto LoadSymbols(const std::string& pluginName, Args&&... args) -> void
|
template<typename T>
|
||||||
|
static auto AdaptPathType(T&& path)
|
||||||
|
{
|
||||||
|
if constexpr(std::is_same_v<T, std::filesystem::path>) {
|
||||||
|
return boost::filesystem::path(std::forward<T>(path));
|
||||||
|
} else {
|
||||||
|
return std::forward<T>(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
template<typename FirstArg, typename... Args>
|
||||||
|
auto LoadSymbols(const std::string& pluginName, FirstArg&& farg, Args&&... args) -> void
|
||||||
{
|
{
|
||||||
using namespace boost::dll;
|
using namespace boost::dll;
|
||||||
using fair::mq::tools::ToString;
|
using fair::mq::tools::ToString;
|
||||||
|
|
||||||
auto lib = shared_library{std::forward<Args>(args)...};
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
|
auto lib = shared_library{AdaptPathType(std::forward<FirstArg>(farg)), std::forward<Args>(args)...};
|
||||||
|
#else
|
||||||
|
auto lib = shared_library{std::forward<FirstArg>(farg), std::forward<Args>(args)...};
|
||||||
|
#endif
|
||||||
fgDLLKeepAlive.push_back(lib);
|
fgDLLKeepAlive.push_back(lib);
|
||||||
|
|
||||||
fPluginFactories[pluginName] = import_alias<PluginFactory>(
|
fPluginFactories[pluginName] = import_alias<PluginFactory>(
|
||||||
|
@ -118,7 +142,8 @@ class PluginManager
|
||||||
auto InstantiatePlugin(const std::string& pluginName) -> void;
|
auto InstantiatePlugin(const std::string& pluginName) -> void;
|
||||||
|
|
||||||
static const std::string fgkLibPrefix;
|
static const std::string fgkLibPrefix;
|
||||||
std::vector<boost::filesystem::path> fSearchPaths;
|
static const std::string fgkLibPrefixAlt;
|
||||||
|
std::vector<fs::path> fSearchPaths;
|
||||||
static std::vector<boost::dll::shared_library> fgDLLKeepAlive; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
static std::vector<boost::dll::shared_library> fgDLLKeepAlive; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
std::map<std::string, std::function<PluginFactory>> fPluginFactories;
|
std::map<std::string, std::function<PluginFactory>> fPluginFactories;
|
||||||
std::unique_ptr<PluginServices> fPluginServices;
|
std::unique_ptr<PluginServices> fPluginServices;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2021-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -41,9 +41,7 @@ struct PollerError : std::runtime_error
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using FairMQPoller [[deprecated("Use fair::mq::Poller")]] = fair::mq::Poller;
|
using FairMQPoller [[deprecated("Use fair::mq::Poller")]] = fair::mq::Poller;
|
||||||
// using FairMQPollerPtr [[deprecated("Use fair::mq::PollerPtr")]] = fair::mq::PollerPtr;
|
using FairMQPollerPtr [[deprecated("Use fair::mq::PollerPtr")]] = fair::mq::PollerPtr;
|
||||||
using FairMQPoller = fair::mq::Poller;
|
|
||||||
using FairMQPollerPtr = fair::mq::PollerPtr;
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_POLLER_H
|
#endif // FAIR_MQ_POLLER_H
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -12,9 +12,7 @@
|
||||||
* Created on March 11, 2015, 10:20 PM
|
* Created on March 11, 2015, 10:20 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FairMQLogger.h"
|
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
|
|
||||||
#include <fairmq/tools/Strings.h>
|
#include <fairmq/tools/Strings.h>
|
||||||
|
|
||||||
#include <boost/any.hpp>
|
#include <boost/any.hpp>
|
||||||
|
@ -22,6 +20,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <fairlogger/Logger.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -449,3 +448,6 @@ void ProgOptions::PrintOptionsRaw() const
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
|
template void fair::mq::ProgOptions::SetProperty<std::string>(const std::string& key, std::string val);
|
||||||
|
template void fair::mq::ProgOptions::SetProperty<int>(const std::string& key, int val);
|
||||||
|
|
|
@ -129,17 +129,7 @@ class ProgOptions
|
||||||
/// @param key
|
/// @param key
|
||||||
/// @param val
|
/// @param val
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void SetProperty(const std::string& key, T val)
|
void SetProperty(const std::string& key, T val);
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(fMtx);
|
|
||||||
|
|
||||||
SetVarMapValue<typename std::decay<T>::type>(key, val);
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
|
|
||||||
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetPropertyAsString(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Updates an existing config property (or fails if it doesn't exist)
|
/// @brief Updates an existing config property (or fails if it doesn't exist)
|
||||||
/// @param key
|
/// @param key
|
||||||
|
@ -275,5 +265,20 @@ class ProgOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
template <typename T>
|
||||||
|
void fair::mq::ProgOptions::SetProperty(const std::string& key, T val)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(fMtx);
|
||||||
|
|
||||||
|
SetVarMapValue<typename std::decay<T>::type>(key, val);
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
|
||||||
|
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetPropertyAsString(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern template void fair::mq::ProgOptions::SetProperty<int>(const std::string& key, int val);
|
||||||
|
extern template void fair::mq::ProgOptions::SetProperty<std::string>(const std::string& key, std::string val);
|
||||||
|
|
||||||
#endif /* FAIR_MQ_PROGOPTIONS_H */
|
#endif /* FAIR_MQ_PROGOPTIONS_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2019-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -13,7 +13,6 @@ namespace fair::mq {
|
||||||
class ProgOptions;
|
class ProgOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// using FairMQProgOptions [[deprecated("Use fair::mq::ProgOptions")]] = fair::mq::ProgOptions;
|
using FairMQProgOptions [[deprecated("Use fair::mq::ProgOptions")]] = fair::mq::ProgOptions;
|
||||||
using FairMQProgOptions = fair::mq::ProgOptions;
|
|
||||||
|
|
||||||
#endif /* FAIR_MQ_PROGOPTIONSFWD_H */
|
#endif /* FAIR_MQ_PROGOPTIONSFWD_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -8,7 +8,15 @@
|
||||||
|
|
||||||
#include <fairmq/Properties.h>
|
#include <fairmq/Properties.h>
|
||||||
|
|
||||||
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
#else
|
||||||
|
#define BOOST_FILESYSTEM_VERSION 3
|
||||||
|
#define BOOST_FILESYSTEM_NO_DEPRECATED
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
namespace fs = ::boost::filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using boost::any_cast;
|
using boost::any_cast;
|
||||||
|
@ -84,7 +92,12 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
|
||||||
{ type_index(typeid(long double)), [](const Property& p) { return getStringPair<long double>(p, "long double"); } },
|
{ type_index(typeid(long double)), [](const Property& p) { return getStringPair<long double>(p, "long double"); } },
|
||||||
{ type_index(typeid(bool)), [](const Property& p) { stringstream ss; ss << boolalpha << any_cast<bool>(p); return pair<string, string>{ ss.str(), "bool" }; } },
|
{ type_index(typeid(bool)), [](const Property& p) { stringstream ss; ss << boolalpha << any_cast<bool>(p); return pair<string, string>{ ss.str(), "bool" }; } },
|
||||||
{ type_index(typeid(vector<bool>)), [](const Property& p) { stringstream ss; ss << boolalpha << any_cast<vector<bool>>(p); return pair<string, string>{ ss.str(), "vector<bool>>" }; } },
|
{ type_index(typeid(vector<bool>)), [](const Property& p) { stringstream ss; ss << boolalpha << any_cast<vector<bool>>(p); return pair<string, string>{ ss.str(), "vector<bool>>" }; } },
|
||||||
{ type_index(typeid(boost::filesystem::path)), [](const Property& p) { return getStringPair<boost::filesystem::path>(p, "boost::filesystem::path"); } },
|
{ type_index(typeid(fs::path)), [](const Property& p) { return getStringPair<fs::path>(p,
|
||||||
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
|
"std::filesystem::path"); } },
|
||||||
|
#else
|
||||||
|
"boost::filesystem::path"); } },
|
||||||
|
#endif
|
||||||
{ type_index(typeid(vector<char>)), [](const Property& p) { return getStringPair<vector<char>>(p, "vector<char>"); } },
|
{ type_index(typeid(vector<char>)), [](const Property& p) { return getStringPair<vector<char>>(p, "vector<char>"); } },
|
||||||
{ type_index(typeid(vector<signed char>)), [](const Property& p) { return getStringPair<vector<signed char>>(p, "vector<signed char>"); } },
|
{ type_index(typeid(vector<signed char>)), [](const Property& p) { return getStringPair<vector<signed char>>(p, "vector<signed char>"); } },
|
||||||
{ type_index(typeid(vector<unsigned char>)), [](const Property& p) { return getStringPair<vector<unsigned char>>(p, "vector<unsigned char>"); } },
|
{ type_index(typeid(vector<unsigned char>)), [](const Property& p) { return getStringPair<vector<unsigned char>>(p, "vector<unsigned char>"); } },
|
||||||
|
@ -100,7 +113,12 @@ unordered_map<type_index, function<pair<string, string>(const Property&)>> Prope
|
||||||
{ type_index(typeid(vector<float>)), [](const Property& p) { return getStringPair<vector<float>>(p, "vector<float>"); } },
|
{ type_index(typeid(vector<float>)), [](const Property& p) { return getStringPair<vector<float>>(p, "vector<float>"); } },
|
||||||
{ type_index(typeid(vector<double>)), [](const Property& p) { return getStringPair<vector<double>>(p, "vector<double>"); } },
|
{ type_index(typeid(vector<double>)), [](const Property& p) { return getStringPair<vector<double>>(p, "vector<double>"); } },
|
||||||
{ type_index(typeid(vector<long double>)), [](const Property& p) { return getStringPair<vector<long double>>(p, "vector<long double>"); } },
|
{ type_index(typeid(vector<long double>)), [](const Property& p) { return getStringPair<vector<long double>>(p, "vector<long double>"); } },
|
||||||
{ type_index(typeid(vector<boost::filesystem::path>)), [](const Property& p) { return getStringPair<vector<boost::filesystem::path>>(p, "vector<boost::filesystem::path>"); } },
|
{ type_index(typeid(vector<fs::path>)), [](const Property& p) { return getStringPair<vector<fs::path>>(p,
|
||||||
|
#if FAIRMQ_HAS_STD_FILESYSTEM
|
||||||
|
"vector<std::filesystem::path>"); } },
|
||||||
|
#else
|
||||||
|
"vector<boost::filesystem::path>"); } },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
unordered_map<type_index, void(*)(const EventManager&, const string&, const Property&)> PropertyHelper::fEventEmitters = {
|
unordered_map<type_index, void(*)(const EventManager&, const string&, const Property&)> PropertyHelper::fEventEmitters = {
|
||||||
|
@ -122,7 +140,7 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
|
||||||
{ type_index(typeid(long double)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long double>(k, any_cast<long double>(p)); } },
|
{ type_index(typeid(long double)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, long double>(k, any_cast<long double>(p)); } },
|
||||||
{ type_index(typeid(bool)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, bool>(k, any_cast<bool>(p)); } },
|
{ type_index(typeid(bool)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, bool>(k, any_cast<bool>(p)); } },
|
||||||
{ type_index(typeid(vector<bool>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<bool>>(k, any_cast<vector<bool>>(p)); } },
|
{ type_index(typeid(vector<bool>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<bool>>(k, any_cast<vector<bool>>(p)); } },
|
||||||
{ type_index(typeid(boost::filesystem::path)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, boost::filesystem::path>(k, any_cast<boost::filesystem::path>(p)); } },
|
{ type_index(typeid(fs::path)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, fs::path>(k, any_cast<fs::path>(p)); } },
|
||||||
{ type_index(typeid(vector<char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<char>>(k, any_cast<vector<char>>(p)); } },
|
{ type_index(typeid(vector<char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<char>>(k, any_cast<vector<char>>(p)); } },
|
||||||
{ type_index(typeid(vector<signed char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<signed char>>(k, any_cast<vector<signed char>>(p)); } },
|
{ type_index(typeid(vector<signed char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<signed char>>(k, any_cast<vector<signed char>>(p)); } },
|
||||||
{ type_index(typeid(vector<unsigned char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned char>>(k, any_cast<vector<unsigned char>>(p)); } },
|
{ type_index(typeid(vector<unsigned char>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<unsigned char>>(k, any_cast<vector<unsigned char>>(p)); } },
|
||||||
|
@ -138,7 +156,7 @@ unordered_map<type_index, void(*)(const EventManager&, const string&, const Prop
|
||||||
{ type_index(typeid(vector<float>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<float>>(k, any_cast<vector<float>>(p)); } },
|
{ type_index(typeid(vector<float>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<float>>(k, any_cast<vector<float>>(p)); } },
|
||||||
{ type_index(typeid(vector<double>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<double>>(k, any_cast<vector<double>>(p)); } },
|
{ type_index(typeid(vector<double>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<double>>(k, any_cast<vector<double>>(p)); } },
|
||||||
{ type_index(typeid(vector<long double>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long double>>(k, any_cast<vector<long double>>(p)); } },
|
{ type_index(typeid(vector<long double>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<long double>>(k, any_cast<vector<long double>>(p)); } },
|
||||||
{ type_index(typeid(vector<boost::filesystem::path>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<boost::filesystem::path>>(k, any_cast<vector<boost::filesystem::path>>(p)); } },
|
{ type_index(typeid(vector<fs::path>)), [](const EventManager& em, const string& k, const Property& p) { em.Emit<PropertyChange, vector<fs::path>>(k, any_cast<vector<fs::path>>(p)); } },
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -29,7 +29,6 @@ using Property = boost::any;
|
||||||
using Properties = std::map<std::string, Property>;
|
using Properties = std::map<std::string, Property>;
|
||||||
|
|
||||||
struct PropertyChange : Event<std::string> {};
|
struct PropertyChange : Event<std::string> {};
|
||||||
struct PropertyChangeAsString : Event<std::string> {};
|
|
||||||
|
|
||||||
class PropertyHelper
|
class PropertyHelper
|
||||||
{
|
{
|
||||||
|
|
26
fairmq/SDK.h
26
fairmq/SDK.h
|
@ -1,26 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* 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" *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef FAIR_MQ_SDK_H
|
|
||||||
#define FAIR_MQ_SDK_H
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include <fairmq/sdk/AsioAsyncOp.h>
|
|
||||||
#include <fairmq/sdk/AsioBase.h>
|
|
||||||
#include <fairmq/sdk/DDSAgent.h>
|
|
||||||
#include <fairmq/sdk/DDSEnvironment.h>
|
|
||||||
#include <fairmq/sdk/DDSInfo.h>
|
|
||||||
#include <fairmq/sdk/DDSSession.h>
|
|
||||||
#include <fairmq/sdk/DDSTask.h>
|
|
||||||
#include <fairmq/sdk/DDSTopology.h>
|
|
||||||
#include <fairmq/sdk/Error.h>
|
|
||||||
#include <fairmq/sdk/Topology.h>
|
|
||||||
#include <fairmq/sdk/Traits.h>
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_SDK_H
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2021-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -52,8 +52,8 @@ struct Socket
|
||||||
|
|
||||||
virtual int64_t Send(MessagePtr& msg, int timeout = -1) = 0;
|
virtual int64_t Send(MessagePtr& msg, int timeout = -1) = 0;
|
||||||
virtual int64_t Receive(MessagePtr& msg, int timeout = -1) = 0;
|
virtual int64_t Receive(MessagePtr& msg, int timeout = -1) = 0;
|
||||||
virtual int64_t Send(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
|
virtual int64_t Send(Parts::container& msgVec, int timeout = -1) = 0;
|
||||||
virtual int64_t Receive(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
|
virtual int64_t Receive(Parts::container & msgVec, int timeout = -1) = 0;
|
||||||
virtual int64_t Send(Parts& parts, int timeout = -1) { return Send(parts.fParts, timeout); }
|
virtual int64_t Send(Parts& parts, int timeout = -1) { return Send(parts.fParts, timeout); }
|
||||||
virtual int64_t Receive(Parts& parts, int timeout = -1) { return Receive(parts.fParts, timeout); }
|
virtual int64_t Receive(Parts& parts, int timeout = -1) { return Receive(parts.fParts, timeout); }
|
||||||
|
|
||||||
|
@ -103,9 +103,7 @@ struct SocketError : std::runtime_error
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
||||||
// using FairMQSocket [[deprecated("Use fair::mq::Socket")]] = fair::mq::Socket;
|
using FairMQSocket [[deprecated("Use fair::mq::Socket")]] = fair::mq::Socket;
|
||||||
// using FairMQSocketPtr [[deprecated("Use fair::mq::SocketPtr")]] = fair::mq::SocketPtr;
|
using FairMQSocketPtr [[deprecated("Use fair::mq::SocketPtr")]] = fair::mq::SocketPtr;
|
||||||
using FairMQSocket = fair::mq::Socket;
|
|
||||||
using FairMQSocketPtr = fair::mq::SocketPtr;
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_SOCKET_H
|
#endif // FAIR_MQ_SOCKET_H
|
||||||
|
|
|
@ -157,6 +157,13 @@ struct Machine_ : public state_machine_def<Machine_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallStatePrep(const State state) const
|
||||||
|
{
|
||||||
|
if (!fStatePrepSignal.empty()) {
|
||||||
|
fStatePrepSignal(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CallNewTransitionCallbacks(const Transition transition) const
|
void CallNewTransitionCallbacks(const Transition transition) const
|
||||||
{
|
{
|
||||||
if (!fNewTransitionSignal.empty()) {
|
if (!fNewTransitionSignal.empty()) {
|
||||||
|
@ -170,11 +177,13 @@ struct Machine_ : public state_machine_def<Machine_>
|
||||||
atomic<bool> fLastTransitionResult;
|
atomic<bool> fLastTransitionResult;
|
||||||
|
|
||||||
mutex fStateMtx;
|
mutex fStateMtx;
|
||||||
|
mutex fSubscriptionsMtx;
|
||||||
atomic<bool> fNewStatePending;
|
atomic<bool> fNewStatePending;
|
||||||
condition_variable fNewStatePendingCV;
|
condition_variable fNewStatePendingCV;
|
||||||
|
|
||||||
boost::signals2::signal<void(const State)> fStateChangeSignal;
|
boost::signals2::signal<void(const State)> fStateChangeSignal;
|
||||||
boost::signals2::signal<void(const State)> fStateHandleSignal;
|
boost::signals2::signal<void(const State)> fStateHandleSignal;
|
||||||
|
boost::signals2::signal<void(const State)> fStatePrepSignal;
|
||||||
boost::signals2::signal<void(const Transition)> fNewTransitionSignal;
|
boost::signals2::signal<void(const Transition)> fNewTransitionSignal;
|
||||||
unordered_map<string, boost::signals2::connection> fStateChangeSignalsMap;
|
unordered_map<string, boost::signals2::connection> fStateChangeSignalsMap;
|
||||||
unordered_map<string, boost::signals2::connection> fNewTransitionSignalsMap;
|
unordered_map<string, boost::signals2::connection> fNewTransitionSignalsMap;
|
||||||
|
@ -198,6 +207,7 @@ struct Machine_ : public state_machine_def<Machine_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallStatePrep(fState);
|
||||||
CallStateChangeCallbacks(fState);
|
CallStateChangeCallbacks(fState);
|
||||||
CallStateHandler(fState);
|
CallStateHandler(fState);
|
||||||
}
|
}
|
||||||
|
@ -301,18 +311,33 @@ try {
|
||||||
|
|
||||||
void StateMachine::SubscribeToStateChange(const string& key, function<void(const State)> callback)
|
void StateMachine::SubscribeToStateChange(const string& key, function<void(const State)> callback)
|
||||||
{
|
{
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignalsMap.insert({key, static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignal.connect(callback)});
|
// Check if the key has a integer value as prefix, if yes, decode it.
|
||||||
|
int i = strtol(key.c_str(), nullptr, 10);
|
||||||
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
lock_guard<mutex> lock(fsm->fSubscriptionsMtx);
|
||||||
|
fsm->fStateChangeSignalsMap.insert({key, fsm->fStateChangeSignal.connect(i, callback)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateMachine::UnsubscribeFromStateChange(const string& key)
|
void StateMachine::UnsubscribeFromStateChange(const string& key)
|
||||||
{
|
{
|
||||||
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
lock_guard<mutex> lock(fsm->fSubscriptionsMtx);
|
||||||
if (fsm->fStateChangeSignalsMap.count(key)) {
|
if (fsm->fStateChangeSignalsMap.count(key)) {
|
||||||
fsm->fStateChangeSignalsMap.at(key).disconnect();
|
fsm->fStateChangeSignalsMap.at(key).disconnect();
|
||||||
fsm->fStateChangeSignalsMap.erase(key);
|
fsm->fStateChangeSignalsMap.erase(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StateMachine::PrepareState(std::function<void(const State)> callback)
|
||||||
|
{
|
||||||
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
if (fsm->fStatePrepSignal.empty()) {
|
||||||
|
fsm->fStatePrepSignal.connect(callback);
|
||||||
|
} else {
|
||||||
|
LOG(error) << "state preparation handler is already set";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StateMachine::HandleStates(function<void(const State)> callback)
|
void StateMachine::HandleStates(function<void(const State)> callback)
|
||||||
{
|
{
|
||||||
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
@ -326,6 +351,9 @@ void StateMachine::HandleStates(function<void(const State)> callback)
|
||||||
void StateMachine::StopHandlingStates()
|
void StateMachine::StopHandlingStates()
|
||||||
{
|
{
|
||||||
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
if (!fsm->fStatePrepSignal.empty()) {
|
||||||
|
fsm->fStatePrepSignal.disconnect_all_slots();
|
||||||
|
}
|
||||||
if (!fsm->fStateHandleSignal.empty()) {
|
if (!fsm->fStateHandleSignal.empty()) {
|
||||||
fsm->fStateHandleSignal.disconnect_all_slots();
|
fsm->fStateHandleSignal.disconnect_all_slots();
|
||||||
}
|
}
|
||||||
|
@ -333,12 +361,15 @@ void StateMachine::StopHandlingStates()
|
||||||
|
|
||||||
void StateMachine::SubscribeToNewTransition(const string& key, function<void(const Transition)> callback)
|
void StateMachine::SubscribeToNewTransition(const string& key, function<void(const Transition)> callback)
|
||||||
{
|
{
|
||||||
static_pointer_cast<FairMQFSM>(fFsm)->fNewTransitionSignalsMap.insert({key, static_pointer_cast<FairMQFSM>(fFsm)->fNewTransitionSignal.connect(callback)});
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
lock_guard<mutex> lock(fsm->fSubscriptionsMtx);
|
||||||
|
fsm->fNewTransitionSignalsMap.insert({key, fsm->fNewTransitionSignal.connect(callback)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateMachine::UnsubscribeFromNewTransition(const string& key)
|
void StateMachine::UnsubscribeFromNewTransition(const string& key)
|
||||||
{
|
{
|
||||||
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
|
||||||
|
lock_guard<mutex> lock(fsm->fSubscriptionsMtx);
|
||||||
if (fsm->fNewTransitionSignalsMap.count(key)) {
|
if (fsm->fNewTransitionSignalsMap.count(key)) {
|
||||||
fsm->fNewTransitionSignalsMap.at(key).disconnect();
|
fsm->fNewTransitionSignalsMap.at(key).disconnect();
|
||||||
fsm->fNewTransitionSignalsMap.erase(key);
|
fsm->fNewTransitionSignalsMap.erase(key);
|
||||||
|
|
|
@ -35,6 +35,7 @@ class StateMachine
|
||||||
void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback);
|
void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback);
|
||||||
void UnsubscribeFromStateChange(const std::string& key);
|
void UnsubscribeFromStateChange(const std::string& key);
|
||||||
|
|
||||||
|
void PrepareState(std::function<void(const State)> callback);
|
||||||
void HandleStates(std::function<void(const State)> callback);
|
void HandleStates(std::function<void(const State)> callback);
|
||||||
void StopHandlingStates();
|
void StopHandlingStates();
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user