Compare commits

..

52 Commits

Author SHA1 Message Date
Alexey Rybalchenko
1a75141fc4 shm: allow monitor::ResetContent to cleanup after a crash 2022-02-02 10:49:00 +01:00
Alexey Rybalchenko
2f82eb4f09 shm: monitor: disable number of msgs in the ack queue output 2022-02-02 10:49:00 +01:00
Alexey Rybalchenko
92a56c26bc shm: remove UR queues on ResetContent 2022-02-02 10:49:00 +01:00
Alexey Rybalchenko
4f9aeda8ec shm: Add size to UnmanagedRegion debug output 2022-02-02 10:49:00 +01:00
Giulio Eulisse
ad894c79cf GUI Controller
provide a controller which can be used to control state
transitions from an external GUI.
2022-01-25 18:02:25 +01:00
Alexey Rybalchenko
5f33401d41 Parallelize more tests 2022-01-25 11:55:38 +01:00
Alexey Rybalchenko
f4d39d224b Avoid fixed ports in the test suites 2022-01-25 11:55:38 +01:00
Alexey Rybalchenko
bfd08bb33f Don't use to-be-deprecated names 2022-01-24 06:40:24 +01:00
Alexey Rybalchenko
f15f669853 use [[maybe_unused]] for values used in assertions 2022-01-24 06:40:24 +01:00
Alexey Rybalchenko
f6bade32bb modify keep-alive example executable a bit, make it configurable 2022-01-12 19:54:49 +01:00
Alexey Rybalchenko
ddf9bc7272 shm: keep mng segment around when skipping cleanup 2022-01-12 19:54:49 +01:00
Alexey Rybalchenko
f79a0714b4 shm: fix double unlock() 2022-01-12 19:54:49 +01:00
Alexey Rybalchenko
c04958e2a4 shm: reduce contention on region events 2022-01-10 19:42:08 +01:00
Alexey Rybalchenko
692576a5b1 shm: add APIs for implementing keep-alive process 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
eb4620b1ec shm: always open_or_create segment 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
9f9583eb55 shm: hide picosha2 from header 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
08ba068791 shm: remove unused member 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
1839f7e8c0 shm: integrate mtx and cv into management segment 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
80ed45df63 extend region config 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
eef42d2dea simplify region cleanup 2021-12-16 16:27:07 +01:00
Alexey Rybalchenko
d630fbb1e4 consolidate UnmanagedRegion options 2021-12-16 16:27:07 +01:00
Giulio Eulisse
acfb495411 Do not print logo, if not requested 2021-12-14 11:26:10 +01:00
Alexey Rybalchenko
953c4a75c8 refactor: deduplicate more zmq/shmem code 2021-12-06 09:45:39 +01:00
Alexey Rybalchenko
f24dee33c2 Add configurable default snd/rcv timeout 2021-12-06 09:45:39 +01:00
Alexey Rybalchenko
856780f88a fix: install tools/Exceptions.h 2021-11-12 13:20:48 +01:00
Alexey Rybalchenko
dbdf17c661 Avoid accessing Device.fChannels directly, use getters 2021-11-03 20:23:40 +01:00
Alexey Rybalchenko
a3bb5fb4b0 feat: Add Device::GetNumSubChannels(channel) 2021-11-03 20:23:40 +01:00
Alexey Rybalchenko
0eaea3c66f Do not catch and rethrow exception from state handlers 2021-11-03 20:23:40 +01:00
Alexey Rybalchenko
ebcbe2dde6 feat: Add interactive controller button to print connected peers 2021-10-19 10:22:19 +02:00
Dennis Klein
fda8126a43 feat: Add new GetNumberOfConnectedPeers() API 2021-10-19 10:22:19 +02:00
Dennis Klein
8796ce5b20 feat: Add new assertm macro
This allows to add a message to the assertion which can improve
readability of error diagnostics.
2021-10-19 10:22:19 +02:00
Dennis Klein
b8503bfbd5 fix: Deprecate Message::Close because it is really a dtor 2021-10-19 10:22:19 +02:00
Dennis Klein
7329cb4428 refactor: Deduplicate GetConstant()
* Deprecate its old name in the Socket classes
2021-10-19 10:22:19 +02:00
Dennis Klein
e84a16da88 fix: warning readability-braces-around-statements 2021-10-19 10:22:19 +02:00
Dennis Klein
1a5d0eddbe fix: Silence false positive cppcoreguidel-pro-bounds-array-to-pointer-decay 2021-10-19 10:22:19 +02:00
Alexey Rybalchenko
5fe2f53c7b feat: add tool for noncanonical input 2021-10-08 09:42:28 +02:00
Alexey Rybalchenko
d7fb01908c fix(shm): fix regression in debug mode data 2021-10-08 09:42:28 +02:00
Alexey Rybalchenko
1449166d44 feat: add options to control allocation attempts 2021-10-08 09:42:28 +02:00
Dennis Klein
55a2cfcc37 ci: Add macos-11-arm64 (apple-clang-13) build 2021-10-01 17:08:50 +02:00
Alexey Rybalchenko
36600dce2c Apply clang-diagnostic-unused-private-field 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
153dcfab94 Apply modernize-use-override 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
ad824b4de1 Define copy/move ctors and assignment ops
Delete special member functions where they are not used.
(as part of applying suggestions from cppcoreguidelines-special-member-functions)

These classes don't need to be copyable/movable:
  # copy/move not used:
  zmq:: TransportFactory, Socket, Message, UnmanagedRegion, Poller, Context
  shm:: TransportFactory, Socket, Message, UnmanagedRegion, Poller
  ofi:: TransportFactory, Socket, Message, Context
  shm:: ZMsg, Region, Monitor, TerminalConfig, Manager
  plugins:: Config, Control, TerminalConfig
  fairmq::StateQueue, StateMachine, ProgOptions, PluginServices, PluginManager, Plugin, Device, StateSubscription
  TestData, BadDevice, TestDevice (test suite heplers)

  # used via ptr interface:
  fairmq::UnmanagedRegion, TransportFactory, Socket, Poller, Message

These classes need to be movable/copyable:
 MyClass (test suite helper), fairmq::Channel, fairmq::Parts
2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
597d88277b Apply clang-analyzer-optin.performance.Padding 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
9590b5be40 Apply readability-static-accessed-through-instance 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
cf9b45cd75 Apply cppcoreguidelines-avoid-non-const-global-variables 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
1ee9d2d222 Apply misc-unused-alias-decls 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
310204a89d Apply performance-faster-string-find 2021-09-27 12:04:07 +02:00
Alexey Rybalchenko
f33c597f34 Apply readability-avoid-const-params-in-decls 2021-09-27 12:04:07 +02:00
Dennis Klein
42a7e298c0 ci: Update build environments 2021-09-24 14:16:44 +02:00
Alexey Rybalchenko
efca8e0ad4 fix(pmix): Avoid deprecated value 2021-09-24 13:36:58 +02:00
Alexey Rybalchenko
1ac30b51b1 fix(pmix): compiler warning infinite-recursion 2021-09-24 13:36:58 +02:00
Alexey Rybalchenko
2934016586 fix(pmix): ler warning string-plus-int 2021-09-24 13:36:58 +02:00
181 changed files with 3262 additions and 2321 deletions

6
Jenkinsfile vendored
View File

@@ -89,15 +89,15 @@ pipeline{
stage("CI") { stage("CI") {
steps{ steps{
script { script {
def all = '-DHAS_ASIO=ON -DHAS_DDS=ON -DHAS_PMIX=ON' 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', extra: all],
[os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10', extra: all], [os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10', extra: all],
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10', extra: all], [os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10', extra: all],
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11', extra: all], [os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11', extra: all],
[os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12', [os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12', extra: '-DHAS_ASIO=ON'],
extra: '-DHAS_ASIO=ON -DHAS_DDS=ON'], [os: 'macos', ver: '11', arch: 'arm64', compiler: 'apple-clang-13', extra: '-DHAS_ASIO=ON'],
]) ])
def all_debug = "${all} -DCMAKE_BUILD_TYPE=Debug" def all_debug = "${all} -DCMAKE_BUILD_TYPE=Debug"

View File

@@ -23,10 +23,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CUR
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh) 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) add_test(NAME Example.1-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
set_tests_properties(Example.1-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ") 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) add_test(NAME Example.1-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ") set_tests_properties(Example.1-1.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
# install # install

View File

@@ -30,7 +30,7 @@ struct Sampler : fair::mq::Device
// create message object with a pointer to the data buffer, its size, // create message object with a pointer to the data buffer, its size,
// custom deletion function (called when transfer is done), // custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer // and pointer to the object managing the data buffer
FairMQMessagePtr msg(NewMessage( fair::mq::MessagePtr msg(NewMessage(
const_cast<char*>(text->c_str()), const_cast<char*>(text->c_str()),
text->length(), text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, [](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },

View File

@@ -27,7 +27,7 @@ struct Sink : fair::mq::Device
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";

View File

@@ -8,20 +8,23 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
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;' TERM trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanAddr' TERM
SAMPLER="fairmq-ex-1-1-sampler" SAMPLER="fairmq-ex-1-1-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --rate 1" SAMPLER+=" --rate 1"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $SESSION" SAMPLER+=" --session $session"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1" SAMPLER+=" --max-iterations 1"
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://*:5555,rateLogging=0" SAMPLER+=" --channel-config name=$chan,type=push,method=bind,address=ipc://$chanAddr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -29,13 +32,16 @@ SINK="fairmq-ex-1-1-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --transport $transport" SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh"
SINK+=" --session $SESSION" SINK+=" --session $session"
SINK+=" --shm-segment-size 100000000"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --max-iterations 1" SINK+=" --max-iterations 1"
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://localhost:5555,rateLogging=0" SINK+=" --channel-config name=$chan,type=pull,method=connect,address=ipc://$chanAddr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
# wait for sampler and sink to finish # wait for sampler and sink to finish
wait $SAMPLER_PID wait $SAMPLER_PID
wait $SINK_PID wait $SINK_PID
rm $chanAddr

View File

@@ -29,10 +29,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-1-n-1.json ${CMAKE_CURRENT_BINARY_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh) 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) add_test(NAME Example.1-n-1.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
set_tests_properties(Example.1-n-1.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ") 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) add_test(NAME Example.1-n-1.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ") set_tests_properties(Example.1-n-1.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received: ")
# install # install

View File

@@ -20,7 +20,7 @@ struct Processor : fair::mq::Device
OnData("data1", &Processor::HandleData); OnData("data1", &Processor::HandleData);
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received data, processing..."; LOG(info) << "Received data, processing...";
@@ -32,7 +32,7 @@ struct Processor : fair::mq::Device
// its size, // its size,
// custom deletion function (called when transfer is done), // custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer // and pointer to the object managing the data buffer
FairMQMessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()), fair::mq::MessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(), text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, [](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },
text)); text));

View File

@@ -28,7 +28,7 @@ struct Sampler : fair::mq::Device
{ {
// Initializing message with NewStaticMessage will avoid copy // Initializing message with NewStaticMessage will avoid copy
// but won't delete the data after the sending is completed. // but won't delete the data after the sending is completed.
FairMQMessagePtr msg(NewStaticMessage(fText)); fair::mq::MessagePtr msg(NewStaticMessage(fText));
LOG(info) << "Sending \"" << fText << "\""; LOG(info) << "Sending \"" << fText << "\"";

View File

@@ -27,7 +27,7 @@ struct Sink : fair::mq::Device
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";

View File

@@ -8,20 +8,25 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
ex2config="@CMAKE_CURRENT_BINARY_DIR@/ex-1-n-1.json" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" chan1="data1"
chan2="data2"
chan1Addr="/tmp/fmq_$session""_""$chan1""_""$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;' TERM 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
SAMPLER="fairmq-ex-1-n-1-sampler" SAMPLER="fairmq-ex-1-n-1-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $SESSION" SAMPLER+=" --session $session"
SAMPLER+=" --severity debug"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 2" SAMPLER+=" --max-iterations 2"
SAMPLER+=" --mq-config $ex2config" SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,address=ipc://$chan1Addr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -29,10 +34,12 @@ PROCESSOR1="fairmq-ex-1-n-1-processor"
PROCESSOR1+=" --id processor1" PROCESSOR1+=" --id processor1"
PROCESSOR1+=" --transport $transport" PROCESSOR1+=" --transport $transport"
PROCESSOR1+=" --verbosity veryhigh" PROCESSOR1+=" --verbosity veryhigh"
PROCESSOR1+=" --session $SESSION" PROCESSOR1+=" --session $session"
PROCESSOR1+=" --severity debug"
PROCESSOR1+=" --shm-segment-size 100000000"
PROCESSOR1+=" --control static --color false" PROCESSOR1+=" --control static --color false"
PROCESSOR1+=" --mq-config $ex2config" PROCESSOR1+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
PROCESSOR1+=" --config-key processor" PROCESSOR1+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR1 & @CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR1 &
PROCESSOR1_PID=$! PROCESSOR1_PID=$!
@@ -40,10 +47,12 @@ PROCESSOR2="fairmq-ex-1-n-1-processor"
PROCESSOR2+=" --id processor2" PROCESSOR2+=" --id processor2"
PROCESSOR2+=" --transport $transport" PROCESSOR2+=" --transport $transport"
PROCESSOR2+=" --verbosity veryhigh" PROCESSOR2+=" --verbosity veryhigh"
PROCESSOR2+=" --session $SESSION" PROCESSOR2+=" --session $session"
PROCESSOR2+=" --severity debug"
PROCESSOR2+=" --shm-segment-size 100000000"
PROCESSOR2+=" --control static --color false" PROCESSOR2+=" --control static --color false"
PROCESSOR2+=" --mq-config $ex2config" PROCESSOR2+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr,rateLogging=0"
PROCESSOR2+=" --config-key processor" PROCESSOR2+=" name=$chan2,type=push,method=connect,address=ipc://$chan2Addr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR2 & @CMAKE_CURRENT_BINARY_DIR@/$PROCESSOR2 &
PROCESSOR2_PID=$! PROCESSOR2_PID=$!
@@ -51,10 +60,12 @@ SINK="fairmq-ex-1-n-1-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --transport $transport" SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh"
SINK+=" --session $SESSION" SINK+=" --session $session"
SINK+=" --severity debug"
SINK+=" --shm-segment-size 100000000"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --max-iterations 2" SINK+=" --max-iterations 2"
SINK+=" --mq-config $ex2config" SINK+=" --channel-config name=$chan2,type=pull,method=bind,address=ipc://$chan2Addr,rateLogging=0"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
@@ -69,3 +80,5 @@ kill -SIGINT $PROCESSOR2_PID
# wait for everything to finish # wait for everything to finish
wait $PROCESSOR1_PID wait $PROCESSOR1_PID
wait $PROCESSOR2_PID wait $PROCESSOR2_PID
rm $chan1Addr; rm $chan2Addr

View File

@@ -15,16 +15,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-builtin-devices.sh.in
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-builtin-devices.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh) 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) add_test(NAME Example.BuiltinDevices.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq)
set_tests_properties(Example.BuiltinDevices.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached") 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) add_test(NAME Example.BuiltinDevices.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem)
set_tests_properties(Example.BuiltinDevices.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached") 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) add_test(NAME Example.BuiltinDevices.multipart.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh zeromq true 2)
set_tests_properties(Example.BuiltinDevices.multipart.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached") 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) add_test(NAME Example.BuiltinDevices.multipart.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-builtin-devices.sh shmem true 2)
set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached") set_tests_properties(Example.BuiltinDevices.multipart.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Configured maximum number of iterations reached")
# install # install

View File

@@ -2,8 +2,6 @@
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@ export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
transport="zeromq" transport="zeromq"
multipart="false" multipart="false"
numParts="1" numParts="1"
@@ -20,8 +18,22 @@ if [[ $3 =~ ^[0-9]+$ ]]; then
numParts=$3 numParts=$3
fi fi
session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan1="data1"
chan2="data2"
chan3="data3"
chan4="data4"
chan5="data5"
chan1Addr="/tmp/fmq_$session""_""$chan1""_""$transport"
chan2Addr1="/tmp/fmq_$session""_""$chan2""_1""_""$transport"
chan2Addr2="/tmp/fmq_$session""_""$chan2""_2""_""$transport"
chan3Addr1="/tmp/fmq_$session""_""$chan3""_1""_""$transport"
chan3Addr2="/tmp/fmq_$session""_""$chan3""_2""_""$transport"
chan4Addr="/tmp/fmq_$session""_""$chan4""_""$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;' TERM 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
SAMPLER="fairmq-bsampler" SAMPLER="fairmq-bsampler"
SAMPLER+=" --id bsampler1" SAMPLER+=" --id bsampler1"
@@ -30,14 +42,15 @@ SAMPLER+=" --transport $transport"
SAMPLER+=" --color false" SAMPLER+=" --color false"
SAMPLER+=" --control static" SAMPLER+=" --control static"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --severity debug" SAMPLER+=" --severity debug"
SAMPLER+=" --msg-size 100000" SAMPLER+=" --msg-size 100000"
SAMPLER+=" --multipart $multipart" SAMPLER+=" --multipart $multipart"
SAMPLER+=" --num-parts $numParts" SAMPLER+=" --num-parts $numParts"
SAMPLER+=" --msg-rate 1" SAMPLER+=" --msg-rate 1"
SAMPLER+=" --max-iterations 0" SAMPLER+=" --max-iterations 0"
SAMPLER+=" --out-channel data1" SAMPLER+=" --out-channel $chan1"
SAMPLER+=" --channel-config name=data1,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5555" SAMPLER+=" --channel-config name=$chan1,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan1Addr"
@FAIRMQ_BIN_DIR@/$SAMPLER & @FAIRMQ_BIN_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -48,11 +61,12 @@ SPLITTER+=" --transport $transport"
SPLITTER+=" --color false" SPLITTER+=" --color false"
SPLITTER+=" --control static" SPLITTER+=" --control static"
SPLITTER+=" --verbosity veryhigh" SPLITTER+=" --verbosity veryhigh"
SPLITTER+=" --shm-segment-size 100000000"
SPLITTER+=" --multipart $multipart" SPLITTER+=" --multipart $multipart"
SPLITTER+=" --in-channel data1" SPLITTER+=" --in-channel $chan1"
SPLITTER+=" --out-channel data2" SPLITTER+=" --out-channel $chan2"
SPLITTER+=" --channel-config name=data1,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5555" SPLITTER+=" --channel-config name=$chan1,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan1Addr"
SPLITTER+=" name=data2,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5556,address=tcp://localhost:5557" SPLITTER+=" name=$chan2,type=push,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr1,address=ipc://$chan2Addr2"
@FAIRMQ_BIN_DIR@/$SPLITTER & @FAIRMQ_BIN_DIR@/$SPLITTER &
SPLITTER_PID=$! SPLITTER_PID=$!
@@ -63,11 +77,12 @@ PROXY1+=" --transport $transport"
PROXY1+=" --color false" PROXY1+=" --color false"
PROXY1+=" --control static" PROXY1+=" --control static"
PROXY1+=" --verbosity veryhigh" PROXY1+=" --verbosity veryhigh"
PROXY1+=" --shm-segment-size 100000000"
PROXY1+=" --multipart $multipart" PROXY1+=" --multipart $multipart"
PROXY1+=" --in-channel data2" PROXY1+=" --in-channel $chan2"
PROXY1+=" --out-channel data3" PROXY1+=" --out-channel $chan3"
PROXY1+=" --channel-config name=data2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5556" PROXY1+=" --channel-config name=$chan2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr1"
PROXY1+=" name=data3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5558" PROXY1+=" name=$chan3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr1"
@FAIRMQ_BIN_DIR@/$PROXY1 & @FAIRMQ_BIN_DIR@/$PROXY1 &
PROXY1_PID=$! PROXY1_PID=$!
@@ -78,11 +93,12 @@ PROXY2+=" --transport $transport"
PROXY2+=" --color false" PROXY2+=" --color false"
PROXY2+=" --control static" PROXY2+=" --control static"
PROXY2+=" --verbosity veryhigh" PROXY2+=" --verbosity veryhigh"
PROXY2+=" --shm-segment-size 100000000"
PROXY2+=" --multipart $multipart" PROXY2+=" --multipart $multipart"
PROXY2+=" --in-channel data2" PROXY2+=" --in-channel $chan2"
PROXY2+=" --out-channel data3" PROXY2+=" --out-channel $chan3"
PROXY2+=" --channel-config name=data2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5557" PROXY2+=" --channel-config name=$chan2,type=pull,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan2Addr2"
PROXY2+=" name=data3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5559" PROXY2+=" name=$chan3,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr2"
@FAIRMQ_BIN_DIR@/$PROXY2 & @FAIRMQ_BIN_DIR@/$PROXY2 &
PROXY2_PID=$! PROXY2_PID=$!
@@ -93,11 +109,12 @@ MERGER+=" --transport $transport"
MERGER+=" --color false" MERGER+=" --color false"
MERGER+=" --control static" MERGER+=" --control static"
MERGER+=" --verbosity veryhigh" MERGER+=" --verbosity veryhigh"
MERGER+=" --shm-segment-size 100000000"
MERGER+=" --multipart $multipart" MERGER+=" --multipart $multipart"
MERGER+=" --in-channel data3" MERGER+=" --in-channel $chan3"
MERGER+=" --out-channel data4" MERGER+=" --out-channel $chan4"
MERGER+=" --channel-config name=data3,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5558,address=tcp://localhost:5559" MERGER+=" --channel-config name=$chan3,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan3Addr1,address=ipc://$chan3Addr2"
MERGER+=" name=data4,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5560" MERGER+=" name=$chan4,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan4Addr"
@FAIRMQ_BIN_DIR@/$MERGER & @FAIRMQ_BIN_DIR@/$MERGER &
MERGER_PID=$! MERGER_PID=$!
@@ -108,11 +125,12 @@ MULTIPLIER+=" --transport $transport"
MULTIPLIER+=" --color false" MULTIPLIER+=" --color false"
MULTIPLIER+=" --control static" MULTIPLIER+=" --control static"
MULTIPLIER+=" --verbosity veryhigh" MULTIPLIER+=" --verbosity veryhigh"
MULTIPLIER+=" --shm-segment-size 100000000"
MULTIPLIER+=" --multipart $multipart" MULTIPLIER+=" --multipart $multipart"
MULTIPLIER+=" --in-channel data4" MULTIPLIER+=" --in-channel $chan4"
MULTIPLIER+=" --out-channel data5" MULTIPLIER+=" --out-channel $chan5"
MULTIPLIER+=" --channel-config name=data4,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5560" MULTIPLIER+=" --channel-config name=$chan4,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan4Addr"
MULTIPLIER+=" name=data5,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5561,address=tcp://localhost:5561" MULTIPLIER+=" name=$chan5,type=push,method=connect,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr,address=ipc://$chan5Addr"
@FAIRMQ_BIN_DIR@/$MULTIPLIER & @FAIRMQ_BIN_DIR@/$MULTIPLIER &
MULTIPLIER_PID=$! MULTIPLIER_PID=$!
@@ -126,8 +144,8 @@ SINK+=" --verbosity veryhigh"
SINK+=" --severity debug" SINK+=" --severity debug"
SINK+=" --multipart $multipart" SINK+=" --multipart $multipart"
SINK+=" --max-iterations 2" SINK+=" --max-iterations 2"
SINK+=" --in-channel data5" SINK+=" --in-channel $chan5"
SINK+=" --channel-config name=data5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=tcp://localhost:5561" SINK+=" --channel-config name=$chan5,type=pull,method=bind,sndBufSize=50,rcvBufSize=50,address=ipc://$chan5Addr"
@FAIRMQ_BIN_DIR@/$SINK & @FAIRMQ_BIN_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
@@ -146,3 +164,5 @@ wait $PROXY1_PID
wait $PROXY2_PID wait $PROXY2_PID
wait $MERGER_PID wait $MERGER_PID
wait $MULTIPLIER_PID wait $MULTIPLIER_PID
rm $chan1Addr; rm $chan2Addr1; rm $chan2Addr2; rm $chan3Addr1; rm $chan3Addr2; rm $chan4Addr; rm $chan5Addr

View File

@@ -24,10 +24,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAK
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh) 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) add_test(NAME Example.CopyPush.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
set_tests_properties(Example.CopyPush.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ") 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) add_test(NAME Example.CopyPush.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ") set_tests_properties(Example.CopyPush.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received message: ")
# install # install

View File

@@ -19,7 +19,7 @@ struct Sampler : fair::mq::Device
{ {
void InitTask() override void InitTask() override
{ {
fNumDataChannels = fChannels.at("data").size(); fNumDataChannels = GetNumSubChannels("data");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
@@ -27,10 +27,10 @@ struct Sampler : fair::mq::Device
{ {
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place). // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy // Should only be used for small data because of the cost of an additional copy
FairMQMessagePtr msg(NewSimpleMessage(fCounter++)); fair::mq::MessagePtr msg(NewSimpleMessage(fCounter++));
for (int i = 0; i < fNumDataChannels - 1; ++i) { for (int i = 0; i < fNumDataChannels - 1; ++i) {
FairMQMessagePtr msgCopy(NewMessage()); fair::mq::MessagePtr msgCopy(NewMessage());
msgCopy->Copy(*msg); msgCopy->Copy(*msg);
Send(msgCopy, "data", i); Send(msgCopy, "data", i);
} }

View File

@@ -27,7 +27,7 @@ struct Sink : fair::mq::Device
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received message: \"" << *(static_cast<uint64_t*>(msg->GetData())) << "\""; LOG(info) << "Received message: \"" << *(static_cast<uint64_t*>(msg->GetData())) << "\"";

View File

@@ -8,19 +8,24 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
chanAddr1="/tmp/fmq_$session""_""$chan""_1""_""$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;' TERM 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
SAMPLER="fairmq-ex-copypush-sampler" SAMPLER="fairmq-ex-copypush-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $SESSION" SAMPLER+=" --severity debug"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --session $session"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1" SAMPLER+=" --max-iterations 1"
SAMPLER+=" --channel-config name=data,type=push,method=bind,rateLogging=0,address=tcp://*:5555,address=tcp://*:5556" SAMPLER+=" --channel-config name=$chan,type=push,method=bind,rateLogging=0,address=ipc://$chanAddr1,address=ipc://$chanAddr2"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -28,10 +33,12 @@ SINK1="fairmq-ex-copypush-sink"
SINK1+=" --id sink1" SINK1+=" --id sink1"
SINK1+=" --transport $transport" SINK1+=" --transport $transport"
SINK1+=" --verbosity veryhigh" SINK1+=" --verbosity veryhigh"
SINK1+=" --session $SESSION" SINK1+=" --severity debug"
SINK1+=" --shm-segment-size 100000000"
SINK1+=" --session $session"
SINK1+=" --control static --color false" SINK1+=" --control static --color false"
SINK1+=" --max-iterations 1" SINK1+=" --max-iterations 1"
SINK1+=" --channel-config name=data,type=pull,method=connect,rateLogging=0,address=tcp://localhost:5555" SINK1+=" --channel-config name=$chan,type=pull,method=connect,rateLogging=0,address=ipc://$chanAddr1"
@CMAKE_CURRENT_BINARY_DIR@/$SINK1 & @CMAKE_CURRENT_BINARY_DIR@/$SINK1 &
SINK1_PID=$! SINK1_PID=$!
@@ -39,10 +46,12 @@ SINK2="fairmq-ex-copypush-sink"
SINK2+=" --id sink2" SINK2+=" --id sink2"
SINK2+=" --transport $transport" SINK2+=" --transport $transport"
SINK2+=" --verbosity veryhigh" SINK2+=" --verbosity veryhigh"
SINK2+=" --session $SESSION" SINK2+=" --severity debug"
SINK2+=" --shm-segment-size 100000000"
SINK2+=" --session $session"
SINK2+=" --control static --color false" SINK2+=" --control static --color false"
SINK2+=" --max-iterations 1" SINK2+=" --max-iterations 1"
SINK2+=" --channel-config name=data,type=pull,method=connect,rateLogging=0,address=tcp://localhost:5556" SINK2+=" --channel-config name=$chan,type=pull,method=connect,rateLogging=0,address=ipc://$chanAddr2"
@CMAKE_CURRENT_BINARY_DIR@/$SINK2 & @CMAKE_CURRENT_BINARY_DIR@/$SINK2 &
SINK2_PID=$! SINK2_PID=$!
@@ -50,3 +59,5 @@ SINK2_PID=$!
wait $SAMPLER_PID wait $SAMPLER_PID
wait $SINK1_PID wait $SINK1_PID
wait $SINK2_PID wait $SINK2_PID
rm $chanAddr1; rm $chanAddr2

View File

@@ -20,7 +20,7 @@ struct Processor : fair::mq::Device
OnData("data1", &Processor::HandleData); OnData("data1", &Processor::HandleData);
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received data, processing..."; LOG(info) << "Received data, processing...";
@@ -32,7 +32,7 @@ struct Processor : fair::mq::Device
// its size, // its size,
// custom deletion function (called when transfer is done), // custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer // and pointer to the object managing the data buffer
FairMQMessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()), fair::mq::MessagePtr msg2(NewMessage(const_cast<char*>(text->c_str()),
text->length(), text->length(),
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, [](void* /*data*/, void* object) { delete static_cast<std::string*>(object); },
text)); text));

View File

@@ -24,7 +24,7 @@ struct Sampler : fair::mq::Device
{ {
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place). // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy // Should only be used for small data because of the cost of an additional copy
FairMQMessagePtr msg(NewSimpleMessage("Data")); fair::mq::MessagePtr msg(NewSimpleMessage("Data"));
LOG(info) << "Sending \"Data\""; LOG(info) << "Sending \"Data\"";

View File

@@ -25,7 +25,7 @@ struct Sink : fair::mq::Device
fIterations = fConfig->GetValue<uint64_t>("iterations"); fIterations = fConfig->GetValue<uint64_t>("iterations");
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";

View File

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

View File

@@ -5,7 +5,7 @@ A topology of two devices - Sampler and Sink, communicating with PUSH-PULL patte
The Sampler sends a multipart message to the Sink, consisting of two message parts - header and body. The Sampler sends a multipart message to the Sink, consisting of two message parts - header and body.
Each message part is a regular FairMQMessage. To combine them into a multi-part message use `FairMQParts`. Add messages to `FairMQParts` with `AddPart` method. Each message part is a regular fair::mq::Message. To combine them into a multi-part message use `fair::mq::Parts`. Add messages to `fair::mq::Parts` with `AddPart` method.
All parts are guaranteed to be delivered together. The Receive call in the sink will recive the entire parts structure. All parts are guaranteed to be delivered together. The Receive call in the sink will recive the entire parts structure.

View File

@@ -35,15 +35,15 @@ struct Sampler : fair::mq::Device
} }
LOG(info) << "Sending header with stopFlag: " << header.stopFlag; LOG(info) << "Sending header with stopFlag: " << header.stopFlag;
FairMQParts parts; fair::mq::Parts parts;
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place). // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy // Should only be used for small data because of the cost of an additional copy
parts.AddPart(NewSimpleMessage(header)); parts.AddPart(NewSimpleMessage(header));
parts.AddPart(NewMessage(1000)); parts.AddPart(NewMessage(1000));
// create more data parts, testing the FairMQParts in-place constructor // create more data parts, testing the fair::mq::Parts in-place constructor
FairMQParts auxData{ NewMessage(500), NewMessage(600), NewMessage(700) }; fair::mq::Parts auxData{ NewMessage(500), NewMessage(600), NewMessage(700) };
assert(auxData.Size() == 3); assert(auxData.Size() == 3);
parts.AddPart(std::move(auxData)); parts.AddPart(std::move(auxData));
assert(auxData.Size() == 0); assert(auxData.Size() == 0);

View File

@@ -20,7 +20,7 @@ struct Sink : fair::mq::Device
OnData("data", &Sink::HandleData); OnData("data", &Sink::HandleData);
} }
bool HandleData(FairMQParts& parts, int) bool HandleData(fair::mq::Parts& parts, int)
{ {
LOG(info) << "Received message with " << parts.Size() << " parts"; LOG(info) << "Received message with " << parts.Size() << " parts";

View File

@@ -8,19 +8,28 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
chanAddr=""
chanIpcFile="/tmp/fmq_$session""_""$chan""_""$transport"
if [ $transport = "ofi" ]; then
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;' TERM trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID; rm $chanIpcFile' TERM
SAMPLER="fairmq-ex-multipart-sampler" SAMPLER="fairmq-ex-multipart-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --session $SESSION" SAMPLER+=" --session $session"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --max-iterations 1" SAMPLER+=" --max-iterations 1"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --channel-config name=data,type=pair,method=connect,rateLogging=0,address=tcp://127.0.0.1:5555,linger=1000" SAMPLER+=" --channel-config name=$chan,type=pair,method=connect,rateLogging=0,address=$chanAddr,linger=1000"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -28,11 +37,14 @@ SINK="fairmq-ex-multipart-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --transport $transport" SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh"
SINK+=" --session $SESSION" SINK+=" --session $session"
SINK+=" --shm-segment-size 100000000"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --channel-config name=data,type=pair,method=bind,rateLogging=0,address=tcp://127.0.0.1:5555" SINK+=" --channel-config name=$chan,type=pair,method=bind,rateLogging=0,address=$chanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
wait $SAMPLER_PID wait $SAMPLER_PID
wait $SINK_PID wait $SINK_PID
rm $chanIpcFile

View File

@@ -26,7 +26,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh) 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) add_test(NAME Example.MultipleChannels.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.") set_tests_properties(Example.MultipleChannels.zeromq PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received messages from both sources.")
# install # install

View File

@@ -5,4 +5,4 @@ This example demonstrates how to work with multiple channels and multiplex betwe
A topology of three devices - **Sampler**, **Sink** and **Broadcaster**. The Sampler sends data to the Sink via the PUSH-PULL pattern. The Broadcaster device sends a message to both Sampler and Sink containing a string "OK" every second. The Broadcaster sends the message via PUB pattern. Both Sampler and Sink, besides doing their PUSH-PULL job, listen via SUB to the Broadcaster. A topology of three devices - **Sampler**, **Sink** and **Broadcaster**. The Sampler sends data to the Sink via the PUSH-PULL pattern. The Broadcaster device sends a message to both Sampler and Sink containing a string "OK" every second. The Broadcaster sends the message via PUB pattern. Both Sampler and Sink, besides doing their PUSH-PULL job, listen via SUB to the Broadcaster.
The multiplexing between their data channels and the broadcast channels happens with `FairMQPoller`. The multiplexing between their data channels and the broadcast channels happens with `fair::mq::Poller`.

View File

@@ -22,7 +22,7 @@ struct Broadcaster : fair::mq::Device
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place). // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy // Should only be used for small data because of the cost of an additional copy
FairMQMessagePtr msg(NewSimpleMessage("OK")); fair::mq::MessagePtr msg(NewSimpleMessage("OK"));
LOG(info) << "Sending OK"; LOG(info) << "Sending OK";

View File

@@ -7,7 +7,7 @@
********************************************************************************/ ********************************************************************************/
#include <fairmq/Device.h> #include <fairmq/Device.h>
#include <FairMQPoller.h> #include <fairmq/Poller.h>
#include <fairmq/runDevice.h> #include <fairmq/runDevice.h>
#include <chrono> #include <chrono>
@@ -26,13 +26,13 @@ struct Sampler : fair::mq::Device
void Run() override void Run() override
{ {
FairMQPollerPtr poller(NewPoller("data", "broadcast")); fair::mq::PollerPtr poller(NewPoller("data", "broadcast"));
while (!NewStatePending()) { while (!NewStatePending()) {
poller->Poll(100); poller->Poll(100);
if (poller->CheckInput("broadcast", 0)) { if (poller->CheckInput("broadcast", 0)) {
FairMQMessagePtr msg(NewMessage()); fair::mq::MessagePtr msg(NewMessage());
if (Receive(msg, "broadcast") > 0) { if (Receive(msg, "broadcast") > 0) {
LOG(info) << "Received broadcast: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received broadcast: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
@@ -42,7 +42,7 @@ struct Sampler : fair::mq::Device
if (poller->CheckOutput("data", 0)) { if (poller->CheckOutput("data", 0)) {
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
FairMQMessagePtr msg(NewSimpleMessage(fText)); fair::mq::MessagePtr msg(NewSimpleMessage(fText));
if (Send(msg, "data") > 0) { if (Send(msg, "data") > 0) {
LOG(info) << "Sent \"" << fText << "\""; LOG(info) << "Sent \"" << fText << "\"";

View File

@@ -27,7 +27,7 @@ struct Sink : fair::mq::Device
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
bool HandleBroadcast(FairMQMessagePtr& msg, int /*index*/) bool HandleBroadcast(fair::mq::MessagePtr& msg, int /*index*/)
{ {
LOG(info) << "Received broadcast: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received broadcast: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
fReceivedBroadcast = true; fReceivedBroadcast = true;
@@ -35,7 +35,7 @@ struct Sink : fair::mq::Device
return CheckIterations(); return CheckIterations();
} }
bool HandleData(FairMQMessagePtr& msg, int /*index*/) bool HandleData(fair::mq::MessagePtr& msg, int /*index*/)
{ {
LOG(info) << "Received message: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\""; LOG(info) << "Received message: \"" << std::string(static_cast<char*>(msg->GetData()), msg->GetSize()) << "\"";
fReceivedData = true; fReceivedData = true;

View File

@@ -8,18 +8,25 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
# setup a trap to kill everything if the test fails/timeouts session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $BROADCASTER_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $BROADCASTER_PID;' TERM dataChan="data"
broadcastChan="broadcast"
dataChanAddr="/tmp/fmq_$session""_""$dataChan""_""$transport"
broadcastChanAddr="/tmp/fmq_$session""_""$broadcastChan""_""$transport"
# 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
SINK="fairmq-ex-multiple-channels-sink" SINK="fairmq-ex-multiple-channels-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --session $session"
SINK+=" --transport $transport" SINK+=" --transport $transport"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh --severity debug"
SINK+=" --shm-segment-size 100000000"
SINK+=" --max-iterations 1" SINK+=" --max-iterations 1"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --channel-config name=data,type=pull,method=connect,rateLogging=0,address=tcp://localhost:5555" SINK+=" --channel-config name=$dataChan,type=pull,method=connect,rateLogging=0,address=ipc://$dataChanAddr"
SINK+=" name=broadcast,type=sub,method=connect,rateLogging=0,address=tcp://localhost:5005" SINK+=" name=$broadcastChan,type=sub,method=connect,rateLogging=0,address=ipc://$broadcastChanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
@@ -27,21 +34,25 @@ sleep 1
SAMPLER="fairmq-ex-multiple-channels-sampler" SAMPLER="fairmq-ex-multiple-channels-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --session $session"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh --severity debug"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --max-iterations 1" SAMPLER+=" --max-iterations 1"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --channel-config name=data,type=push,method=bind,rateLogging=0,address=tcp://*:5555" SAMPLER+=" --channel-config name=$dataChan,type=push,method=bind,rateLogging=0,address=ipc://$dataChanAddr"
SAMPLER+=" name=broadcast,type=sub,method=connect,rateLogging=0,address=tcp://localhost:5005" SAMPLER+=" name=$broadcastChan,type=sub,method=connect,rateLogging=0,address=ipc://$broadcastChanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
BROADCASTER="fairmq-ex-multiple-channels-broadcaster" BROADCASTER="fairmq-ex-multiple-channels-broadcaster"
BROADCASTER+=" --id broadcaster1" BROADCASTER+=" --id broadcaster1"
BROADCASTER+=" --session $session"
BROADCASTER+=" --transport $transport" BROADCASTER+=" --transport $transport"
BROADCASTER+=" --verbosity veryhigh" BROADCASTER+=" --verbosity veryhigh --severity debug"
BROADCASTER+=" --shm-segment-size 100000000"
BROADCASTER+=" --control static --color false" BROADCASTER+=" --control static --color false"
BROADCASTER+=" --channel-config name=broadcast,type=pub,method=bind,rateLogging=0,address=tcp://*:5005" BROADCASTER+=" --channel-config name=$broadcastChan,type=pub,method=bind,rateLogging=0,address=ipc://$broadcastChanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$BROADCASTER & @CMAKE_CURRENT_BINARY_DIR@/$BROADCASTER &
BROADCASTER_PID=$! BROADCASTER_PID=$!
@@ -53,3 +64,5 @@ kill -SIGINT $BROADCASTER_PID
# wait for broadcaster to finish # wait for broadcaster to finish
wait $BROADCASTER_PID wait $BROADCASTER_PID
rm $dataChanAddr; rm $broadcastChanAddr

View File

@@ -25,7 +25,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-transports.s
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-transports.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-transports.sh) 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) add_test(NAME Example.MultipleTransports COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-transports.sh)
set_tests_properties(Example.MultipleTransports PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.") set_tests_properties(Example.MultipleTransports PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received messages from both sources.")
# install # install

View File

@@ -28,7 +28,7 @@ struct Sampler1 : fair::mq::Device
bool ConditionalRun() override bool ConditionalRun() override
{ {
// Creates a message using the transport of channel data1 // Creates a message using the transport of channel data1
FairMQMessagePtr msg(NewMessageFor("data1", 0, 1000000)); fair::mq::MessagePtr msg(NewMessageFor("data1", 0, 1000000));
// in case of error or transfer interruption, return false to go to IDLE state // in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message). // successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).
@@ -54,7 +54,7 @@ struct Sampler1 : fair::mq::Device
uint64_t numAcks = 0; uint64_t numAcks = 0;
while (!NewStatePending()) { while (!NewStatePending()) {
FairMQMessagePtr ack(NewMessageFor("ack", 0)); fair::mq::MessagePtr ack(NewMessageFor("ack", 0));
if (Receive(ack, "ack") < 0) { if (Receive(ack, "ack") < 0) {
break; break;
} }

View File

@@ -22,7 +22,7 @@ struct Sampler2 : fair::mq::Device
bool ConditionalRun() override bool ConditionalRun() override
{ {
FairMQMessagePtr msg(NewMessage(1000)); fair::mq::MessagePtr msg(NewMessage(1000));
// in case of error or transfer interruption, return false to go to IDLE state // in case of error or transfer interruption, return false to go to IDLE state
// successfull transfer will return number of bytes transfered (can be 0 if sending an empty message). // successfull transfer will return number of bytes transfered (can be 0 if sending an empty message).

View File

@@ -26,11 +26,11 @@ struct Sink : fair::mq::Device
} }
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0) // handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
bool HandleData1(FairMQMessagePtr& /*msg*/, int /*index*/) bool HandleData1(fair::mq::MessagePtr& /*msg*/, int /*index*/)
{ {
fNumIterations1++; fNumIterations1++;
// Creates a message using the transport of channel ack // Creates a message using the transport of channel ack
FairMQMessagePtr ack(NewMessageFor("ack", 0)); fair::mq::MessagePtr ack(NewMessageFor("ack", 0));
if (Send(ack, "ack") < 0) { if (Send(ack, "ack") < 0) {
return false; return false;
} }
@@ -40,7 +40,7 @@ struct Sink : fair::mq::Device
} }
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0) // handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
bool HandleData2(FairMQMessagePtr& /*msg*/, int /*index*/) bool HandleData2(fair::mq::MessagePtr& /*msg*/, int /*index*/)
{ {
fNumIterations2++; fNumIterations2++;
// 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)

View File

@@ -2,46 +2,57 @@
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)"
chan1="data1"
chan2="data2"
ackChan="ack"
chan1Addr="/tmp/fmq_$session""_""$chan1"
chan2Addr="/tmp/fmq_$session""_""$chan2"
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;' TERM 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
SINK="fairmq-ex-multiple-transports-sink" SINK="fairmq-ex-multiple-transports-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh --severity debug"
SINK+=" --session $SESSION" SINK+=" --shm-segment-size 100000000"
SINK+=" --session $session"
SINK+=" --max-iterations 1" SINK+=" --max-iterations 1"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --transport shmem" SINK+=" --transport shmem"
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555" SINK+=" --channel-config name=$chan1,type=pull,method=connect,address=ipc://$chan1Addr"
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=zeromq" SINK+=" name=$chan2,type=pull,method=connect,address=ipc://$chan2Addr,transport=zeromq"
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq" SINK+=" name=$ackChan,type=pub,method=connect,address=ipc://$ackChanAddr,transport=zeromq"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
SAMPLER1="fairmq-ex-multiple-transports-sampler1" SAMPLER1="fairmq-ex-multiple-transports-sampler1"
SAMPLER1+=" --id sampler1" SAMPLER1+=" --id sampler1"
SAMPLER1+=" --session $SESSION" SAMPLER1+=" --session $session"
SAMPLER1+=" --verbosity veryhigh" SAMPLER1+=" --verbosity veryhigh --severity debug"
SAMPLER1+=" --shm-segment-size 100000000"
SAMPLER1+=" --max-iterations 1" SAMPLER1+=" --max-iterations 1"
SAMPLER1+=" --control static --color false" SAMPLER1+=" --control static --color false"
SAMPLER1+=" --transport shmem" SAMPLER1+=" --transport shmem"
SAMPLER1+=" --channel-config name=data1,type=push,method=bind,address=tcp://127.0.0.1:5555" SAMPLER1+=" --channel-config name=$chan1,type=push,method=bind,address=ipc://$chan1Addr"
SAMPLER1+=" name=ack,type=sub,method=bind,address=tcp://127.0.0.1:5557,transport=zeromq" SAMPLER1+=" name=$ackChan,type=sub,method=bind,address=ipc://$ackChanAddr,transport=zeromq"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER1 & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER1 &
SAMPLER1_PID=$! SAMPLER1_PID=$!
SAMPLER2="fairmq-ex-multiple-transports-sampler2" SAMPLER2="fairmq-ex-multiple-transports-sampler2"
SAMPLER2+=" --id sampler2" SAMPLER2+=" --id sampler2"
SAMPLER2+=" --session $SESSION" SAMPLER2+=" --session $session"
SAMPLER2+=" --verbosity veryhigh" SAMPLER2+=" --verbosity veryhigh --severity debug"
SAMPLER2+=" --shm-segment-size 100000000"
SAMPLER2+=" --max-iterations 1" SAMPLER2+=" --max-iterations 1"
SAMPLER2+=" --control static --color false" SAMPLER2+=" --control static --color false"
SAMPLER2+=" --transport zeromq" SAMPLER2+=" --transport zeromq"
SAMPLER2+=" --channel-config name=data2,type=push,method=bind,address=tcp://127.0.0.1:5556" SAMPLER2+=" --channel-config name=$chan2,type=push,method=bind,address=ipc://$chan2Addr"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER2 & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER2 &
SAMPLER2_PID=$! SAMPLER2_PID=$!
wait $SAMPLER1_PID wait $SAMPLER1_PID
wait $SAMPLER2_PID wait $SAMPLER2_PID
wait $SINK_PID wait $SINK_PID
rm $chan1Addr; rm $chan2Addr; rm $ackChanAddr

View File

@@ -24,7 +24,7 @@ namespace bpo = boost::program_options;
struct TFBuffer struct TFBuffer
{ {
FairMQParts parts; fair::mq::Parts parts;
chrono::steady_clock::time_point start; chrono::steady_clock::time_point start;
chrono::steady_clock::time_point end; chrono::steady_clock::time_point end;
}; };
@@ -43,7 +43,7 @@ struct Receiver : fair::mq::Device
fMaxTimeframes = GetConfig()->GetValue<int>("max-timeframes"); fMaxTimeframes = GetConfig()->GetValue<int>("max-timeframes");
} }
bool HandleData(FairMQParts& parts, int /* index */) bool HandleData(fair::mq::Parts& parts, int /* index */)
{ {
Header& h = *(static_cast<Header*>(parts.At(0)->GetData())); Header& h = *(static_cast<Header*>(parts.At(0)->GetData()));
// LOG(info) << "Received sub-time frame #" << h.id << " from Sender" << h.senderIndex; // LOG(info) << "Received sub-time frame #" << h.id << " from Sender" << h.senderIndex;
@@ -107,7 +107,7 @@ void addCustomOptions(bpo::options_description& options)
("max-timeframes", bpo::value<int>()->default_value(0), "Maximum number of timeframes to receive (0 - unlimited)"); ("max-timeframes", bpo::value<int>()->default_value(0), "Maximum number of timeframes to receive (0 - unlimited)");
} }
std::unique_ptr<fair::mq::Device> getDevice(FairMQProgOptions& /* config */) std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /* config */)
{ {
return std::make_unique<Receiver>(); return std::make_unique<Receiver>();
} }

View File

@@ -28,11 +28,11 @@ struct Sender : fair::mq::Device
void Run() override void Run() override
{ {
FairMQChannel& dataInChannel = fChannels.at("sync").at(0); fair::mq::Channel& dataInChannel = GetChannel("sync", 0);
while (!NewStatePending()) { while (!NewStatePending()) {
Header h; Header h;
FairMQMessagePtr id(NewMessage()); fair::mq::MessagePtr id(NewMessage());
if (dataInChannel.Receive(id) > 0) { if (dataInChannel.Receive(id) > 0) {
h.id = *(static_cast<uint16_t*>(id->GetData())); h.id = *(static_cast<uint16_t*>(id->GetData()));
h.senderIndex = fIndex; h.senderIndex = fIndex;
@@ -40,7 +40,7 @@ struct Sender : fair::mq::Device
continue; continue;
} }
FairMQParts parts; fair::mq::Parts parts;
parts.AddPart(NewSimpleMessage(h)); parts.AddPart(NewSimpleMessage(h));
parts.AddPart(NewMessage(fSubtimeframeSize)); parts.AddPart(NewMessage(fSubtimeframeSize));
@@ -66,7 +66,7 @@ void addCustomOptions(bpo::options_description& options)
("subtimeframe-size", bpo::value<int>()->default_value(1000), "Subtimeframe size in bytes") ("subtimeframe-size", bpo::value<int>()->default_value(1000), "Subtimeframe size in bytes")
("num-receivers", bpo::value<int>()->required(), "Number of EPNs"); ("num-receivers", bpo::value<int>()->required(), "Number of EPNs");
} }
std::unique_ptr<fair::mq::Device> getDevice(FairMQProgOptions& /* config */) std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /* config */)
{ {
return std::make_unique<Sender>(); return std::make_unique<Sender>();
} }

View File

@@ -19,7 +19,7 @@ struct Synchronizer : fair::mq::Device
{ {
bool ConditionalRun() override bool ConditionalRun() override
{ {
FairMQMessagePtr msg(NewSimpleMessage(fTimeframeId)); fair::mq::MessagePtr msg(NewSimpleMessage(fTimeframeId));
if (Send(msg, "sync") > 0) { if (Send(msg, "sync") > 0) {
if (++fTimeframeId == UINT16_MAX - 1) { if (++fTimeframeId == UINT16_MAX - 1) {
@@ -37,7 +37,7 @@ struct Synchronizer : fair::mq::Device
}; };
void addCustomOptions(bpo::options_description& /* options */) {} void addCustomOptions(bpo::options_description& /* options */) {}
std::unique_ptr<fair::mq::Device> getDevice(FairMQProgOptions& /* config */) std::unique_ptr<fair::mq::Device> getDevice(fair::mq::ProgOptions& /* config */)
{ {
return std::make_unique<Synchronizer>(); return std::make_unique<Synchronizer>();
} }

View File

@@ -30,10 +30,10 @@ struct QCDispatcher : fair::mq::Device
}); });
} }
bool HandleData(FairMQMessagePtr& msg, int) bool HandleData(fair::mq::MessagePtr& msg, int)
{ {
if (fDoQC.load() == true) { if (fDoQC.load() == true) {
FairMQMessagePtr msgCopy(NewMessage()); fair::mq::MessagePtr msgCopy(NewMessage());
msgCopy->Copy(*msg); msgCopy->Copy(*msg);
if (Send(msg, "qc") < 0) { if (Send(msg, "qc") < 0) {
return false; return false;

View File

@@ -9,12 +9,12 @@
#include <fairmq/Device.h> #include <fairmq/Device.h>
#include <fairmq/runDevice.h> #include <fairmq/runDevice.h>
class QCTask : public FairMQDevice class QCTask : public fair::mq::Device
{ {
public: public:
QCTask() QCTask()
{ {
OnData("qc", [](FairMQMessagePtr& /*msg*/, int) { OnData("qc", [](fair::mq::MessagePtr& /*msg*/, int) {
LOG(info) << "received data"; LOG(info) << "received data";
return false; return false;
}); });

View File

@@ -16,7 +16,7 @@ struct Sampler : fair::mq::Device
{ {
bool ConditionalRun() override bool ConditionalRun() override
{ {
FairMQMessagePtr msg(NewMessage(1000)); fair::mq::MessagePtr msg(NewMessage(1000));
if (Send(msg, "data1") < 0) { if (Send(msg, "data1") < 0) {
return false; return false;

View File

@@ -14,7 +14,7 @@
struct Sink : fair::mq::Device struct Sink : fair::mq::Device
{ {
Sink() { OnData("data2", &Sink::HandleData); } Sink() { OnData("data2", &Sink::HandleData); }
bool HandleData(FairMQMessagePtr& /*msg*/, int /*index*/) { return true; } bool HandleData(fair::mq::MessagePtr& /*msg*/, int /*index*/) { return true; }
}; };
namespace bpo = boost::program_options; namespace bpo = boost::program_options;

View File

@@ -13,7 +13,7 @@
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
class Builder : public FairMQDevice class Builder : public fair::mq::Device
{ {
public: public:
Builder() = default; Builder() = default;
@@ -24,7 +24,7 @@ class Builder : public FairMQDevice
OnData("rb", &Builder::HandleData); OnData("rb", &Builder::HandleData);
} }
bool HandleData(FairMQMessagePtr& msg, int /*index*/) bool HandleData(fair::mq::MessagePtr& msg, int /*index*/)
{ {
if (Send(msg, fOutputChannelName) < 0) { if (Send(msg, fOutputChannelName) < 0) {
return false; return false;

View File

@@ -18,9 +18,9 @@ struct Processor : fair::mq::Device
OnData("bp", &Processor::HandleData); OnData("bp", &Processor::HandleData);
} }
bool HandleData(FairMQMessagePtr& msg, int /*index*/) bool HandleData(fair::mq::MessagePtr& msg, int /*index*/)
{ {
FairMQMessagePtr msg2(NewMessageFor("ps", 0, msg->GetSize())); fair::mq::MessagePtr msg2(NewMessageFor("ps", 0, msg->GetSize()));
if (Send(msg2, "ps") < 0) { if (Send(msg2, "ps") < 0) {
return false; return false;
} }

View File

@@ -22,7 +22,7 @@ struct Readout : fair::mq::Device
fMsgSize = fConfig->GetProperty<int>("msg-size"); fMsgSize = fConfig->GetProperty<int>("msg-size");
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("rb", fRegion = fair::mq::UnmanagedRegionPtr(NewUnmanagedRegionFor("rb",
0, 0,
10000000, 10000000,
[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
@@ -36,7 +36,7 @@ struct Readout : fair::mq::Device
bool ConditionalRun() override bool ConditionalRun() override
{ {
FairMQMessagePtr msg(NewMessageFor("rb", // channel fair::mq::MessagePtr msg(NewMessageFor("rb", // channel
0, // sub-channel 0, // sub-channel
fRegion, // region fRegion, // region
fRegion->GetData(), // ptr within region fRegion->GetData(), // ptr within region
@@ -71,7 +71,7 @@ struct Readout : fair::mq::Device
int fMsgSize = 10000; int fMsgSize = 10000;
uint64_t fMaxIterations = 0; uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0; uint64_t fNumIterations = 0;
FairMQUnmanagedRegionPtr fRegion = nullptr; fair::mq::UnmanagedRegionPtr fRegion = nullptr;
std::atomic<uint64_t> fNumUnackedMsgs = 0; std::atomic<uint64_t> fNumUnackedMsgs = 0;
}; };

View File

@@ -26,7 +26,7 @@ struct Receiver : Device
void Run() override void Run() override
{ {
Channel& dataInChannel = fChannels.at("sr").at(0); Channel& dataInChannel = GetChannel("sr", 0);
while (!NewStatePending()) { while (!NewStatePending()) {
auto msg(dataInChannel.NewMessage()); auto msg(dataInChannel.NewMessage());

View File

@@ -21,7 +21,7 @@ struct Sender : fair::mq::Device
OnData(fInputChannelName, &Sender::HandleData); OnData(fInputChannelName, &Sender::HandleData);
} }
bool HandleData(FairMQMessagePtr& msg, int /*index*/) bool HandleData(fair::mq::MessagePtr& msg, int /*index*/)
{ {
if (Send(msg, "sr") < 0) { if (Send(msg, "sr") < 0) {
return false; return false;

View File

@@ -12,7 +12,10 @@ target_link_libraries(fairmq-ex-region-sampler PRIVATE FairMQ)
add_executable(fairmq-ex-region-sink sink.cxx) add_executable(fairmq-ex-region-sink sink.cxx)
target_link_libraries(fairmq-ex-region-sink PRIVATE FairMQ) target_link_libraries(fairmq-ex-region-sink PRIVATE FairMQ)
add_custom_target(ExampleRegion DEPENDS fairmq-ex-region-sampler fairmq-ex-region-sink) 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(EX_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq) set(FAIRMQ_BIN_DIR ${CMAKE_BINARY_DIR}/fairmq)
@@ -23,10 +26,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh) 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) add_test(NAME Example.Region.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh zeromq)
set_tests_properties(Example.Region.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks") 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) add_test(NAME Example.Region.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh shmem)
set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received [0-9*] acks") set_tests_properties(Example.Region.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received [0-9*] acks")
# install # install

View File

@@ -0,0 +1,144 @@
/********************************************************************************
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include <fairmq/shmem/Common.h>
#include <fairmq/shmem/UnmanagedRegion.h>
#include <fairmq/shmem/Segment.h>
#include <fairmq/shmem/Monitor.h>
#include <fairmq/tools/Unique.h>
#include <fairlogger/Logger.h>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <csignal>
#include <chrono>
#include <map>
#include <string>
#include <thread>
using namespace std;
using namespace boost::program_options;
namespace
{
volatile sig_atomic_t gStopping = 0;
}
void signalHandler(int /* signal */)
{
gStopping = 1;
}
struct ShmManager
{
ShmManager(uint64_t _shmId, const vector<string>& _segments, const vector<string>& _regions)
: shmId(fair::mq::shmem::makeShmIdStr(_shmId))
{
for (const auto& s : _segments) {
vector<string> segmentConf;
boost::algorithm::split(segmentConf, s, boost::algorithm::is_any_of(","));
if (segmentConf.size() != 2) {
LOG(error) << "incorrect format for --segments. Expecting pairs of <id>,<size>.";
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
throw runtime_error("incorrect format for --segments. Expecting pairs of <id>,<size>.");
}
uint16_t id = stoi(segmentConf.at(0));
uint64_t size = stoull(segmentConf.at(1));
auto ret = segments.emplace(id, fair::mq::shmem::Segment(shmId, id, size, fair::mq::shmem::rbTreeBestFit));
fair::mq::shmem::Segment& segment = ret.first->second;
LOG(info) << "Created segment " << id << " of size " << segment.GetSize() << ", starting at " << segment.GetData() << ". Locking...";
segment.Lock();
LOG(info) << "Done.";
LOG(info) << "Zeroing...";
segment.Zero();
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));
fair::mq::shmem::UnmanagedRegion& region = *(ret.first->second);
LOG(info) << "Created unamanged region " << id << " of size " << region.GetSize() << ", starting at " << region.GetData() << ". Locking...";
region.Lock();
LOG(info) << "Done.";
LOG(info) << "Zeroing...";
region.Zero();
LOG(info) << "Done.";
}
}
void ResetContent()
{
fair::mq::shmem::Monitor::ResetContent(fair::mq::shmem::ShmId{shmId});
}
~ShmManager()
{
// clean all segments, regions and any other shmem objects belonging to this shmId
fair::mq::shmem::Monitor::Cleanup(fair::mq::shmem::ShmId{shmId});
}
std::string shmId;
map<uint16_t, fair::mq::shmem::Segment> segments;
map<uint16_t, unique_ptr<fair::mq::shmem::UnmanagedRegion>> regions;
};
int main(int argc, char** argv)
{
fair::Logger::SetConsoleColor(true);
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
try {
uint64_t shmId = 0;
vector<string> segments;
vector<string> regions;
options_description desc("Options");
desc.add_options()
("shmid", value<uint64_t>(&shmId)->required(), "Shm id")
("segments", value<vector<string>>(&segments)->multitoken()->composing(), "Segments, as <id>,<size> <id>,<size> <id>,<size> ...")
("regions", value<vector<string>>(&regions)->multitoken()->composing(), "Regions, as <id>,<size> <id>,<size> <id>,<size> ...")
("help,h", "Print help");
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
LOG(info) << "ShmManager" << "\n" << desc;
return 0;
}
notify(vm);
ShmManager shmManager(shmId, segments, regions);
while (!gStopping) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
LOG(info) << "stopping.";
} catch (exception& e) {
LOG(error) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit";
return 2;
}
return 0;
}

View File

@@ -23,7 +23,7 @@ struct Sampler : fair::mq::Device
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");
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) { GetChannel("data", 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
@@ -32,27 +32,25 @@ struct Sampler : fair::mq::Device
<< ", flags: " << info.flags; << ", flags: " << info.flags;
}); });
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data", // region is created using the transport of this channel... fair::mq::RegionConfig regionCfg;
regionCfg.linger = fLinger; // delay in ms before region destruction to collect outstanding events
regionCfg.lock = true; // mlock region after creation
regionCfg.zero = true; // zero region content after creation
fRegion = fair::mq::UnmanagedRegionPtr(NewUnmanagedRegionFor("data", // 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
std::lock_guard<std::mutex> lock(fMtx); std::lock_guard<std::mutex> lock(fMtx);
fNumUnackedMsgs -= blocks.size(); fNumUnackedMsgs -= blocks.size();
if (fMaxIterations > 0) { if (fMaxIterations > 0) {
LOG(info) << "Received " << blocks.size() << " acks"; LOG(info) << "Received " << blocks.size() << " acks";
} }
}, }, regionCfg));
"", // path, if a region is backed by a file
0, // flags that are passed for region creation
fair::mq::RegionConfig{true, true} // additional config: { call mlock on the region, zero the region memory }
));
fRegion->SetLinger(fLinger);
} }
bool ConditionalRun() override bool ConditionalRun() override
{ {
FairMQMessagePtr msg(NewMessageFor("data", // channel fair::mq::MessagePtr msg(NewMessageFor("data", // channel
0, // sub-channel 0, // sub-channel
fRegion, // region fRegion, // region
fRegion->GetData(), // ptr within region fRegion->GetData(), // ptr within region
@@ -87,7 +85,7 @@ struct Sampler : fair::mq::Device
LOG(info) << "All acknowledgements received."; LOG(info) << "All acknowledgements received.";
} }
} }
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents(); GetChannel("data", 0).Transport()->UnsubscribeFromRegionEvents();
} }
private: private:
@@ -95,7 +93,7 @@ struct Sampler : fair::mq::Device
uint32_t fLinger = 100; uint32_t fLinger = 100;
uint64_t fMaxIterations = 0; uint64_t fMaxIterations = 0;
uint64_t fNumIterations = 0; uint64_t fNumIterations = 0;
FairMQUnmanagedRegionPtr fRegion = nullptr; fair::mq::UnmanagedRegionPtr fRegion = nullptr;
std::mutex fMtx; std::mutex fMtx;
uint64_t fNumUnackedMsgs = 0; uint64_t fNumUnackedMsgs = 0;
}; };

View File

@@ -22,7 +22,7 @@ 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");
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](RegionInfo info) { GetChannel("data", 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,7 +32,7 @@ struct Sink : Device
void Run() override void Run() override
{ {
Channel& dataInChannel = fChannels.at("data").at(0); Channel& dataInChannel = GetChannel("data", 0);
while (!NewStatePending()) { while (!NewStatePending()) {
auto msg(dataInChannel.Transport()->CreateMessage()); auto msg(dataInChannel.Transport()->CreateMessage());
@@ -51,7 +51,7 @@ struct Sink : Device
void ResetTask() override void ResetTask() override
{ {
fChannels.at("data").at(0).Transport()->UnsubscribeFromRegionEvents(); GetChannel("data", 0).Transport()->UnsubscribeFromRegionEvents();
} }
private: private:

View File

@@ -9,22 +9,25 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
fi fi
msgSize="1000000" msgSize="1000000"
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
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' TERM 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
SAMPLER="fairmq-ex-region-sampler" SAMPLER="fairmq-ex-region-sampler"
SAMPLER+=" --id sampler1" SAMPLER+=" --id sampler1"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
SAMPLER+=" --severity debug" SAMPLER+=" --severity debug"
SAMPLER+=" --session $SESSION" SAMPLER+=" --session $session"
SAMPLER+=" --shm-segment-size 100000000"
SAMPLER+=" --verbosity veryhigh" SAMPLER+=" --verbosity veryhigh"
SAMPLER+=" --control static --color false" SAMPLER+=" --control static --color false"
SAMPLER+=" --max-iterations 1" SAMPLER+=" --max-iterations 1"
SAMPLER+=" --msg-size $msgSize" SAMPLER+=" --msg-size $msgSize"
SAMPLER+=" --region-linger 500" SAMPLER+=" --region-linger 500"
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777" SAMPLER+=" --channel-config name=$chan,type=push,method=bind,address=ipc://$chanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER & @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
SAMPLER_PID=$! SAMPLER_PID=$!
@@ -32,14 +35,17 @@ SINK="fairmq-ex-region-sink"
SINK+=" --id sink1" SINK+=" --id sink1"
SINK+=" --transport $transport" SINK+=" --transport $transport"
SINK+=" --severity debug" SINK+=" --severity debug"
SINK+=" --session $SESSION" SINK+=" --session $session"
SINK+=" --shm-segment-size 100000000"
SINK+=" --verbosity veryhigh" SINK+=" --verbosity veryhigh"
SINK+=" --control static --color false" SINK+=" --control static --color false"
SINK+=" --max-iterations 1" SINK+=" --max-iterations 1"
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:7777" SINK+=" --channel-config name=$chan,type=pull,method=connect,address=ipc://$chanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SINK & @CMAKE_CURRENT_BINARY_DIR@/$SINK &
SINK_PID=$! SINK_PID=$!
# wait for sampler and sink to finish # wait for sampler and sink to finish
wait $SAMPLER_PID wait $SAMPLER_PID
wait $SINK_PID wait $SINK_PID
rm $chanAddr

View File

@@ -24,10 +24,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh) 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) add_test(NAME Example.ReqRep.zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh zeromq)
set_tests_properties(Example.ReqRep.zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ") 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) add_test(NAME Example.ReqRep.shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh shmem)
set_tests_properties(Example.ReqRep.shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ") set_tests_properties(Example.ReqRep.shmem PROPERTIES TIMEOUT "30" PASS_REGULAR_EXPRESSION "Received reply from server: ")
# install # install

View File

@@ -32,11 +32,11 @@ struct Client : fair::mq::Device
// its size, // its size,
// custom deletion function (called when transfer is done), // custom deletion function (called when transfer is done),
// and pointer to the object managing the data buffer // and pointer to the object managing the data buffer
FairMQMessagePtr req(NewMessage(const_cast<char*>(text->c_str()), // data fair::mq::MessagePtr req(NewMessage(const_cast<char*>(text->c_str()), // data
text->length(), // size text->length(), // size
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, // deletion callback [](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, // deletion callback
text)); // object that manages the data text)); // object that manages the data
FairMQMessagePtr rep(NewMessage()); fair::mq::MessagePtr rep(NewMessage());
LOG(info) << "Sending \"" << fText << "\" to server."; LOG(info) << "Sending \"" << fText << "\" to server.";

View File

@@ -26,7 +26,7 @@ struct Server : fair::mq::Device
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations"); fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
} }
bool HandleData(FairMQMessagePtr& req, int) bool HandleData(fair::mq::MessagePtr& req, int)
{ {
LOG(info) << "Received request from client: \"" << std::string(static_cast<char*>(req->GetData()), req->GetSize()) << "\""; LOG(info) << "Received request from client: \"" << std::string(static_cast<char*>(req->GetData()), req->GetSize()) << "\"";
@@ -34,7 +34,7 @@ struct Server : fair::mq::Device
LOG(info) << "Sending reply to client."; LOG(info) << "Sending reply to client.";
FairMQMessagePtr rep(NewMessage(const_cast<char*>(text->c_str()), // data fair::mq::MessagePtr rep(NewMessage(const_cast<char*>(text->c_str()), // data
text->length(), // size text->length(), // size
[](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, // deletion callback [](void* /*data*/, void* object) { delete static_cast<std::string*>(object); }, // deletion callback
text)); // object that manages the data text)); // object that manages the data

View File

@@ -8,19 +8,22 @@ if [[ $1 =~ ^[a-z]+$ ]]; then
transport=$1 transport=$1
fi fi
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)" session="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
chan="data"
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;' TERM trap 'kill -TERM $CLIENT_PID; kill -TERM $SERVER_PID; wait $CLIENT_PID; wait $SERVER_PID; rm $chanAddr' TERM
CLIENT="fairmq-ex-req-rep-client" CLIENT="fairmq-ex-req-rep-client"
CLIENT+=" --id client" CLIENT+=" --id client"
CLIENT+=" --transport $transport" CLIENT+=" --transport $transport"
CLIENT+=" --verbosity veryhigh" CLIENT+=" --verbosity veryhigh"
CLIENT+=" --session $SESSION" CLIENT+=" --session $session"
CLIENT+=" --shm-segment-size 100000000"
CLIENT+=" --control static --color false" CLIENT+=" --control static --color false"
CLIENT+=" --max-iterations 1" CLIENT+=" --max-iterations 1"
CLIENT+=" --channel-config name=data,type=req,method=connect,rateLogging=0,address=tcp://127.0.0.1:5005" CLIENT+=" --channel-config name=$chan,type=req,method=connect,rateLogging=0,address=ipc://$chanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$CLIENT & @CMAKE_CURRENT_BINARY_DIR@/$CLIENT &
CLIENT_PID=$! CLIENT_PID=$!
@@ -28,13 +31,16 @@ SERVER="fairmq-ex-req-rep-server"
SERVER+=" --id server" SERVER+=" --id server"
SERVER+=" --transport $transport" SERVER+=" --transport $transport"
SERVER+=" --verbosity veryhigh" SERVER+=" --verbosity veryhigh"
SERVER+=" --session $SESSION" SERVER+=" --session $session"
SERVER+=" --shm-segment-size 100000000"
SERVER+=" --control static --color false" SERVER+=" --control static --color false"
SERVER+=" --max-iterations 1" SERVER+=" --max-iterations 1"
SERVER+=" --channel-config name=data,type=rep,method=bind,rateLogging=0,address=tcp://127.0.0.1:5005" SERVER+=" --channel-config name=$chan,type=rep,method=bind,rateLogging=0,address=ipc://$chanAddr"
@CMAKE_CURRENT_BINARY_DIR@/$SERVER & @CMAKE_CURRENT_BINARY_DIR@/$SERVER &
SERVER_PID=$! SERVER_PID=$!
# wait for everything to finish # wait for everything to finish
wait $CLIENT_PID wait $CLIENT_PID
wait $SERVER_PID wait $SERVER_PID
rm $chanAddr

View File

@@ -30,7 +30,9 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
set(TOOLS_PUBLIC_HEADER_FILES set(TOOLS_PUBLIC_HEADER_FILES
tools/CppSTL.h tools/CppSTL.h
tools/Exceptions.h
tools/InstanceLimit.h tools/InstanceLimit.h
tools/IO.h
tools/Network.h tools/Network.h
tools/Process.h tools/Process.h
tools/RateLimit.h tools/RateLimit.h
@@ -190,6 +192,9 @@ if(BUILD_FAIRMQ)
runDevice.h runDevice.h
runFairMQDevice.h runFairMQDevice.h
shmem/Monitor.h shmem/Monitor.h
shmem/Common.h
shmem/UnmanagedRegion.h
shmem/Segment.h
) )
set(FAIRMQ_PRIVATE_HEADER_FILES set(FAIRMQ_PRIVATE_HEADER_FILES
@@ -204,12 +209,11 @@ if(BUILD_FAIRMQ)
plugins/control/Control.h plugins/control/Control.h
shmem/Message.h shmem/Message.h
shmem/Poller.h shmem/Poller.h
shmem/UnmanagedRegion.h shmem/UnmanagedRegionImpl.h
shmem/Socket.h shmem/Socket.h
shmem/TransportFactory.h shmem/TransportFactory.h
shmem/Common.h
shmem/Manager.h shmem/Manager.h
shmem/Region.h zeromq/Common.h
zeromq/Context.h zeromq/Context.h
zeromq/Message.h zeromq/Message.h
zeromq/Poller.h zeromq/Poller.h
@@ -246,6 +250,7 @@ if(BUILD_FAIRMQ)
TransportFactory.cxx TransportFactory.cxx
plugins/config/Config.cxx plugins/config/Config.cxx
plugins/control/Control.cxx plugins/control/Control.cxx
shmem/Common.cxx
shmem/Manager.cxx shmem/Manager.cxx
shmem/Monitor.cxx shmem/Monitor.cxx
) )
@@ -382,7 +387,7 @@ if(BUILD_FAIRMQ)
fairmq_target_tidy(TARGET fairmq-splitter) fairmq_target_tidy(TARGET fairmq-splitter)
endif() endif()
add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx) add_executable(fairmq-shmmonitor shmem/Common.cxx shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx)
target_compile_features(fairmq-shmmonitor PUBLIC cxx_std_17) target_compile_features(fairmq-shmmonitor PUBLIC cxx_std_17)
target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY) target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY)
if(FAIRMQ_DEBUG_MODE) if(FAIRMQ_DEBUG_MODE)

View File

@@ -39,6 +39,8 @@ constexpr int Channel::DefaultSndBufSize;
constexpr int Channel::DefaultRcvBufSize; constexpr int Channel::DefaultRcvBufSize;
constexpr int Channel::DefaultSndKernelSize; constexpr int Channel::DefaultSndKernelSize;
constexpr int Channel::DefaultRcvKernelSize; constexpr int Channel::DefaultRcvKernelSize;
constexpr int Channel::DefaultSndTimeoutMs;
constexpr int Channel::DefaultRcvTimeoutMs;
constexpr int Channel::DefaultLinger; constexpr int Channel::DefaultLinger;
constexpr int Channel::DefaultRateLogging; constexpr int Channel::DefaultRateLogging;
constexpr int Channel::DefaultPortRangeMin; constexpr int Channel::DefaultPortRangeMin;
@@ -73,6 +75,8 @@ Channel::Channel(string name, string type, string method, string address, shared
, fRcvBufSize(DefaultRcvBufSize) , fRcvBufSize(DefaultRcvBufSize)
, fSndKernelSize(DefaultSndKernelSize) , fSndKernelSize(DefaultSndKernelSize)
, fRcvKernelSize(DefaultRcvKernelSize) , fRcvKernelSize(DefaultRcvKernelSize)
, fSndTimeoutMs(DefaultSndTimeoutMs)
, fRcvTimeoutMs(DefaultRcvTimeoutMs)
, fLinger(DefaultLinger) , fLinger(DefaultLinger)
, fRateLogging(DefaultRateLogging) , fRateLogging(DefaultRateLogging)
, fPortRangeMin(DefaultPortRangeMin) , fPortRangeMin(DefaultPortRangeMin)
@@ -97,6 +101,8 @@ Channel::Channel(const string& name, int index, const Properties& properties)
fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), DefaultRcvBufSize); fRcvBufSize = GetPropertyOrDefault(properties, string(prefix + "rcvBufSize"), DefaultRcvBufSize);
fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), DefaultSndKernelSize); fSndKernelSize = GetPropertyOrDefault(properties, string(prefix + "sndKernelSize"), DefaultSndKernelSize);
fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), DefaultRcvKernelSize); fRcvKernelSize = GetPropertyOrDefault(properties, string(prefix + "rcvKernelSize"), DefaultRcvKernelSize);
fSndTimeoutMs = GetPropertyOrDefault(properties, string(prefix + "sndTimeoutMs"), DefaultSndTimeoutMs);
fRcvTimeoutMs = GetPropertyOrDefault(properties, string(prefix + "rcvTimeoutMs"), DefaultRcvTimeoutMs);
fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), DefaultLinger); fLinger = GetPropertyOrDefault(properties, string(prefix + "linger"), DefaultLinger);
fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), DefaultRateLogging); fRateLogging = GetPropertyOrDefault(properties, string(prefix + "rateLogging"), DefaultRateLogging);
fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), DefaultPortRangeMin); fPortRangeMin = GetPropertyOrDefault(properties, string(prefix + "portRangeMin"), DefaultPortRangeMin);
@@ -120,6 +126,8 @@ Channel::Channel(const Channel& chan, string newName)
, fRcvBufSize(chan.fRcvBufSize) , fRcvBufSize(chan.fRcvBufSize)
, fSndKernelSize(chan.fSndKernelSize) , fSndKernelSize(chan.fSndKernelSize)
, fRcvKernelSize(chan.fRcvKernelSize) , fRcvKernelSize(chan.fRcvKernelSize)
, fSndTimeoutMs(chan.fSndTimeoutMs)
, fRcvTimeoutMs(chan.fRcvTimeoutMs)
, fLinger(chan.fLinger) , fLinger(chan.fLinger)
, fRateLogging(chan.fRateLogging) , fRateLogging(chan.fRateLogging)
, fPortRangeMin(chan.fPortRangeMin) , fPortRangeMin(chan.fPortRangeMin)
@@ -146,6 +154,8 @@ Channel& Channel::operator=(const Channel& chan)
fRcvBufSize = chan.fRcvBufSize; fRcvBufSize = chan.fRcvBufSize;
fSndKernelSize = chan.fSndKernelSize; fSndKernelSize = chan.fSndKernelSize;
fRcvKernelSize = chan.fRcvKernelSize; fRcvKernelSize = chan.fRcvKernelSize;
fSndTimeoutMs = chan.fSndTimeoutMs;
fRcvTimeoutMs = chan.fRcvTimeoutMs;
fLinger = chan.fLinger; fLinger = chan.fLinger;
fRateLogging = chan.fRateLogging; fRateLogging = chan.fRateLogging;
fPortRangeMin = chan.fPortRangeMin; fPortRangeMin = chan.fPortRangeMin;

View File

@@ -9,7 +9,6 @@
#ifndef FAIR_MQ_CHANNEL_H #ifndef FAIR_MQ_CHANNEL_H
#define FAIR_MQ_CHANNEL_H #define FAIR_MQ_CHANNEL_H
#include <cstdint> // int64_t
#include <fairmq/Message.h> #include <fairmq/Message.h>
#include <fairmq/Parts.h> #include <fairmq/Parts.h>
#include <fairmq/Properties.h> #include <fairmq/Properties.h>
@@ -17,8 +16,9 @@
#include <fairmq/TransportFactory.h> #include <fairmq/TransportFactory.h>
#include <fairmq/Transports.h> #include <fairmq/Transports.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
#include <cstdint> // int64_t
#include <memory> // unique_ptr, shared_ptr #include <memory> // unique_ptr, shared_ptr
#include <mutex>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <utility> // std::move #include <utility> // std::move
@@ -73,21 +73,25 @@ class Channel
Channel(const Channel&, std::string name); Channel(const Channel&, std::string name);
/// Move constructor /// Move constructor
// Channel(Channel&&) = delete; Channel(Channel&&) = default;
/// Assignment operator /// Assignment operator
Channel& operator=(const Channel&); Channel& operator=(const Channel&);
/// Move assignment operator /// Move assignment operator
// Channel& operator=(Channel&&) = delete; Channel& operator=(Channel&&) = default;
/// Destructor /// Destructor
virtual ~Channel() = default; ~Channel() = default;
// { LOG(warn) << "Destroying channel '" << fName << "'"; } // { LOG(warn) << "Destroying channel '" << fName << "'"; }
struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; }; struct ChannelConfigurationError : std::runtime_error { using std::runtime_error::runtime_error; };
Socket& GetSocket() const { assert(fSocket); return *fSocket; } Socket& GetSocket() const
{
assert(fSocket); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
return *fSocket;
}
bool Bind(const std::string& address) bool Bind(const std::string& address)
{ {
@@ -162,6 +166,14 @@ class Channel
/// @return Returns socket kernel transmit receive buffer size (in bytes) /// @return Returns socket kernel transmit receive buffer size (in bytes)
int GetRcvKernelSize() const { return fRcvKernelSize; } int GetRcvKernelSize() const { return fRcvKernelSize; }
/// Get socket default send timeout (in ms)
/// @return Returns socket default send timeout (in ms)
int GetSndTimeout() const { return fSndTimeoutMs; }
/// Get socket default receive timeout (in ms)
/// @return Returns socket default receive timeout (in ms)
int GetRcvTimeout() const { return fRcvTimeoutMs; }
/// Get linger duration (in milliseconds) /// Get linger duration (in milliseconds)
/// @return Returns linger duration (in milliseconds) /// @return Returns linger duration (in milliseconds)
int GetLinger() const { return fLinger; } int GetLinger() const { return fLinger; }
@@ -182,6 +194,14 @@ class Channel
/// @return true/false, true if automatic binding is enabled /// @return true/false, true if automatic binding is enabled
bool GetAutoBind() const { return fAutoBind; } bool GetAutoBind() const { return fAutoBind; }
/// @par Thread Safety
/// * @e Distinct @e objects: Safe.@n
/// * @e Shared @e objects: Unsafe.
auto GetNumberOfConnectedPeers() const
{
return fSocket ? fSocket->GetNumberOfConnectedPeers() : 0;
}
/// Set channel name /// Set channel name
/// @param name Arbitrary channel name /// @param name Arbitrary channel name
void UpdateName(const std::string& name) { fName = name; Invalidate(); } void UpdateName(const std::string& name) { fName = name; Invalidate(); }
@@ -204,39 +224,47 @@ class Channel
/// 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)
void UpdateSndBufSize(const int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); } void UpdateSndBufSize(int sndBufSize) { fSndBufSize = sndBufSize; Invalidate(); }
/// Set socket receive buffer size /// Set socket receive buffer size
/// @param rcvBufSize Socket receive buffer size (in number of messages) /// @param rcvBufSize Socket receive buffer size (in number of messages)
void UpdateRcvBufSize(const int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); } void UpdateRcvBufSize(int rcvBufSize) { fRcvBufSize = rcvBufSize; Invalidate(); }
/// Set socket kernel transmit send buffer size (in bytes) /// Set socket kernel transmit send buffer size (in bytes)
/// @param sndKernelSize Socket send buffer size (in bytes) /// @param sndKernelSize Socket send buffer size (in bytes)
void UpdateSndKernelSize(const int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); } void UpdateSndKernelSize(int sndKernelSize) { fSndKernelSize = sndKernelSize; Invalidate(); }
/// Set socket kernel transmit receive buffer size (in bytes) /// Set socket kernel transmit receive buffer size (in bytes)
/// @param rcvKernelSize Socket receive buffer size (in bytes) /// @param rcvKernelSize Socket receive buffer size (in bytes)
void UpdateRcvKernelSize(const int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); } void UpdateRcvKernelSize(int rcvKernelSize) { fRcvKernelSize = rcvKernelSize; Invalidate(); }
/// Set socket default send timeout (in ms)
/// @param sndTimeoutMs Socket default send timeout (in ms)
void UpdateSndTimeout(int sndTimeoutMs) { fSndTimeoutMs = sndTimeoutMs; Invalidate(); }
/// Set socket default receive timeout (in ms)
/// @param rcvTimeoutMs Socket default receive timeout (in ms)
void UpdateRcvTimeout(int rcvTimeoutMs) { fRcvTimeoutMs = rcvTimeoutMs; Invalidate(); }
/// Set linger duration (in milliseconds) /// Set linger duration (in milliseconds)
/// @param duration linger duration (in milliseconds) /// @param duration linger duration (in milliseconds)
void UpdateLinger(const int duration) { fLinger = duration; Invalidate(); } void UpdateLinger(int duration) { fLinger = duration; Invalidate(); }
/// Set socket rate logging interval (in seconds) /// Set socket rate logging interval (in seconds)
/// @param rateLogging Socket rate logging interval (in seconds) /// @param rateLogging Socket rate logging interval (in seconds)
void UpdateRateLogging(const int rateLogging) { fRateLogging = rateLogging; Invalidate(); } void UpdateRateLogging(int rateLogging) { fRateLogging = rateLogging; Invalidate(); }
/// Set start of the port range for automatic binding /// Set start of the port range for automatic binding
/// @param minPort start of the port range /// @param minPort start of the port range
void UpdatePortRangeMin(const int minPort) { fPortRangeMin = minPort; Invalidate(); } void UpdatePortRangeMin(int minPort) { fPortRangeMin = minPort; Invalidate(); }
/// Set end of the port range for automatic binding /// Set end of the port range for automatic binding
/// @param maxPort end of the port range /// @param maxPort end of the port range
void UpdatePortRangeMax(const int maxPort) { fPortRangeMax = maxPort; Invalidate(); } void UpdatePortRangeMax(int maxPort) { fPortRangeMax = maxPort; Invalidate(); }
/// Set automatic binding (pick random port if bind fails) /// Set automatic binding (pick random port if bind fails)
/// @param autobind true/false, true to enable automatic binding /// @param autobind true/false, true to enable automatic binding
void UpdateAutoBind(const bool autobind) { fAutoBind = autobind; Invalidate(); } void UpdateAutoBind(bool autobind) { fAutoBind = autobind; Invalidate(); }
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel())) /// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
/// @return true if channel settings are valid, false otherwise. /// @return true if channel settings are valid, false otherwise.
@@ -255,62 +283,52 @@ class Channel
/// invalidates the channel (requires validation to be used again). /// invalidates the channel (requires validation to be used again).
void Invalidate() { fValid = false; } void Invalidate() { fValid = false; }
/// Sends a message to the socket queue. /// Send message(s) to the socket queue.
/// @param msg Constant reference of unique_ptr to a Message /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send) /// @param sndTimeoutMs send timeout in ms.
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change) /// -1 will wait forever (or until interrupt (e.g. via state change)),
int64_t Send(MessagePtr& msg, int sndTimeoutInMs = -1) /// 0 will not wait (return immediately if cannot send).
/// If not provided, default timeout will be taken.
/// @return Number of bytes that have been queued,
/// TransferCode::timeout if timed out,
/// TransferCode::error if there was an error,
/// TransferCode::interrupted if interrupted (e.g. by requested state change)
template<typename M, typename... Timeout>
std::enable_if_t<is_transferrable<M>::value, int64_t>
Send(M& m, Timeout&&... sndTimeoutMs)
{ {
CheckSendCompatibility(msg); static_assert(sizeof...(sndTimeoutMs) <= 1, "Send called with too many arguments");
return fSocket->Send(msg, sndTimeoutInMs);
CheckSendCompatibility(m);
int t = fSndTimeoutMs;
if constexpr (sizeof...(sndTimeoutMs) == 1) {
t = {sndTimeoutMs...};
}
return fSocket->Send(m, t);
} }
/// Receives a message from the socket queue. /// Receive message(s) from the socket queue.
/// @param msg Constant reference of unique_ptr to a Message /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive) /// @param rcvTimeoutMs receive timeout in ms.
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change) /// -1 will wait forever (or until interrupt (e.g. via state change)),
int64_t Receive(MessagePtr& msg, int rcvTimeoutInMs = -1) /// 0 will not wait (return immediately if cannot receive).
/// If not provided, default timeout will be taken.
/// @return Number of bytes that have been received,
/// TransferCode::timeout if timed out,
/// TransferCode::error if there was an error,
/// TransferCode::interrupted if interrupted (e.g. by requested state change)
template<typename M, typename... Timeout>
std::enable_if_t<is_transferrable<M>::value, int64_t>
Receive(M& m, Timeout&&... rcvTimeoutMs)
{ {
CheckReceiveCompatibility(msg); static_assert(sizeof...(rcvTimeoutMs) <= 1, "Receive called with too many arguments");
return fSocket->Receive(msg, rcvTimeoutInMs);
}
/// Send a vector of messages CheckReceiveCompatibility(m);
/// @param msgVec message vector reference int t = fRcvTimeoutMs;
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send) if constexpr (sizeof...(rcvTimeoutMs) == 1) {
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change) t = {rcvTimeoutMs...};
int64_t Send(std::vector<MessagePtr>& msgVec, int sndTimeoutInMs = -1)
{
CheckSendCompatibility(msgVec);
return fSocket->Send(msgVec, sndTimeoutInMs);
} }
return fSocket->Receive(m, t);
/// Receive a vector of messages
/// @param msgVec message vector reference
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(std::vector<MessagePtr>& msgVec, int rcvTimeoutInMs = -1)
{
CheckReceiveCompatibility(msgVec);
return fSocket->Receive(msgVec, rcvTimeoutInMs);
}
/// Send Parts
/// @param parts Parts reference
/// @param sndTimeoutInMs send timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot send)
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Send(Parts& parts, int sndTimeoutInMs = -1)
{
return Send(parts.fParts, sndTimeoutInMs);
}
/// Receive Parts
/// @param parts Parts reference
/// @param rcvTimeoutInMs receive timeout in ms. -1 will wait forever (or until interrupt (e.g. via state change)), 0 will not wait (return immediately if cannot receive)
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by requested state change)
int64_t Receive(Parts& parts, int rcvTimeoutInMs = -1)
{
return Receive(parts.fParts, rcvTimeoutInMs);
} }
unsigned long GetBytesTx() const { return fSocket->GetBytesTx(); } unsigned long GetBytesTx() const { return fSocket->GetBytesTx(); }
@@ -354,6 +372,8 @@ class Channel
static constexpr int DefaultRcvBufSize = 1000; static constexpr int DefaultRcvBufSize = 1000;
static constexpr int DefaultSndKernelSize = 0; static constexpr int DefaultSndKernelSize = 0;
static constexpr int DefaultRcvKernelSize = 0; static constexpr int DefaultRcvKernelSize = 0;
static constexpr int DefaultSndTimeoutMs = -1;
static constexpr int DefaultRcvTimeoutMs = -1;
static constexpr int DefaultLinger = 500; static constexpr int DefaultLinger = 500;
static constexpr int DefaultRateLogging = 1; static constexpr int DefaultRateLogging = 1;
static constexpr int DefaultPortRangeMin = 22000; static constexpr int DefaultPortRangeMin = 22000;
@@ -373,6 +393,8 @@ class Channel
int fRcvBufSize; int fRcvBufSize;
int fSndKernelSize; int fSndKernelSize;
int fRcvKernelSize; int fRcvKernelSize;
int fSndTimeoutMs;
int fRcvTimeoutMs;
int fLinger; int fLinger;
int fRateLogging; int fRateLogging;
int fPortRangeMin; int fPortRangeMin;
@@ -402,6 +424,7 @@ class Channel
} }
} }
void CheckSendCompatibility(Parts& parts) { CheckSendCompatibility(parts.fParts); }
void CheckSendCompatibility(std::vector<MessagePtr>& msgVec) void CheckSendCompatibility(std::vector<MessagePtr>& msgVec)
{ {
for (auto& msg : msgVec) { for (auto& msg : msgVec) {
@@ -431,6 +454,7 @@ class Channel
} }
} }
void CheckReceiveCompatibility(Parts& parts) { CheckReceiveCompatibility(parts.fParts); }
void CheckReceiveCompatibility(std::vector<MessagePtr>& msgVec) void CheckReceiveCompatibility(std::vector<MessagePtr>& msgVec)
{ {
for (auto& msg : msgVec) { for (auto& msg : msgVec) {

View File

@@ -47,6 +47,11 @@ struct StateSubscription
}); });
} }
StateSubscription(const StateSubscription&) = delete;
StateSubscription(StateSubscription&&) = delete;
StateSubscription& operator=(const StateSubscription&) = delete;
StateSubscription& operator=(StateSubscription&&) = delete;
~StateSubscription() { ~StateSubscription() {
fStateMachine.UnsubscribeFromStateChange(fId); fStateMachine.UnsubscribeFromStateChange(fId);
} }
@@ -60,15 +65,15 @@ Device::Device(ProgOptions& config)
: Device(&config, {0, 0, 0}) : Device(&config, {0, 0, 0})
{} {}
Device::Device(const tools::Version version) Device::Device(tools::Version version)
: Device(nullptr, version) : Device(nullptr, version)
{} {}
Device::Device(ProgOptions& config, const tools::Version version) Device::Device(ProgOptions& config, tools::Version version)
: Device(&config, version) : Device(&config, version)
{} {}
Device::Device(ProgOptions* config, const 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>())
, fConfig(config ? config : fInternalConfig.get()) , fConfig(config ? config : fInternalConfig.get())
@@ -133,7 +138,7 @@ Device::Device(ProgOptions* config, const tools::Version version)
fStateMachine.Start(); fStateMachine.Start();
} }
void Device::TransitionTo(const State s) void Device::TransitionTo(State s)
{ {
{ {
lock_guard<mutex> lock(fTransitionMtx); lock_guard<mutex> lock(fTransitionMtx);
@@ -430,7 +435,7 @@ void Device::InitTaskWrapper()
void Device::RunWrapper() void Device::RunWrapper()
{ {
LOG(info) << "DEVICE: Running..."; LOG(info) << "fair::mq::Device running...";
// start the rate logger thread // start the rate logger thread
future<void> rateLogger = async(launch::async, &Device::LogSocketRates, this); future<void> rateLogger = async(launch::async, &Device::LogSocketRates, this);
@@ -440,7 +445,11 @@ void Device::RunWrapper()
t.second->Resume(); t.second->Resume();
} }
try { // change to Error state in case of an exception, to release LogSocketRates
tools::CallOnDestruction cod([&](){
ChangeState(Transition::ErrorFound);
});
PreRun(); PreRun();
// process either data callbacks or ConditionalRun/Run // process either data callbacks or ConditionalRun/Run
@@ -470,15 +479,8 @@ void Device::RunWrapper()
} }
PostRun(); PostRun();
} catch (const out_of_range& oor) {
LOG(error) << "out of range: " << oor.what(); cod.disable();
LOG(error) << "incorrect/incomplete channel configuration?";
ChangeState(Transition::ErrorFound);
throw;
} catch (...) {
ChangeState(Transition::ErrorFound);
throw;
}
rateLogger.get(); rateLogger.get();
} }

View File

@@ -53,15 +53,17 @@ class Device
public: public:
Device(); Device();
Device(ProgOptions& config); Device(ProgOptions& config);
Device(const tools::Version version); Device(tools::Version version);
Device(ProgOptions& config, const tools::Version version); Device(ProgOptions& config, tools::Version version);
private: private:
Device(ProgOptions* config, const tools::Version version); Device(ProgOptions* config, tools::Version version);
public: public:
Device(const Device&) = delete; Device(const Device&) = delete;
Device operator=(const Device&) = delete; Device(Device&&) = delete;
Device& operator=(const Device&) = delete;
Device& operator=(Device&&) = delete;
virtual ~Device(); virtual ~Device();
/// Outputs the socket transfer rates /// Outputs the socket transfer rates
@@ -79,72 +81,70 @@ class Device
Deserializer().Deserialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...); Deserializer().Deserialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
} }
/// Shorthand method to send `msg` on `chan` at index `i` /// Send `m` on `chan` at index `i`
/// @param msg message reference /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param chan channel name /// @param chan channel name
/// @param i channel index /// @param i channel index
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via /// @return Number of queued bytes,
/// state change)), 0 will not wait (return immediately if cannot send) /// TransferCode::timeout if timed out,
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, /// TransferCode::error if there was an error,
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by /// TransferCode::interrupted if interrupted (e.g. by requested state change)
/// requested state change) template<typename M>
int64_t Send(MessagePtr& msg, std::enable_if_t<is_transferrable<M>::value, int64_t>
const std::string& channel, Send(M& m, const std::string& channel, const int index = 0)
const int index = 0,
int sndTimeoutInMs = -1)
{ {
return GetChannel(channel, index).Send(msg, sndTimeoutInMs); return GetChannel(channel, index).Send(m);
} }
/// Shorthand method to receive `msg` on `chan` at index `i` /// Receive `m` on `chan` at index `i`
/// @param msg message reference /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param chan channel name /// @param chan channel name
/// @param i channel index /// @param i channel index
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. /// @return Number of received bytes,
/// via state change)), 0 will not wait (return immediately if cannot receive) /// TransferCode::timeout if timed out,
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, /// TransferCode::error if there was an error,
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by /// TransferCode::interrupted if interrupted (e.g. by requested state change)
/// requested state change) template<typename M>
int64_t Receive(MessagePtr& msg, std::enable_if_t<is_transferrable<M>::value, int64_t>
const std::string& channel, Receive(M& m, const std::string& channel, const int index = 0)
const int index = 0,
int rcvTimeoutInMs = -1)
{ {
return GetChannel(channel, index).Receive(msg, rcvTimeoutInMs); return GetChannel(channel, index).Receive(m);
} }
/// Shorthand method to send Parts on `chan` at index `i` /// Send `m` on `chan` at index `i`
/// @param parts parts reference /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param chan channel name /// @param chan channel name
/// @param i channel index /// @param i channel index
/// @param sndTimeoutInMs send timeout in ms, -1 will wait forever (or until interrupt (e.g. via /// @param sndTimeoutMs send timeout in ms,
/// state change)), 0 will not wait (return immediately if cannot send) /// -1 will wait forever (or until interrupt (e.g. via state change)),
/// @return Number of bytes that have been queued, TransferCode::timeout if timed out, /// 0 will not wait (return immediately if cannot send)
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by /// @return Number of queued bytes,
/// requested state change) /// TransferCode::timeout if timed out,
int64_t Send(Parts& parts, /// TransferCode::error if there was an error,
const std::string& channel, /// TransferCode::interrupted if interrupted (e.g. by requested state change)
const int index = 0, template<typename M>
int sndTimeoutInMs = -1) std::enable_if_t<is_transferrable<M>::value, int64_t>
Send(M& m, const std::string& channel, const int index, int sndTimeoutMs)
{ {
return GetChannel(channel, index).Send(parts.fParts, sndTimeoutInMs); return GetChannel(channel, index).Send(m, sndTimeoutMs);
} }
/// Shorthand method to receive Parts on `chan` at index `i` /// Receive `m` on `chan` at index `i`
/// @param parts parts reference /// @param m reference to MessagePtr/Parts/vector<MessagePtr>
/// @param chan channel name /// @param chan channel name
/// @param i channel index /// @param i channel index
/// @param rcvTimeoutInMs receive timeout in ms, -1 will wait forever (or until interrupt (e.g. /// @param rcvTimeoutMs receive timeout in ms,
/// via state change)), 0 will not wait (return immediately if cannot receive) /// -1 will wait forever (or until interrupt (e.g. via state change),
/// @return Number of bytes that have been received, TransferCode::timeout if timed out, /// 0 will not wait (return immediately if cannot receive)
/// TransferCode::error if there was an error, TransferCode::interrupted if interrupted (e.g. by /// @return Number of received bytes,
/// requested state change) /// TransferCode::timeout if timed out,
int64_t Receive(Parts& parts, /// TransferCode::error if there was an error,
const std::string& channel, /// TransferCode::interrupted if interrupted (e.g. by requested state change)
const int index = 0, template<typename M>
int rcvTimeoutInMs = -1) std::enable_if_t<is_transferrable<M>::value, int64_t>
Receive(M& m, const std::string& channel, const int index, int rcvTimeoutMs)
{ {
return GetChannel(channel, index).Receive(parts.fParts, rcvTimeoutInMs); return GetChannel(channel, index).Receive(m, rcvTimeoutMs);
} }
/// @brief Getter for default transport factory /// @brief Getter for default transport factory
@@ -252,7 +252,7 @@ class Device
/// Adds a transport to the device if it doesn't exist /// Adds a transport to the device if it doesn't exist
/// @param transport Transport string ("zeromq"/"shmem") /// @param transport Transport string ("zeromq"/"shmem")
std::shared_ptr<TransportFactory> AddTransport(const mq::Transport transport); std::shared_ptr<TransportFactory> AddTransport(mq::Transport transport);
/// Assigns config to the device /// Assigns config to the device
void SetConfig(ProgOptions& config); void SetConfig(ProgOptions& config);
@@ -318,13 +318,26 @@ class Device
try { try {
return fChannels.at(channelName).at(index); return fChannels.at(channelName).at(index);
} catch (const std::out_of_range& oor) { } catch (const std::out_of_range& oor) {
LOG(error) LOG(error) << "GetChannel(): '" << channelName << "[" << index << "]' does not exist.";
<< "requested channel has not been configured? check channel names/configuration.";
LOG(error) << "channel: " << channelName << ", index: " << index;
LOG(error) << "out of range: " << oor.what();
throw; throw;
} }
size_t GetNumSubChannels(const std::string& channelName)
try {
return fChannels.at(channelName).size();
} catch (const std::out_of_range& oor) {
LOG(error) << "GetNumSubChannels(): '" << channelName << "' does not exist.";
throw;
}
/// @brief Get numbers of connected peers for the given channel
/// @param name channel name
/// @param index sub-channel
unsigned long GetNumberOfConnectedPeers(const std::string& channelName, int index = 0)
{
return fChannels.at(channelName).at(index).GetNumberOfConnectedPeers();
}
virtual void RegisterChannelEndpoints() {} virtual void RegisterChannelEndpoints() {}
bool RegisterChannelEndpoint(const std::string& channelName, bool RegisterChannelEndpoint(const std::string& channelName,
@@ -489,7 +502,7 @@ 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(const State 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
@@ -537,11 +550,11 @@ class Device
/// @brief Returns name of the given state as a string /// @brief Returns name of the given state as a string
/// @param state state /// @param state state
[[deprecated("Use fair::mq::GetStateName from <fairmq/States.h> directly")]] [[deprecated("Use fair::mq::GetStateName from <fairmq/States.h> directly")]]
static std::string GetStateName(const State state) { return fair::mq::GetStateName(state); } static std::string GetStateName(State state) { return fair::mq::GetStateName(state); }
/// @brief Returns name of the given transition as a string /// @brief Returns name of the given transition as a string
/// @param transition transition /// @param transition transition
[[deprecated("Use fair::mq::GetTransitionName from <fairmq/States.h> directly")]] [[deprecated("Use fair::mq::GetTransitionName from <fairmq/States.h> directly")]]
static std::string GetTransitionName(const Transition transition) static std::string GetTransitionName(Transition transition)
{ {
return fair::mq::GetTransitionName(transition); return fair::mq::GetTransitionName(transition);
} }

View File

@@ -120,7 +120,7 @@ auto DeviceRunner::Run() -> int
fPluginManager.ForEachPluginProgOptions([&](boost::program_options::options_description options) { fPluginManager.ForEachPluginProgOptions([&](boost::program_options::options_description options) {
fConfig.AddToCmdLineOptions(options); fConfig.AddToCmdLineOptions(options);
}); });
fConfig.AddToCmdLineOptions(fPluginManager.ProgramOptions()); fConfig.AddToCmdLineOptions(PluginManager::ProgramOptions());
////// CALL HOOK /////// ////// CALL HOOK ///////
fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this); fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);
@@ -128,7 +128,7 @@ auto DeviceRunner::Run() -> int
fConfig.ParseAll(fRawCmdLineArgs, true); fConfig.ParseAll(fRawCmdLineArgs, true);
if (!HandleGeneralOptions(fConfig)) { if (!HandleGeneralOptions(fConfig, fPrintLogo)) {
return 0; return 0;
} }

View File

@@ -9,10 +9,15 @@
#ifndef FAIR_MQ_ERROR_H #ifndef FAIR_MQ_ERROR_H
#define FAIR_MQ_ERROR_H #define FAIR_MQ_ERROR_H
#include <cassert>
#include <fairmq/tools/Strings.h> #include <fairmq/tools/Strings.h>
#include <stdexcept> #include <stdexcept>
#include <system_error> #include <system_error>
// Macro copied from https://en.cppreference.com/w/cpp/error/assert
// Use (void) to silent unused warnings.
#define assertm(exp, msg) assert(((void)msg, exp))
namespace fair::mq { namespace fair::mq {
struct RuntimeError : ::std::runtime_error struct RuntimeError : ::std::runtime_error

View File

@@ -30,13 +30,13 @@
using namespace std; using namespace std;
using namespace fair::mq; using namespace fair::mq;
using namespace fair::mq::tools; using namespace tools;
using namespace boost::property_tree; using namespace boost::property_tree;
namespace fair::mq namespace fair::mq
{ {
fair::mq::Properties PtreeParser(const ptree& pt, const string& id) Properties PtreeParser(const ptree& pt, const string& id)
{ {
if (id.empty()) { if (id.empty()) {
throw ParserError("no device ID provided. Provide with `--id` cmd option"); throw ParserError("no device ID provided. Provide with `--id` cmd option");
@@ -47,7 +47,7 @@ fair::mq::Properties PtreeParser(const ptree& pt, const string& id)
return helper::DeviceParser(pt.get_child("fairMQOptions"), id); return helper::DeviceParser(pt.get_child("fairMQOptions"), id);
} }
fair::mq::Properties JSONParser(const string& filename, const string& deviceId) Properties JSONParser(const string& filename, const string& deviceId)
{ {
ptree pt; ptree pt;
LOG(debug) << "Parsing JSON from " << filename << " ..."; LOG(debug) << "Parsing JSON from " << filename << " ...";
@@ -58,9 +58,9 @@ fair::mq::Properties JSONParser(const string& filename, const string& deviceId)
namespace helper namespace helper
{ {
fair::mq::Properties DeviceParser(const ptree& fairMQOptions, const string& deviceId) Properties DeviceParser(const ptree& fairMQOptions, const string& deviceId)
{ {
fair::mq::Properties properties; Properties properties;
for (const auto& node : fairMQOptions) { for (const auto& node : fairMQOptions) {
if (node.first == "devices") { if (node.first == "devices") {
@@ -82,25 +82,27 @@ fair::mq::Properties DeviceParser(const ptree& fairMQOptions, const string& devi
return properties; return properties;
} }
void ChannelParser(const ptree& tree, fair::mq::Properties& properties) void ChannelParser(const ptree& tree, Properties& properties)
{ {
for (const auto& node : tree) { for (const auto& node : tree) {
if (node.first == "channels") { if (node.first == "channels") {
for (const auto& cn : node.second) { for (const auto& cn : node.second) {
fair::mq::Properties commonProperties; Properties commonProperties;
commonProperties.emplace("type", cn.second.get<string>("type", FairMQChannel::DefaultType)); commonProperties.emplace("type", cn.second.get<string>("type", Channel::DefaultType));
commonProperties.emplace("method", cn.second.get<string>("method", FairMQChannel::DefaultMethod)); commonProperties.emplace("method", cn.second.get<string>("method", Channel::DefaultMethod));
commonProperties.emplace("address", cn.second.get<string>("address", FairMQChannel::DefaultAddress)); commonProperties.emplace("address", cn.second.get<string>("address", Channel::DefaultAddress));
commonProperties.emplace("transport", cn.second.get<string>("transport", FairMQChannel::DefaultTransportName)); commonProperties.emplace("transport", cn.second.get<string>("transport", Channel::DefaultTransportName));
commonProperties.emplace("sndBufSize", cn.second.get<int>("sndBufSize", FairMQChannel::DefaultSndBufSize)); commonProperties.emplace("sndBufSize", cn.second.get<int>("sndBufSize", Channel::DefaultSndBufSize));
commonProperties.emplace("rcvBufSize", cn.second.get<int>("rcvBufSize", FairMQChannel::DefaultRcvBufSize)); commonProperties.emplace("rcvBufSize", cn.second.get<int>("rcvBufSize", Channel::DefaultRcvBufSize));
commonProperties.emplace("sndKernelSize", cn.second.get<int>("sndKernelSize", FairMQChannel::DefaultSndKernelSize)); commonProperties.emplace("sndKernelSize", cn.second.get<int>("sndKernelSize", Channel::DefaultSndKernelSize));
commonProperties.emplace("rcvKernelSize", cn.second.get<int>("rcvKernelSize", FairMQChannel::DefaultRcvKernelSize)); commonProperties.emplace("rcvKernelSize", cn.second.get<int>("rcvKernelSize", Channel::DefaultRcvKernelSize));
commonProperties.emplace("linger", cn.second.get<int>("linger", FairMQChannel::DefaultLinger)); commonProperties.emplace("sndTimeoutMs", cn.second.get<int>("sndTimeoutMs", Channel::DefaultSndTimeoutMs));
commonProperties.emplace("rateLogging", cn.second.get<int>("rateLogging", FairMQChannel::DefaultRateLogging)); commonProperties.emplace("rcvTimeoutMs", cn.second.get<int>("rcvTimeoutMs", Channel::DefaultRcvTimeoutMs));
commonProperties.emplace("portRangeMin", cn.second.get<int>("portRangeMin", FairMQChannel::DefaultPortRangeMin)); commonProperties.emplace("linger", cn.second.get<int>("linger", Channel::DefaultLinger));
commonProperties.emplace("portRangeMax", cn.second.get<int>("portRangeMax", FairMQChannel::DefaultPortRangeMax)); commonProperties.emplace("rateLogging", cn.second.get<int>("rateLogging", Channel::DefaultRateLogging));
commonProperties.emplace("autoBind", cn.second.get<bool>("autoBind", FairMQChannel::DefaultAutoBind)); commonProperties.emplace("portRangeMin", cn.second.get<int>("portRangeMin", Channel::DefaultPortRangeMin));
commonProperties.emplace("portRangeMax", cn.second.get<int>("portRangeMax", Channel::DefaultPortRangeMax));
commonProperties.emplace("autoBind", cn.second.get<bool>("autoBind", Channel::DefaultAutoBind));
string name = cn.second.get<string>("name"); string name = cn.second.get<string>("name");
int numSockets = cn.second.get<int>("numSockets", 0); int numSockets = cn.second.get<int>("numSockets", 0);
@@ -126,7 +128,7 @@ void ChannelParser(const ptree& tree, fair::mq::Properties& properties)
} }
} }
void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties, const string& channelName, const fair::mq::Properties& commonProperties) void SubChannelParser(const ptree& channelTree, Properties& properties, const string& channelName, const Properties& commonProperties)
{ {
// for each socket in channel // for each socket in channel
int i = 0; int i = 0;
@@ -135,7 +137,7 @@ void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties
if (node.first == "sockets") { if (node.first == "sockets") {
for (const auto& sn : node.second) { for (const auto& sn : node.second) {
// a sub-channel inherits relevant properties from the common channel ... // a sub-channel inherits relevant properties from the common channel ...
fair::mq::Properties newProperties(commonProperties); Properties newProperties(commonProperties);
// ... and adds/overwrites its own properties // ... and adds/overwrites its own properties
newProperties["type"] = sn.second.get<string>("type", boost::any_cast<string>(commonProperties.at("type"))); newProperties["type"] = sn.second.get<string>("type", boost::any_cast<string>(commonProperties.at("type")));
@@ -146,6 +148,8 @@ void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties
newProperties["rcvBufSize"] = sn.second.get<int>("rcvBufSize", boost::any_cast<int>(commonProperties.at("rcvBufSize"))); newProperties["rcvBufSize"] = sn.second.get<int>("rcvBufSize", boost::any_cast<int>(commonProperties.at("rcvBufSize")));
newProperties["sndKernelSize"] = sn.second.get<int>("sndKernelSize", boost::any_cast<int>(commonProperties.at("sndKernelSize"))); newProperties["sndKernelSize"] = sn.second.get<int>("sndKernelSize", boost::any_cast<int>(commonProperties.at("sndKernelSize")));
newProperties["rcvKernelSize"] = sn.second.get<int>("rcvKernelSize", boost::any_cast<int>(commonProperties.at("rcvKernelSize"))); newProperties["rcvKernelSize"] = sn.second.get<int>("rcvKernelSize", boost::any_cast<int>(commonProperties.at("rcvKernelSize")));
newProperties["sndTimeoutMs"] = sn.second.get<int>("sndTimeoutMs", boost::any_cast<int>(commonProperties.at("sndTimeoutMs")));
newProperties["rcvTimeoutMs"] = sn.second.get<int>("rcvTimeoutMs", boost::any_cast<int>(commonProperties.at("rcvTimeoutMs")));
newProperties["linger"] = sn.second.get<int>("linger", boost::any_cast<int>(commonProperties.at("linger"))); newProperties["linger"] = sn.second.get<int>("linger", boost::any_cast<int>(commonProperties.at("linger")));
newProperties["rateLogging"] = sn.second.get<int>("rateLogging", boost::any_cast<int>(commonProperties.at("rateLogging"))); newProperties["rateLogging"] = sn.second.get<int>("rateLogging", boost::any_cast<int>(commonProperties.at("rateLogging")));
newProperties["portRangeMin"] = sn.second.get<int>("portRangeMin", boost::any_cast<int>(commonProperties.at("portRangeMin"))); newProperties["portRangeMin"] = sn.second.get<int>("portRangeMin", boost::any_cast<int>(commonProperties.at("portRangeMin")));
@@ -173,7 +177,7 @@ void SubChannelParser(const ptree& channelTree, fair::mq::Properties& properties
LOG(trace) << "\tNo sockets specified,"; LOG(trace) << "\tNo sockets specified,";
LOG(trace) << "\tapplying common settings to the channel:"; LOG(trace) << "\tapplying common settings to the channel:";
fair::mq::Properties newProperties(commonProperties); Properties newProperties(commonProperties);
for (auto& p : newProperties) { for (auto& p : newProperties) {
LOG(trace) << "\t" << setw(13) << left << p.first << " : " << p.second; LOG(trace) << "\t" << setw(13) << left << p.first << " : " << p.second;

View File

@@ -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>
namespace fair::mq namespace fair::mq
@@ -28,13 +28,13 @@ template<typename ContainerT>
// pmr::polymorphic_allocator<typename // pmr::polymorphic_allocator<typename
// ContainerT::value_type>, // ContainerT::value_type>,
// typename ContainerT::allocator_type>::value == true, // typename ContainerT::allocator_type>::value == true,
// FairMQMessagePtr>::type // MessagePtr>::type
FairMQMessagePtr getMessage(ContainerT &&container_, FairMQMemoryResource *targetResource = nullptr) MessagePtr getMessage(ContainerT &&container_, MemoryResource *targetResource = nullptr)
{ {
auto container = std::move(container_); auto container = std::move(container_);
auto alloc = container.get_allocator(); auto alloc = container.get_allocator();
auto resource = dynamic_cast<FairMQMemoryResource *>(alloc.resource()); auto resource = dynamic_cast<MemoryResource *>(alloc.resource());
if (!resource && !targetResource) { if (!resource && !targetResource) {
throw std::runtime_error("Neither the container or target resource specified"); throw std::runtime_error("Neither the container or target resource specified");
} }

View File

@@ -32,16 +32,21 @@ struct Message
: fTransport(factory) : fTransport(factory)
{} {}
Message(const Message&) = delete;
Message(Message&&) = delete;
Message& operator=(const Message&) = delete;
Message& operator=(Message&&) = delete;
virtual void Rebuild() = 0; virtual void Rebuild() = 0;
virtual void Rebuild(Alignment alignment) = 0; virtual void Rebuild(Alignment alignment) = 0;
virtual void Rebuild(const size_t size) = 0; virtual void Rebuild(size_t size) = 0;
virtual void Rebuild(const size_t size, Alignment alignment) = 0; virtual void Rebuild(size_t size, Alignment alignment) = 0;
virtual void Rebuild(void* data, const size_t size, FreeFn* ffn, void* hint = nullptr) = 0; virtual void Rebuild(void* data, size_t size, FreeFn* ffn, void* hint = nullptr) = 0;
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(const size_t size) = 0; virtual bool SetUsedSize(size_t size) = 0;
virtual Transport GetType() const = 0; virtual Transport GetType() const = 0;
TransportFactory* GetTransport() { return fTransport; } TransportFactory* GetTransport() { return fTransport; }

View File

@@ -25,13 +25,11 @@ class Parts
public: public:
Parts() = default; Parts() = default;
Parts(const Parts&) = delete; Parts(const Parts&) = delete;
Parts(Parts&& p) = default; Parts(Parts&&) = default;
Parts& operator=(const Parts&) = delete;
template<typename... Ts> template<typename... Ts>
Parts(Ts&&... messages) Parts(Ts&&... messages) { AddPart(std::forward<Ts>(messages)...); }
{ Parts& operator=(const Parts&) = delete;
AddPart(std::forward<Ts>(messages)...); Parts& operator=(Parts&&) = default;
}
~Parts() = default; ~Parts() = default;
/// Adds part (Message) to the container /// Adds part (Message) to the container

View File

@@ -7,7 +7,7 @@
********************************************************************************/ ********************************************************************************/
#include <fairmq/Plugin.h> #include <fairmq/Plugin.h>
#include <FairMQLogger.h> #include <fairlogger/Logger.h>
#include <utility> #include <utility>
using namespace std; using namespace std;

View File

@@ -48,7 +48,9 @@ class Plugin
PluginServices* pluginServices); PluginServices* pluginServices);
Plugin(const Plugin&) = delete; Plugin(const Plugin&) = delete;
Plugin operator=(const Plugin&) = delete; Plugin(Plugin&&) = delete;
Plugin& operator=(const Plugin&) = delete;
Plugin& operator=(Plugin&&) = delete;
virtual ~Plugin(); virtual ~Plugin();
@@ -72,10 +74,10 @@ class Plugin
// see <fairmq/PluginServices.h> for docs // see <fairmq/PluginServices.h> for docs
using DeviceState = fair::mq::PluginServices::DeviceState; using DeviceState = fair::mq::PluginServices::DeviceState;
using DeviceStateTransition = fair::mq::PluginServices::DeviceStateTransition; using DeviceStateTransition = fair::mq::PluginServices::DeviceStateTransition;
auto ToDeviceState(const std::string& state) const -> DeviceState { return fPluginServices->ToDeviceState(state); } auto ToDeviceState(const std::string& state) const -> DeviceState { return PluginServices::ToDeviceState(state); }
auto ToDeviceStateTransition(const std::string& transition) const -> DeviceStateTransition { return fPluginServices->ToDeviceStateTransition(transition); } auto ToDeviceStateTransition(const std::string& transition) const -> DeviceStateTransition { return PluginServices::ToDeviceStateTransition(transition); }
auto ToStr(DeviceState state) const -> std::string { return fPluginServices->ToStr(state); } auto ToStr(DeviceState state) const -> std::string { return PluginServices::ToStr(state); }
auto ToStr(DeviceStateTransition transition) const -> std::string { return fPluginServices->ToStr(transition); } auto ToStr(DeviceStateTransition transition) const -> std::string { return PluginServices::ToStr(transition); }
auto GetCurrentDeviceState() const -> DeviceState { return fPluginServices->GetCurrentDeviceState(); } auto GetCurrentDeviceState() const -> DeviceState { return fPluginServices->GetCurrentDeviceState(); }
auto TakeDeviceControl() -> void { fPluginServices->TakeDeviceControl(fkName); }; auto TakeDeviceControl() -> void { fPluginServices->TakeDeviceControl(fkName); };
auto StealDeviceControl() -> void { fPluginServices->StealDeviceControl(fkName); }; auto StealDeviceControl() -> void { fPluginServices->StealDeviceControl(fkName); };
@@ -89,6 +91,8 @@ class Plugin
auto SubscribeToDeviceStateChange(std::function<void(DeviceState)> callback) -> void { fPluginServices->SubscribeToDeviceStateChange(fkName, callback); } auto SubscribeToDeviceStateChange(std::function<void(DeviceState)> callback) -> void { fPluginServices->SubscribeToDeviceStateChange(fkName, callback); }
auto UnsubscribeFromDeviceStateChange() -> void { fPluginServices->UnsubscribeFromDeviceStateChange(fkName); } auto UnsubscribeFromDeviceStateChange() -> void { fPluginServices->UnsubscribeFromDeviceStateChange(fkName); }
auto GetNumberOfConnectedPeers(const std::string& channelName, int index = 0) -> unsigned long { return fPluginServices->GetNumberOfConnectedPeers(channelName, index); }
// device config API // device config API
// see <fairmq/PluginServices.h> for docs // see <fairmq/PluginServices.h> for docs
auto PropertyExists(const std::string& key) -> int { return fPluginServices->PropertyExists(key); } auto PropertyExists(const std::string& key) -> int { return fPluginServices->PropertyExists(key); }

View File

@@ -35,7 +35,7 @@ fair::mq::PluginManager::PluginManager()
{ {
} }
fair::mq::PluginManager::PluginManager(const vector<string> args) fair::mq::PluginManager::PluginManager(const vector<string>& args)
: fPluginServices() : fPluginServices()
{ {
// Parse command line options // Parse command line options

View File

@@ -49,7 +49,11 @@ class PluginManager
using PluginFactory = std::unique_ptr<fair::mq::Plugin>(PluginServices&); using PluginFactory = std::unique_ptr<fair::mq::Plugin>(PluginServices&);
PluginManager(); PluginManager();
PluginManager(const std::vector<std::string> args); PluginManager(const PluginManager&) = delete;
PluginManager(PluginManager&&) = delete;
PluginManager& operator=(const PluginManager&) = delete;
PluginManager& operator=(PluginManager&&) = delete;
PluginManager(const std::vector<std::string>& args);
~PluginManager() ~PluginManager()
{ {
@@ -115,7 +119,7 @@ class PluginManager
static const std::string fgkLibPrefix; static const std::string fgkLibPrefix;
std::vector<boost::filesystem::path> fSearchPaths; std::vector<boost::filesystem::path> fSearchPaths;
static std::vector<boost::dll::shared_library> fgDLLKeepAlive; 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;
std::map<std::string, std::unique_ptr<Plugin>> fPlugins; std::map<std::string, std::unique_ptr<Plugin>> fPlugins;

View File

@@ -51,7 +51,9 @@ class PluginServices
} }
PluginServices(const PluginServices&) = delete; PluginServices(const PluginServices&) = delete;
PluginServices operator=(const PluginServices&) = delete; PluginServices(PluginServices&&) = delete;
PluginServices& operator=(const PluginServices&) = delete;
PluginServices& operator=(PluginServices&&) = delete;
using DeviceState = fair::mq::State; using DeviceState = fair::mq::State;
using DeviceStateTransition = fair::mq::Transition; using DeviceStateTransition = fair::mq::Transition;
@@ -136,6 +138,9 @@ class PluginServices
/// @param subscriber id /// @param subscriber id
auto UnsubscribeFromDeviceStateChange(const std::string& subscriber) -> void { fDevice.UnsubscribeFromStateChange(subscriber); } auto UnsubscribeFromDeviceStateChange(const std::string& subscriber) -> void { fDevice.UnsubscribeFromStateChange(subscriber); }
/// DO NOT USE, ONLY FOR TESTING, WILL BE REMOVED (and info made available via property api)
auto GetNumberOfConnectedPeers(const std::string& channelName, int index = 0) -> unsigned long { return fDevice.GetNumberOfConnectedPeers(channelName, index); }
// Config API // Config API
/// @brief Checks a property with the given key exist in the configuration /// @brief Checks a property with the given key exist in the configuration

View File

@@ -17,11 +17,17 @@ namespace fair::mq {
struct Poller struct Poller
{ {
virtual void Poll(const int timeout) = 0; Poller() = default;
virtual bool CheckInput(const int index) = 0; Poller(const Poller&) = delete;
virtual bool CheckOutput(const int index) = 0; Poller(Poller&&) = delete;
virtual bool CheckInput(const std::string& channelKey, const int index) = 0; Poller& operator=(const Poller&) = delete;
virtual bool CheckOutput(const std::string& channelKey, const int index) = 0; Poller& operator=(Poller&&) = delete;
virtual void Poll(int timeout) = 0;
virtual bool CheckInput(int index) = 0;
virtual bool CheckOutput(int index) = 0;
virtual bool CheckInput(const std::string& channelKey, int index) = 0;
virtual bool CheckOutput(const std::string& channelKey, int index) = 0;
virtual ~Poller() = default; virtual ~Poller() = default;
}; };

View File

@@ -169,7 +169,7 @@ unordered_map<string, int> ProgOptions::GetChannelInfoImpl() const
for (const auto& m : fVarMap) { for (const auto& m : fVarMap) {
if (boost::regex_match(m.first, re)) { if (boost::regex_match(m.first, re)) {
string chan = m.first.substr(6); string chan = m.first.substr(6);
string::size_type n = chan.find("."); string::size_type n = chan.find('.');
string chanName = chan.substr(0, n); string chanName = chan.substr(0, n);
if (info.find(chanName) == info.end()) { if (info.find(chanName) == info.end()) {
@@ -351,7 +351,7 @@ void ProgOptions::DeleteProperty(const string& key)
vm.erase(key); vm.erase(key);
} }
void ProgOptions::AddChannel(const string& name, const FairMQChannel& channel) void ProgOptions::AddChannel(const string& name, const Channel& channel)
{ {
lock_guard<mutex> lock(fMtx); lock_guard<mutex> lock(fMtx);
unordered_map<string, int> existingChannels = GetChannelInfoImpl(); unordered_map<string, int> existingChannels = GetChannelInfoImpl();

View File

@@ -33,7 +33,11 @@ class ProgOptions
{ {
public: public:
ProgOptions(); ProgOptions();
virtual ~ProgOptions() = default; ProgOptions(const ProgOptions&) = delete;
ProgOptions(ProgOptions&&) = delete;
ProgOptions& operator=(const ProgOptions&) = delete;
ProgOptions& operator=(ProgOptions&&) = delete;
~ProgOptions() = default;
void ParseAll(const std::vector<std::string>& cmdArgs, bool allowUnregistered); void ParseAll(const std::vector<std::string>& cmdArgs, bool allowUnregistered);
void ParseAll(int argc, char const* const* argv, bool allowUnregistered = true); void ParseAll(int argc, char const* const* argv, bool allowUnregistered = true);

View File

@@ -65,9 +65,9 @@ class PropertyHelper
} }
} }
static std::unordered_map<std::type_index, void(*)(const fair::mq::EventManager&, const std::string&, const Property&)> fEventEmitters; static std::unordered_map<std::type_index, void(*)(const fair::mq::EventManager&, const std::string&, const Property&)> fEventEmitters; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
private: private:
static std::unordered_map<std::type_index, std::function<std::pair<std::string, std::string>(const Property&)>> fTypeInfos; static std::unordered_map<std::type_index, std::function<std::pair<std::string, std::string>(const Property&)>> fTypeInfos; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
}; };
} }

View File

@@ -10,9 +10,12 @@
#define FAIR_MQ_SOCKET_H #define FAIR_MQ_SOCKET_H
#include <fairmq/Message.h> #include <fairmq/Message.h>
#include <fairmq/Parts.h>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <type_traits>
#include <vector> #include <vector>
namespace fair::mq { namespace fair::mq {
@@ -27,12 +30,20 @@ enum class TransferCode : int
interrupted = -3 interrupted = -3
}; };
template <typename T>
struct is_transferrable : std::disjunction<std::is_same<T, MessagePtr>,
std::is_same<T, std::vector<MessagePtr>>,
std::is_same<T, fair::mq::Parts>>
{};
struct Socket struct Socket
{ {
Socket() = default; Socket() = default;
Socket(TransportFactory* fac) Socket(TransportFactory* fac) : fTransport(fac) {}
: fTransport(fac) Socket(const Socket&) = delete;
{} Socket(Socket&&) = delete;
Socket& operator=(const Socket&) = delete;
Socket& operator=(Socket&&) = delete;
virtual std::string GetId() const = 0; virtual std::string GetId() const = 0;
@@ -43,7 +54,10 @@ struct Socket
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(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
virtual int64_t Receive(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0; virtual int64_t Receive(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
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); }
[[deprecated("Use Socket::~Socket() instead.")]]
virtual void Close() = 0; virtual void Close() = 0;
virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0; virtual void SetOption(const std::string& option, const void* value, size_t valueSize) = 0;
@@ -53,15 +67,15 @@ struct Socket
/// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in /// DISCLAIMER: this API is experimental and unsupported and might be dropped / refactored in
/// the future. /// the future.
virtual int Events(uint32_t* events) = 0; virtual int Events(uint32_t* events) = 0;
virtual void SetLinger(const int value) = 0; virtual void SetLinger(int value) = 0;
virtual int GetLinger() const = 0; virtual int GetLinger() const = 0;
virtual void SetSndBufSize(const int value) = 0; virtual void SetSndBufSize(int value) = 0;
virtual int GetSndBufSize() const = 0; virtual int GetSndBufSize() const = 0;
virtual void SetRcvBufSize(const int value) = 0; virtual void SetRcvBufSize(int value) = 0;
virtual int GetRcvBufSize() const = 0; virtual int GetRcvBufSize() const = 0;
virtual void SetSndKernelSize(const int value) = 0; virtual void SetSndKernelSize(int value) = 0;
virtual int GetSndKernelSize() const = 0; virtual int GetSndKernelSize() const = 0;
virtual void SetRcvKernelSize(const int value) = 0; virtual void SetRcvKernelSize(int value) = 0;
virtual int GetRcvKernelSize() const = 0; virtual int GetRcvKernelSize() const = 0;
virtual unsigned long GetBytesTx() const = 0; virtual unsigned long GetBytesTx() const = 0;
@@ -69,6 +83,8 @@ struct Socket
virtual unsigned long GetMessagesTx() const = 0; virtual unsigned long GetMessagesTx() const = 0;
virtual unsigned long GetMessagesRx() const = 0; virtual unsigned long GetMessagesRx() const = 0;
virtual unsigned long GetNumberOfConnectedPeers() const = 0;
TransportFactory* GetTransport() { return fTransport; } TransportFactory* GetTransport() { return fTransport; }
void SetTransport(TransportFactory* transport) { fTransport = transport; } void SetTransport(TransportFactory* transport) { fTransport = transport; }

View File

@@ -7,6 +7,7 @@
********************************************************************************/ ********************************************************************************/
#include <fairmq/StateMachine.h> #include <fairmq/StateMachine.h>
#include <fairmq/tools/Exceptions.h>
#include <fairlogger/Logger.h> #include <fairlogger/Logger.h>
@@ -84,8 +85,6 @@ struct Machine_ : public state_machine_def<Machine_>
, fNewStatePending(false) , fNewStatePending(false)
{} {}
virtual ~Machine_() = default;
// initial states // initial states
using initial_state = bmpl::vector<IDLE_S, OK_S>; using initial_state = bmpl::vector<IDLE_S, OK_S>;
@@ -206,6 +205,7 @@ struct Machine_ : public state_machine_def<Machine_>
} }
if (fState == State::Error) { if (fState == State::Error) {
LOG(trace) << "Device transitioned to error state";
throw StateMachine::ErrorStateException("Device transitioned to error state"); throw StateMachine::ErrorStateException("Device transitioned to error state");
} }
} }
@@ -222,9 +222,9 @@ struct Machine_ : public state_machine_def<Machine_>
bmpl::for_each<AllStates, wrap<bmpl::placeholders::_1>>(get_state_name<RecursiveStt>(stateName, state)); bmpl::for_each<AllStates, wrap<bmpl::placeholders::_1>>(get_state_name<RecursiveStt>(stateName, state));
stateName = boost::core::demangle(stateName.c_str()); stateName = boost::core::demangle(stateName.c_str());
size_t pos = stateName.rfind(":"); size_t pos = stateName.rfind(':');
stateName = stateName.substr(pos + 1); stateName = stateName.substr(pos + 1);
size_t pos2 = stateName.rfind("_"); size_t pos2 = stateName.rfind('_');
stateName = stateName.substr(0, pos2); stateName = stateName.substr(0, pos2);
if (stateName != "OK") { if (stateName != "OK") {
@@ -246,7 +246,7 @@ StateMachine::StateMachine() : fFsm(new FairMQFSM) {}
void StateMachine::Start() { static_pointer_cast<FairMQFSM>(fFsm)->start(); } void StateMachine::Start() { static_pointer_cast<FairMQFSM>(fFsm)->start(); }
StateMachine::~StateMachine() { static_pointer_cast<FairMQFSM>(fFsm)->stop(); } StateMachine::~StateMachine() { static_pointer_cast<FairMQFSM>(fFsm)->stop(); }
bool StateMachine::ChangeState(const Transition transition) bool StateMachine::ChangeState(Transition transition)
try { try {
auto fsm = static_pointer_cast<FairMQFSM>(fFsm); auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
lock_guard<mutex> lock(fsm->fStateMtx); lock_guard<mutex> lock(fsm->fStateMtx);
@@ -357,7 +357,7 @@ void StateMachine::WaitForPendingState() const
unique_lock<mutex> lock(fsm->fStateMtx); unique_lock<mutex> lock(fsm->fStateMtx);
fsm->fNewStatePendingCV.wait(lock, [&]{ return static_cast<bool>(fsm->fNewStatePending); }); fsm->fNewStatePendingCV.wait(lock, [&]{ return static_cast<bool>(fsm->fNewStatePending); });
} }
bool StateMachine::WaitForPendingStateFor(const int durationInMs) const bool StateMachine::WaitForPendingStateFor(int durationInMs) const
{ {
auto fsm = static_pointer_cast<FairMQFSM>(fFsm); auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
unique_lock<mutex> lock(fsm->fStateMtx); unique_lock<mutex> lock(fsm->fStateMtx);
@@ -368,20 +368,18 @@ void StateMachine::ProcessWork()
{ {
auto fsm = static_pointer_cast<FairMQFSM>(fFsm); auto fsm = static_pointer_cast<FairMQFSM>(fFsm);
try { fair::mq::tools::CallOnDestruction cod([&](){
fsm->CallStateChangeCallbacks(State::Idle); LOG(debug) << "Exception caught in ProcessWork(), going to Error state";
fsm->ProcessWork();
} catch(ErrorStateException& ese) {
LOG(trace) << "ErrorStateException caught in ProcessWork(), rethrowing";
throw;
} catch(...) {
LOG(debug) << "Exception caught in ProcessWork(), going to Error state and rethrowing";
{ {
lock_guard<mutex> lock(fsm->fStateMtx); lock_guard<mutex> lock(fsm->fStateMtx);
fsm->fState = State::Error; fsm->fState = State::Error;
fsm->CallStateChangeCallbacks(State::Error); fsm->CallStateChangeCallbacks(State::Error);
} }
ChangeState(Transition::ErrorFound); ChangeState(Transition::ErrorFound);
throw; });
}
fsm->CallStateChangeCallbacks(State::Idle);
fsm->ProcessWork();
cod.disable();
} }

View File

@@ -23,9 +23,13 @@ class StateMachine
{ {
public: public:
StateMachine(); StateMachine();
virtual ~StateMachine(); StateMachine(const StateMachine&) = delete;
StateMachine(StateMachine&&) = delete;
StateMachine& operator=(const StateMachine&) = delete;
StateMachine& operator=(StateMachine&&) = delete;
~StateMachine();
bool ChangeState(const Transition transition); bool ChangeState(Transition transition);
bool ChangeState(const std::string& transition) { return ChangeState(GetTransition(transition)); } bool ChangeState(const std::string& transition) { return ChangeState(GetTransition(transition)); }
void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback); void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback);
@@ -39,7 +43,7 @@ class StateMachine
bool NewStatePending() const; bool NewStatePending() const;
void WaitForPendingState() const; void WaitForPendingState() const;
bool WaitForPendingStateFor(const int durationInMs) const; bool WaitForPendingStateFor(int durationInMs) const;
State GetCurrentState() const; State GetCurrentState() const;
std::string GetCurrentStateName() const; std::string GetCurrentStateName() const;

View File

@@ -24,6 +24,10 @@ class StateQueue
{ {
public: public:
StateQueue() = default; StateQueue() = default;
StateQueue(const StateQueue&) = delete;
StateQueue(StateQueue&&) = delete;
StateQueue& operator=(const StateQueue&) = delete;
StateQueue& operator=(StateQueue&&) = delete;
~StateQueue() = default; ~StateQueue() = default;
fair::mq::State WaitForNext() fair::mq::State WaitForNext()

View File

@@ -16,7 +16,7 @@ using namespace std;
namespace fair::mq namespace fair::mq
{ {
array<string, 16> stateNames = const array<string, 16> stateNames =
{ {
{ {
"UNDEFINED", "UNDEFINED",
@@ -38,7 +38,7 @@ array<string, 16> stateNames =
} }
}; };
unordered_map<string, State> states = const unordered_map<string, State> states =
{ {
{ "UNDEFINED", State::Undefined }, { "UNDEFINED", State::Undefined },
{ "OK", State::Ok }, { "OK", State::Ok },
@@ -58,7 +58,7 @@ unordered_map<string, State> states =
{ "EXITING", State::Exiting } { "EXITING", State::Exiting }
}; };
array<string, 12> transitionNames = const array<string, 12> transitionNames =
{ {
{ {
"AUTO", "AUTO",
@@ -76,7 +76,7 @@ array<string, 12> transitionNames =
} }
}; };
unordered_map<string, Transition> transitions = const unordered_map<string, Transition> transitions =
{ {
{ "AUTO", Transition::Auto }, { "AUTO", Transition::Auto },
{ "INIT DEVICE", Transition::InitDevice }, { "INIT DEVICE", Transition::InitDevice },

View File

@@ -38,6 +38,8 @@ enum channelOptionKeyIds
RCVBUFSIZE, // size of the receive queue RCVBUFSIZE, // size of the receive queue
SNDKERNELSIZE, SNDKERNELSIZE,
RCVKERNELSIZE, RCVKERNELSIZE,
SNDTIMEOUTMS,
RCVTIMEOUTMS,
LINGER, LINGER,
RATELOGGING, // logging rate RATELOGGING, // logging rate
PORTRANGEMIN, PORTRANGEMIN,
@@ -57,6 +59,8 @@ constexpr static const char* channelOptionKeys[] = {
/*[RCVBUFSIZE] = */ "rcvBufSize", /*[RCVBUFSIZE] = */ "rcvBufSize",
/*[SNDKERNELSIZE] = */ "sndKernelSize", /*[SNDKERNELSIZE] = */ "sndKernelSize",
/*[RCVKERNELSIZE] = */ "rcvKernelSize", /*[RCVKERNELSIZE] = */ "rcvKernelSize",
/*[SNDTIMEOUTMS] = */ "sndTimeoutMs",
/*[RCVTIMEOUTMS] = */ "rcvTimeoutMs",
/*[LINGER] = */ "linger", /*[LINGER] = */ "linger",
/*[RATELOGGING] = */ "rateLogging", /*[RATELOGGING] = */ "rateLogging",
/*[PORTRANGEMIN] = */ "portRangeMin", /*[PORTRANGEMIN] = */ "portRangeMin",

View File

@@ -11,6 +11,7 @@
// IWYU pragma: begin_exports // IWYU pragma: begin_exports
#include <fairmq/tools/CppSTL.h> #include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Exceptions.h>
#include <fairmq/tools/InstanceLimit.h> #include <fairmq/tools/InstanceLimit.h>
#include <fairmq/tools/Network.h> #include <fairmq/tools/Network.h>
#include <fairmq/tools/Process.h> #include <fairmq/tools/Process.h>

View File

@@ -43,6 +43,11 @@ class TransportFactory
: fkId(std::move(id)) : fkId(std::move(id))
{} {}
TransportFactory(const TransportFactory&) = delete;
TransportFactory(TransportFactory&&) = delete;
TransportFactory& operator=(const TransportFactory&) = delete;
TransportFactory& operator=(TransportFactory&&) = delete;
auto GetId() const -> const std::string { return fkId; }; auto GetId() const -> const std::string { return fkId; };
/// Get a pointer to the associated polymorphic memory resource /// Get a pointer to the associated polymorphic memory resource
@@ -104,13 +109,15 @@ class TransportFactory
/// @param path optional parameter to pass to the underlying transport /// @param path optional parameter to pass to the underlying transport
/// @param flags optional parameter to pass to the underlying transport /// @param flags optional parameter to pass to the underlying transport
/// @return pointer to UnmanagedRegion /// @return pointer to UnmanagedRegion
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, // [[deprecated("Use CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg)")]]
virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size,
RegionCallback callback = nullptr, RegionCallback callback = nullptr,
const std::string& path = "", const std::string& path = "",
int flags = 0, int flags = 0,
RegionConfig cfg = RegionConfig()) = 0; RegionConfig cfg = RegionConfig()) = 0;
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, // [[deprecated("Use CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg)")]]
RegionBulkCallback callback = nullptr, virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size,
RegionBulkCallback bulkCallback = nullptr,
const std::string& path = "", const std::string& path = "",
int flags = 0, int flags = 0,
RegionConfig cfg = RegionConfig()) = 0; RegionConfig cfg = RegionConfig()) = 0;
@@ -123,19 +130,35 @@ class TransportFactory
/// @param path optional parameter to pass to the underlying transport /// @param path optional parameter to pass to the underlying transport
/// @param flags optional parameter to pass to the underlying transport /// @param flags optional parameter to pass to the underlying transport
/// @return pointer to UnmanagedRegion /// @return pointer to UnmanagedRegion
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, // [[deprecated("Use CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg)")]]
const int64_t userFlags, virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size,
int64_t userFlags,
RegionCallback callback = nullptr, RegionCallback callback = nullptr,
const std::string& path = "", const std::string& path = "",
int flags = 0, int flags = 0,
RegionConfig cfg = RegionConfig()) = 0; RegionConfig cfg = RegionConfig()) = 0;
virtual UnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, // [[deprecated("Use CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg)")]]
const int64_t userFlags, virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size,
RegionBulkCallback callback = nullptr, int64_t userFlags,
RegionBulkCallback bulkCallback = nullptr,
const std::string& path = "", const std::string& path = "",
int flags = 0, int flags = 0,
RegionConfig cfg = RegionConfig()) = 0; RegionConfig cfg = RegionConfig()) = 0;
/// @brief Create new UnmanagedRegion
/// @param size size of the region
/// @param callback callback to be called when a message belonging to this region is no longer needed by the transport
/// @param cfg region configuration
/// @return pointer to UnmanagedRegion
virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionCallback callback, RegionConfig cfg) = 0;
/// @brief Create new UnmanagedRegion
/// @param size size of the region
/// @param bulkCallback callback to be called when message(s) belonging to this region is no longer needed by the transport
/// @param cfg region configuration
/// @return pointer to UnmanagedRegion
virtual UnmanagedRegionPtr CreateUnmanagedRegion(size_t size, RegionBulkCallback bulkCallback, RegionConfig cfg) = 0;
/// @brief Subscribe to region events (creation, destruction, ...) /// @brief Subscribe to region events (creation, destruction, ...)
/// @param callback the callback that is called when a region event occurs /// @param callback the callback that is called when a region event occurs
virtual void SubscribeToRegionEvents(RegionEventCallback callback) = 0; virtual void SubscribeToRegionEvents(RegionEventCallback callback) = 0;

View File

@@ -31,21 +31,21 @@ struct TransportError : std::runtime_error
using std::runtime_error::runtime_error; using std::runtime_error::runtime_error;
}; };
static std::unordered_map<std::string, Transport> TransportTypes{ static const std::unordered_map<std::string, Transport> TransportTypes{
{"default", Transport::DEFAULT}, {"default", Transport::DEFAULT},
{"zeromq", Transport::ZMQ}, {"zeromq", Transport::ZMQ},
{"shmem", Transport::SHM}, {"shmem", Transport::SHM},
{"ofi", Transport::OFI} {"ofi", Transport::OFI}
}; };
static std::unordered_map<Transport, std::string> TransportNames{ static const std::unordered_map<Transport, std::string> TransportNames{
{Transport::DEFAULT, "default"}, {Transport::DEFAULT, "default"},
{Transport::ZMQ, "zeromq"}, {Transport::ZMQ, "zeromq"},
{Transport::SHM, "shmem"}, {Transport::SHM, "shmem"},
{Transport::OFI, "ofi"} {Transport::OFI, "ofi"}
}; };
inline std::string TransportName(Transport transport) { return TransportNames[transport]; } inline std::string TransportName(Transport transport) { return TransportNames.at(transport); }
inline Transport TransportType(const std::string& transport) inline Transport TransportType(const std::string& transport)
try { try {

View File

@@ -9,12 +9,16 @@
#ifndef FAIR_MQ_UNMANAGEDREGION_H #ifndef FAIR_MQ_UNMANAGEDREGION_H
#define FAIR_MQ_UNMANAGEDREGION_H #define FAIR_MQ_UNMANAGEDREGION_H
#include <fairmq/Transports.h>
#include <cstddef> // size_t #include <cstddef> // size_t
#include <cstdint> // uint32_t #include <cstdint> // uint32_t
#include <fairmq/Transports.h>
#include <functional> // std::function #include <functional> // std::function
#include <memory> // std::unique_ptr #include <memory> // std::unique_ptr
#include <ostream> // std::ostream #include <optional> // std::optional
#include <ostream>
#include <string>
#include <vector> #include <vector>
namespace fair::mq { namespace fair::mq {
@@ -78,6 +82,11 @@ struct UnmanagedRegion
: fTransport(factory) : fTransport(factory)
{} {}
UnmanagedRegion(const UnmanagedRegion&) = delete;
UnmanagedRegion(UnmanagedRegion&&) = delete;
UnmanagedRegion& operator=(const UnmanagedRegion&) = delete;
UnmanagedRegion& operator=(UnmanagedRegion&&) = delete;
virtual void* GetData() const = 0; virtual void* GetData() const = 0;
virtual size_t GetSize() const = 0; virtual size_t GetSize() const = 0;
virtual uint16_t GetId() const = 0; virtual uint16_t GetId() const = 0;
@@ -114,13 +123,20 @@ struct RegionConfig
{ {
RegionConfig() = default; RegionConfig() = default;
RegionConfig(bool l, bool z) RegionConfig(bool _lock, bool _zero)
: lock(l) : lock(_lock)
, zero(z) , zero(_zero)
{} {}
bool lock = false; bool lock = false; /// mlock region after creation
bool zero = false; bool zero = false; /// zero region content after creation
bool removeOnDestruction = true; /// remove the region on object destruction
int creationFlags = 0; /// flags passed to the underlying transport on region creation
int64_t userFlags = 0; /// custom flags that have no effect on the transport, but can be retrieved from the region by the user
uint64_t size = 0; /// region size
std::string path = ""; /// file path, if the region is backed by a file
std::optional<uint16_t> id = std::nullopt; /// region id
uint32_t linger = 100; /// delay in ms before region destruction to collect outstanding events
}; };
} // namespace fair::mq } // namespace fair::mq

View File

@@ -44,7 +44,7 @@ class BenchmarkSampler : public Device
void Run() override void Run() override
{ {
// store the channel reference to avoid traversing the map on every loop iteration // store the channel reference to avoid traversing the map on every loop iteration
FairMQChannel& dataOutChannel = fChannels.at(fOutChannelName).at(0); Channel& dataOutChannel = GetChannel(fOutChannelName, 0);
LOG(info) << "Starting the benchmark with message size of " << fMsgSize << " and " << fMaxIterations << " iterations."; LOG(info) << "Starting the benchmark with message size of " << fMsgSize << " and " << fMaxIterations << " iterations.";
auto tStart = std::chrono::high_resolution_clock::now(); auto tStart = std::chrono::high_resolution_clock::now();
@@ -53,7 +53,7 @@ class BenchmarkSampler : public Device
while (!NewStatePending()) { while (!NewStatePending()) {
if (fMultipart) { if (fMultipart) {
FairMQParts parts; Parts parts;
for (size_t i = 0; i < fNumParts; ++i) { for (size_t i = 0; i < fNumParts; ++i) {
parts.AddPart(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment})); parts.AddPart(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment}));
@@ -71,7 +71,7 @@ class BenchmarkSampler : public Device
++fNumIterations; ++fNumIterations;
} }
} else { } else {
FairMQMessagePtr msg(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment})); MessagePtr msg(dataOutChannel.NewMessage(fMsgSize, fair::mq::Alignment{fMsgAlignment}));
if (fMemSet) { if (fMemSet) {
std::memset(msg->GetData(), 0, msg->GetSize()); std::memset(msg->GetData(), 0, msg->GetSize());
} }

View File

@@ -9,7 +9,7 @@
#ifndef FAIR_MQ_MERGER_H #ifndef FAIR_MQ_MERGER_H
#define FAIR_MQ_MERGER_H #define FAIR_MQ_MERGER_H
#include <FairMQPoller.h> #include <fairmq/Poller.h>
#include <fairmq/Device.h> #include <fairmq/Device.h>
#include <fairlogger/Logger.h> #include <fairlogger/Logger.h>
@@ -43,15 +43,15 @@ class Merger : public Device
void Run() override void Run() override
{ {
int numInputs = fChannels.at(fInChannelName).size(); int numInputs = GetNumSubChannels(fInChannelName);
std::vector<FairMQChannel*> chans; std::vector<Channel*> chans;
for (auto& chan : fChannels.at(fInChannelName)) { for (auto& chan : fChannels.at(fInChannelName)) {
chans.push_back(&chan); chans.push_back(&chan);
} }
FairMQPollerPtr poller(NewPoller(chans)); PollerPtr poller(NewPoller(chans));
if (fMultipart) { if (fMultipart) {
while (!NewStatePending()) { while (!NewStatePending()) {
@@ -61,7 +61,7 @@ class Merger : public Device
for (int i = 0; i < numInputs; ++i) { for (int i = 0; i < numInputs; ++i) {
// Check if the channel has data ready to be received. // Check if the channel has data ready to be received.
if (poller->CheckInput(i)) { if (poller->CheckInput(i)) {
FairMQParts payload; Parts payload;
if (Receive(payload, fInChannelName, i) >= 0) { if (Receive(payload, fInChannelName, i) >= 0) {
if (Send(payload, fOutChannelName) < 0) { if (Send(payload, fOutChannelName) < 0) {
@@ -83,7 +83,7 @@ class Merger : public Device
for (int i = 0; i < numInputs; ++i) { for (int i = 0; i < numInputs; ++i) {
// Check if the channel has data ready to be received. // Check if the channel has data ready to be received.
if (poller->CheckInput(i)) { if (poller->CheckInput(i)) {
FairMQMessagePtr payload(fTransportFactory->CreateMessage()); MessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName, i) >= 0) { if (Receive(payload, fInChannelName, i) >= 0) {
if (Send(payload, fOutChannelName) < 0) { if (Send(payload, fOutChannelName) < 0) {

View File

@@ -30,7 +30,7 @@ class Multiplier : public Device
fMultipart = fConfig->GetProperty<bool>("multipart"); fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<std::string>("in-channel"); fInChannelName = fConfig->GetProperty<std::string>("in-channel");
fOutChannelNames = fConfig->GetProperty<std::vector<std::string>>("out-channel"); fOutChannelNames = fConfig->GetProperty<std::vector<std::string>>("out-channel");
fNumOutputs = fChannels.at(fOutChannelNames.at(0)).size(); fNumOutputs = GetNumSubChannels(fOutChannelNames.at(0));
if (fMultipart) { if (fMultipart) {
OnData(fInChannelName, &Multiplier::HandleMultipartData); OnData(fInChannelName, &Multiplier::HandleMultipartData);
@@ -40,21 +40,21 @@ class Multiplier : public Device
} }
bool HandleSingleData(std::unique_ptr<FairMQMessage>& payload, int) bool HandleSingleData(std::unique_ptr<Message>& payload, int)
{ {
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) { // all subChannels in a channel for (unsigned int j = 0; j < GetNumSubChannels(fOutChannelNames.at(i)); ++j) { // all subChannels in a channel
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage()); MessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload); msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.at(i), j); Send(msgCopy, fOutChannelNames.at(i), j);
} }
} }
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size(); unsigned int lastChannelSize = GetNumSubChannels(fOutChannelNames.back());
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage()); MessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(*payload); msgCopy->Copy(*payload);
Send(msgCopy, fOutChannelNames.back(), i); Send(msgCopy, fOutChannelNames.back(), i);
@@ -65,14 +65,14 @@ class Multiplier : public Device
return true; return true;
} }
bool HandleMultipartData(FairMQParts& payload, int) bool HandleMultipartData(Parts& payload, int)
{ {
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) { // all except last channel
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) { // all subChannels in a channel for (unsigned int j = 0; j < GetNumSubChannels(fOutChannelNames.at(i)); ++j) { // all subChannels in a channel
FairMQParts parts; Parts parts;
for (int k = 0; k < payload.Size(); ++k) { for (int k = 0; k < payload.Size(); ++k) {
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage()); MessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k)); msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy)); parts.AddPart(std::move(msgCopy));
} }
@@ -81,13 +81,13 @@ class Multiplier : public Device
} }
} }
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size(); unsigned int lastChannelSize = GetNumSubChannels(fOutChannelNames.back());
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel for (unsigned int i = 0; i < lastChannelSize - 1; ++i) { // iterate over all except last subChannels of the last channel
FairMQParts parts; Parts parts;
for (int k = 0; k < payload.Size(); ++k) { for (int k = 0; k < payload.Size(); ++k) {
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage()); MessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.AtRef(k)); msgCopy->Copy(payload.AtRef(k));
parts.AddPart(std::move(msgCopy)); parts.AddPart(std::move(msgCopy));
} }

View File

@@ -34,7 +34,7 @@ class Proxy : public Device
{ {
if (fMultipart) { if (fMultipart) {
while (!NewStatePending()) { while (!NewStatePending()) {
FairMQParts payload; Parts payload;
if (Receive(payload, fInChannelName) >= 0) { if (Receive(payload, fInChannelName) >= 0) {
if (Send(payload, fOutChannelName) < 0) { if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted"; LOG(debug) << "Transfer interrupted";
@@ -47,7 +47,7 @@ class Proxy : public Device
} }
} else { } else {
while (!NewStatePending()) { while (!NewStatePending()) {
FairMQMessagePtr payload(fTransportFactory->CreateMessage()); MessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, fInChannelName) >= 0) { if (Receive(payload, fInChannelName) >= 0) {
if (Send(payload, fOutChannelName) < 0) { if (Send(payload, fOutChannelName) < 0) {
LOG(debug) << "Transfer interrupted"; LOG(debug) << "Transfer interrupted";

View File

@@ -9,7 +9,6 @@
#ifndef FAIR_MQ_SINK_H #ifndef FAIR_MQ_SINK_H
#define FAIR_MQ_SINK_H #define FAIR_MQ_SINK_H
#include <FairMQPoller.h>
#include <fairmq/Device.h> #include <fairmq/Device.h>
#include <fairmq/tools/Strings.h> #include <fairmq/tools/Strings.h>
@@ -48,7 +47,7 @@ class Sink : public Device
void Run() override void Run() override
{ {
// store the channel reference to avoid traversing the map on every loop iteration // store the channel reference to avoid traversing the map on every loop iteration
FairMQChannel& dataInChannel = fChannels.at(fInChannelName).at(0); Channel& dataInChannel = GetChannel(fInChannelName, 0);
LOG(info) << "Starting sink and expecting to receive " << fMaxIterations << " messages."; LOG(info) << "Starting sink and expecting to receive " << fMaxIterations << " messages.";
auto tStart = std::chrono::high_resolution_clock::now(); auto tStart = std::chrono::high_resolution_clock::now();
@@ -70,7 +69,7 @@ class Sink : public Device
while (!NewStatePending()) { while (!NewStatePending()) {
if (fMultipart) { if (fMultipart) {
FairMQParts parts; Parts parts;
if (dataInChannel.Receive(parts) < 0) { if (dataInChannel.Receive(parts) < 0) {
continue; continue;
} }
@@ -80,7 +79,7 @@ class Sink : public Device
} }
} }
} else { } else {
FairMQMessagePtr msg(dataInChannel.NewMessage()); MessagePtr msg(dataInChannel.NewMessage());
if (dataInChannel.Receive(msg) < 0) { if (dataInChannel.Receive(msg) < 0) {
continue; continue;
} }

View File

@@ -30,13 +30,13 @@ class Splitter : public Device
fMultipart = fConfig->GetProperty<bool>("multipart"); fMultipart = fConfig->GetProperty<bool>("multipart");
fInChannelName = fConfig->GetProperty<std::string>("in-channel"); fInChannelName = fConfig->GetProperty<std::string>("in-channel");
fOutChannelName = fConfig->GetProperty<std::string>("out-channel"); fOutChannelName = fConfig->GetProperty<std::string>("out-channel");
fNumOutputs = fChannels.at(fOutChannelName).size(); fNumOutputs = GetNumSubChannels(fOutChannelName);
fDirection = 0; fDirection = 0;
if (fMultipart) { if (fMultipart) {
OnData(fInChannelName, &Splitter::HandleData<FairMQParts>); OnData(fInChannelName, &Splitter::HandleData<Parts>);
} else { } else {
OnData(fInChannelName, &Splitter::HandleData<FairMQMessagePtr>); OnData(fInChannelName, &Splitter::HandleData<MessagePtr>);
} }
} }

View File

@@ -54,6 +54,10 @@ class Context
Context(FairMQTransportFactory& sendFactory, Context(FairMQTransportFactory& sendFactory,
FairMQTransportFactory& receiveFactory, FairMQTransportFactory& receiveFactory,
int numberIoThreads = 1); int numberIoThreads = 1);
Context(const Context&) = delete;
Context(Context&&) = delete;
Context& operator=(const Context&) = delete;
Context& operator=(Context&&) = delete;
~Context(); ~Context();
auto GetAsiofiVersion() const -> std::string; auto GetAsiofiVersion() const -> std::string;

View File

@@ -110,7 +110,7 @@ auto Message::Rebuild(Alignment /* alignment */) -> void
Rebuild(); Rebuild();
} }
auto Message::Rebuild(const size_t size) -> void auto Message::Rebuild(size_t size) -> void
{ {
if (fFreeFunction) { if (fFreeFunction) {
fFreeFunction(fData, fHint); fFreeFunction(fData, fHint);
@@ -131,13 +131,13 @@ auto Message::Rebuild(const size_t size) -> void
fHint = nullptr; fHint = nullptr;
} }
auto Message::Rebuild(const size_t size, Alignment /* alignment */) -> void auto Message::Rebuild(size_t size, Alignment /* alignment */) -> void
{ {
// TODO: implement alignment // TODO: implement alignment
Rebuild(size); Rebuild(size);
} }
auto Message::Rebuild(void* /*data*/, const size_t size, fairmq_free_fn* ffn, void* hint) -> void auto Message::Rebuild(void* /*data*/, size_t size, fairmq_free_fn* ffn, void* hint) -> void
{ {
if (fFreeFunction) { if (fFreeFunction) {
fFreeFunction(fData, fHint); fFreeFunction(fData, fHint);
@@ -169,7 +169,7 @@ auto Message::GetSize() const -> size_t
return fSize; return fSize;
} }
auto Message::SetUsedSize(const size_t size) -> bool auto Message::SetUsedSize(size_t size) -> bool
{ {
if (size == fSize) { if (size == fSize) {
return true; return true;

View File

@@ -32,32 +32,34 @@ class Message final : public fair::mq::Message
public: public:
Message(std::pmr::memory_resource* pmr); Message(std::pmr::memory_resource* pmr);
Message(std::pmr::memory_resource* pmr, Alignment alignment); Message(std::pmr::memory_resource* pmr, Alignment alignment);
Message(std::pmr::memory_resource* pmr, const size_t size); Message(std::pmr::memory_resource* pmr, size_t size);
Message(std::pmr::memory_resource* pmr, const size_t size, Alignment alignment); Message(std::pmr::memory_resource* pmr, size_t size, Alignment alignment);
Message(std::pmr::memory_resource* pmr, Message(std::pmr::memory_resource* pmr,
void* data, void* data,
const size_t size, size_t size,
fairmq_free_fn* ffn, fairmq_free_fn* ffn,
void* hint = nullptr); void* hint = nullptr);
Message(std::pmr::memory_resource* pmr, Message(std::pmr::memory_resource* pmr,
fair::mq::UnmanagedRegionPtr& region, fair::mq::UnmanagedRegionPtr& region,
void* data, void* data,
const size_t size, size_t size,
void* hint = 0); void* hint = 0);
Message(const Message&) = delete; Message(const Message&) = delete;
Message operator=(const Message&) = delete; Message(Message&&) = delete;
Message& operator=(const Message&) = delete;
Message& operator=(Message&&) = delete;
auto Rebuild() -> void override; auto Rebuild() -> void override;
auto Rebuild(Alignment alignment) -> void override; auto Rebuild(Alignment alignment) -> void override;
auto Rebuild(const size_t size) -> void override; auto Rebuild(size_t size) -> void override;
auto Rebuild(const size_t size, Alignment alignment) -> void override; auto Rebuild(size_t size, Alignment alignment) -> void override;
auto Rebuild(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = nullptr) -> void override; auto Rebuild(void* data, size_t size, fairmq_free_fn* ffn, void* hint = nullptr) -> void override;
auto GetData() const -> void* override; auto GetData() const -> void* override;
auto GetSize() const -> size_t override; auto GetSize() const -> size_t override;
auto SetUsedSize(const size_t size) -> bool override; auto SetUsedSize(size_t size) -> bool override;
auto GetType() const -> fair::mq::Transport override { return fair::mq::Transport::OFI; } auto GetType() const -> fair::mq::Transport override { return fair::mq::Transport::OFI; }

View File

@@ -10,7 +10,7 @@
#include <fairmq/ofi/Socket.h> #include <fairmq/ofi/Socket.h>
#include <fairmq/ofi/TransportFactory.h> #include <fairmq/ofi/TransportFactory.h>
#include <fairmq/tools/Strings.h> #include <fairmq/tools/Strings.h>
#include <FairMQLogger.h> #include <fairlogger/Logger.h>
#include <asiofi.hpp> #include <asiofi.hpp>
#include <asio/buffer.hpp> #include <asio/buffer.hpp>
@@ -43,8 +43,6 @@ Socket::Socket(Context& context, const string& type, const string& name, const s
, fBytesRx(0) , fBytesRx(0)
, fMessagesTx(0) , fMessagesTx(0)
, fMessagesRx(0) , fMessagesRx(0)
, fSndTimeout(100)
, fRcvTimeout(100)
, fMultiPartRecvCounter(-1) , fMultiPartRecvCounter(-1)
, fSendPushSem(fContext.GetIoContext(), 384) , fSendPushSem(fContext.GetIoContext(), 384)
, fSendPopSem(fContext.GetIoContext(), 0) , fSendPopSem(fContext.GetIoContext(), 0)
@@ -250,7 +248,7 @@ auto Socket::ConnectEndpoint(std::unique_ptr<asiofi::connected_endpoint>& endpoi
} }
} }
auto Socket::Send(MessagePtr& msg, const int /*timeout*/) -> int64_t auto Socket::Send(MessagePtr& msg, int /*timeout*/) -> int64_t
{ {
// timeout argument not yet implemented // timeout argument not yet implemented
@@ -261,7 +259,7 @@ auto Socket::Send(MessagePtr& msg, const int /*timeout*/) -> int64_t
return Send(msgVec); return Send(msgVec);
} }
auto Socket::Send(std::vector<MessagePtr>& msgVec, const int /*timeout*/) -> int64_t auto Socket::Send(std::vector<MessagePtr>& msgVec, int /*timeout*/) -> int64_t
try { try {
// timeout argument not yet implemented // timeout argument not yet implemented
@@ -408,7 +406,7 @@ auto Socket::SendQueueReaderStatic() -> void
}); });
} }
auto Socket::Receive(MessagePtr& msg, const int /*timeout*/) -> int64_t auto Socket::Receive(MessagePtr& msg, int /*timeout*/) -> int64_t
try { try {
// timeout argument not yet implemented // timeout argument not yet implemented
@@ -430,7 +428,7 @@ try {
return static_cast<int>(TransferCode::error); return static_cast<int>(TransferCode::error);
} }
auto Socket::Receive(std::vector<MessagePtr>& msgVec, const int /*timeout*/) -> int64_t auto Socket::Receive(std::vector<MessagePtr>& msgVec, int /*timeout*/) -> int64_t
try { try {
// timeout argument not yet implemented // timeout argument not yet implemented
@@ -609,7 +607,7 @@ auto Socket::GetOption(const string& /*option*/, void* /*value*/, size_t* /*valu
// } // }
} }
void Socket::SetLinger(const int /*value*/) void Socket::SetLinger(int /*value*/)
{ {
LOG(debug) << "OFI transport (" << fId << "): Not yet implemented."; LOG(debug) << "OFI transport (" << fId << "): Not yet implemented.";
} }
@@ -620,7 +618,7 @@ int Socket::GetLinger() const
return 0; return 0;
} }
void Socket::SetSndBufSize(const int /*value*/) void Socket::SetSndBufSize(int /*value*/)
{ {
LOG(debug) << "OFI transport (" << fId << "): Not yet implemented."; LOG(debug) << "OFI transport (" << fId << "): Not yet implemented.";
} }
@@ -631,7 +629,7 @@ int Socket::GetSndBufSize() const
return 0; return 0;
} }
void Socket::SetRcvBufSize(const int /*value*/) void Socket::SetRcvBufSize(int /*value*/)
{ {
LOG(debug) << "OFI transport (" << fId << "): Not yet implemented."; LOG(debug) << "OFI transport (" << fId << "): Not yet implemented.";
} }
@@ -642,7 +640,7 @@ int Socket::GetRcvBufSize() const
return 0; return 0;
} }
void Socket::SetSndKernelSize(const int /*value*/) void Socket::SetSndKernelSize(int /*value*/)
{ {
LOG(debug) << "OFI transport (" << fId << "): Not yet implemented."; LOG(debug) << "OFI transport (" << fId << "): Not yet implemented.";
} }
@@ -653,7 +651,7 @@ int Socket::GetSndKernelSize() const
return 0; return 0;
} }
void Socket::SetRcvKernelSize(const int /*value*/) void Socket::SetRcvKernelSize(int /*value*/)
{ {
LOG(debug) << "OFI transport (" << fId << "): Not yet implemented."; LOG(debug) << "OFI transport (" << fId << "): Not yet implemented.";
} }

View File

@@ -36,7 +36,9 @@ class Socket final : public fair::mq::Socket
public: public:
Socket(Context& context, const std::string& type, const std::string& name, const std::string& id = ""); Socket(Context& context, const std::string& type, const std::string& name, const std::string& id = "");
Socket(const Socket&) = delete; Socket(const Socket&) = delete;
Socket operator=(const Socket&) = delete; Socket(Socket&&) = delete;
Socket& operator=(const Socket&) = delete;
Socket& operator=(Socket&&) = delete;
auto GetId() const -> std::string override { return fId; } auto GetId() const -> std::string override { return fId; }
@@ -51,15 +53,15 @@ class Socket final : public fair::mq::Socket
auto GetSocket() const -> void* { return nullptr; } auto GetSocket() const -> void* { return nullptr; }
void SetLinger(const int value) override; void SetLinger(int value) override;
int GetLinger() const override; int GetLinger() const override;
void SetSndBufSize(const int value) override; void SetSndBufSize(int value) override;
int GetSndBufSize() const override; int GetSndBufSize() const override;
void SetRcvBufSize(const int value) override; void SetRcvBufSize(int value) override;
int GetRcvBufSize() const override; int GetRcvBufSize() const override;
void SetSndKernelSize(const int value) override; void SetSndKernelSize(int value) override;
int GetSndKernelSize() const override; int GetSndKernelSize() const override;
void SetRcvKernelSize(const int value) override; void SetRcvKernelSize(int value) override;
int GetRcvKernelSize() const override; int GetRcvKernelSize() const override;
auto Close() -> void override; auto Close() -> void override;
@@ -72,6 +74,11 @@ class Socket final : public fair::mq::Socket
auto GetMessagesTx() const -> unsigned long override { return fMessagesTx; } auto GetMessagesTx() const -> unsigned long override { return fMessagesTx; }
auto GetMessagesRx() const -> unsigned long override { return fMessagesRx; } auto GetMessagesRx() const -> unsigned long override { return fMessagesRx; }
auto GetNumberOfConnectedPeers() const -> unsigned long override
{
throw SocketError("not yet implemented");
}
static auto GetConstant(const std::string& constant) -> int; static auto GetConstant(const std::string& constant) -> int;
~Socket() override; ~Socket() override;
@@ -91,8 +98,6 @@ class Socket final : public fair::mq::Socket
std::atomic<unsigned long> fMessagesRx; std::atomic<unsigned long> fMessagesRx;
Address fRemoteAddr; Address fRemoteAddr;
Address fLocalAddr; Address fLocalAddr;
int fSndTimeout;
int fRcvTimeout;
std::mutex fSendQueueMutex, fRecvQueueMutex; std::mutex fSendQueueMutex, fRecvQueueMutex;
std::queue<std::vector<MessagePtr>> fSendQueue, fRecvQueue; std::queue<std::vector<MessagePtr>> fSendQueue, fRecvQueue;
std::vector<MessagePtr> fInflightMultiPartMessage; std::vector<MessagePtr> fInflightMultiPartMessage;

View File

@@ -55,10 +55,11 @@ struct TransportFactory final : mq::TransportFactory
} }
} }
TransportFactory(TransportFactory const&) = delete; TransportFactory(const TransportFactory&) = delete;
TransportFactory& operator=(TransportFactory const&) = delete; TransportFactory(TransportFactory&&) = delete;
TransportFactory(TransportFactory&&) = default; TransportFactory& operator=(const TransportFactory&) = delete;
TransportFactory& operator=(TransportFactory&&) = default; TransportFactory& operator=(TransportFactory&&) = delete;
~TransportFactory() override = default;
auto CreateMessage() -> std::unique_ptr<mq::Message> override auto CreateMessage() -> std::unique_ptr<mq::Message> override
{ {
@@ -165,6 +166,22 @@ struct TransportFactory final : mq::TransportFactory
throw std::runtime_error("Not yet implemented UMR."); throw std::runtime_error("Not yet implemented UMR.");
} }
auto CreateUnmanagedRegion(std::size_t /*size*/,
RegionCallback /*callback*/,
RegionConfig /*cfg*/)
-> std::unique_ptr<mq::UnmanagedRegion> override
{
throw std::runtime_error("Not yet implemented UMR.");
}
auto CreateUnmanagedRegion(std::size_t /*size*/,
RegionBulkCallback /*callback*/,
RegionConfig /*cfg*/)
-> std::unique_ptr<mq::UnmanagedRegion> override
{
throw std::runtime_error("Not yet implemented UMR.");
}
auto SubscribeToRegionEvents(RegionEventCallback /*callback*/) -> void override auto SubscribeToRegionEvents(RegionEventCallback /*callback*/) -> void override
{ {
throw std::runtime_error("Not yet implemented."); throw std::runtime_error("Not yet implemented.");

View File

@@ -18,6 +18,7 @@
#include <pmix.h> #include <pmix.h>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -86,7 +87,7 @@ struct value : pmix_value_t
PMIX_VALUE_XFER(rc, lhs, static_cast<pmix_value_t*>(const_cast<value*>(&rhs))); PMIX_VALUE_XFER(rc, lhs, static_cast<pmix_value_t*>(const_cast<value*>(&rhs)));
if (rc != PMIX_SUCCESS) { if (rc != PMIX_SUCCESS) {
throw runtime_error("pmix::value copy ctor failed: rc=" + rc); throw runtime_error("pmix::value copy ctor failed: rc=" + std::to_string(rc));
} }
} }

View File

@@ -11,7 +11,7 @@
#include "PMIx.hpp" #include "PMIx.hpp"
#include <FairMQLogger.h> #include <fairlogger/Logger.h>
#include <fairmq/tools/Semaphore.h> #include <fairmq/tools/Semaphore.h>
#include <memory> // make_unique #include <memory> // make_unique
#include <string> #include <string>
@@ -270,7 +270,7 @@ class Commands
// LOG(trace) << "suppressing message from itself"; // LOG(trace) << "suppressing message from itself";
} }
} else { } else {
LOG(ERROR) << "ERROR"; LOG(error) << "ERROR";
} }
if (cbfunc != nullptr) { if (cbfunc != nullptr) {

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