2121#include " Framework/CallbackService.h"
2222#include " Framework/ControlService.h"
2323#include " Framework/SourceInfoHeader.h"
24+ #include " Framework/ConfigParamRegistry.h"
2425#include " Headers/DataHeader.h"
2526#include " Headers/Stack.h"
2627
3738#include < numeric> // std::accumulate
3839#include < sstream>
3940#include < stdexcept>
41+ #include < regex>
4042
4143namespace o2 ::framework
4244{
@@ -438,15 +440,28 @@ DataProcessorSpec specifyFairMQDeviceOutputProxy(char const* name,
438440 spec.name = name;
439441 spec.inputs = inputSpecs;
440442 spec.outputs = {};
441- spec.algorithm = adaptStateful ([inputSpecs](CallbackService& callbacks, RawDeviceService& rds, DeviceSpec const & deviceSpec) {
443+ spec.algorithm = adaptStateful ([inputSpecs](CallbackService& callbacks, RawDeviceService& rds, DeviceSpec const & deviceSpec, ConfigParamRegistry const & options) {
444+ // we can retrieve the channel name from the channel configuration string
445+ // FIXME: even if a --channel-config option is specified on the command line, always the default string
446+ // is retrieved from the config registry. The channel name thus needs to be configured in the default
447+ // string AND must match the name in an optional channel config.
448+ std::string channelConfig = options.get <std::string>(" channel-config" );
449+ std::regex r{R"( name=([^,]*))" };
450+ std::vector<std::string> values{std::sregex_token_iterator{std::begin (channelConfig), std::end (channelConfig), r, 1 },
451+ std::sregex_token_iterator{}};
452+ if (values.size () != 1 || values[0 ].empty ()) {
453+ throw std::runtime_error (" failed to extract channel name from channel configuration parameter '" + channelConfig + " '" );
454+ }
455+ std::string outputChannelName = values[0 ];
456+
442457 auto * device = rds.device ();
443458 // check that the input spec bindings have corresponding output channels
444459 // FairMQDevice calls the custom init before the channels have been configured
445460 // so we do the check before starting in a dedicated callback
446- auto channelConfigurationChecker = [inputSpecs = std::move (inputSpecs), device]() {
461+ auto channelConfigurationChecker = [inputSpecs = std::move (inputSpecs), device, outputChannelName ]() {
447462 LOG (INFO ) << " checking channel configuration" ;
448- if (device->fChannels .count (" downstream " ) == 0 ) {
449- throw std::runtime_error (" no corresponding output channel found for input 'downstream '" );
463+ if (device->fChannels .count (outputChannelName ) == 0 ) {
464+ throw std::runtime_error (" no corresponding output channel found for input '" + outputChannelName + " '" );
450465 }
451466 };
452467 callbacks.set (CallbackService::Id::Start, channelConfigurationChecker);
@@ -461,20 +476,17 @@ DataProcessorSpec specifyFairMQDeviceOutputProxy(char const* name,
461476 for (auto const & inputSpec : inputSpecs) {
462477 // this is a prototype, in principle we want to have all spec objects const
463478 // and so only the const object can be retrieved from service registry
464- ForwardRoute route{0 , 1 , inputSpec, " downstream " };
479+ ForwardRoute route{0 , 1 , inputSpec, outputChannelName };
465480 const_cast <DeviceSpec&>(deviceSpec).forwards .emplace_back (route);
466481 }
467482
468- auto forwardEos = [device, lastDataProcessingHeader](EndOfStreamContext&) {
483+ auto forwardEos = [device, lastDataProcessingHeader, outputChannelName ](EndOfStreamContext&) {
469484 // DPL implements an internal end of stream signal, which is propagated through
470485 // all downstream channels if a source is dry, make it available to other external
471486 // devices via a message of type {DPL/EOS/0}
472487 for (auto & channelInfo : device->fChannels ) {
473- // FIXME: in this function the channel name is hardcoded to 'downstream'
474- // have to check if this simply should be combined with the function below
475- // supporting multiple outputs
476488 auto & channelName = channelInfo.first ;
477- if (channelName != " downstream " ) {
489+ if (channelName != outputChannelName ) {
478490 continue ;
479491 }
480492 DataHeader dh;
@@ -570,9 +582,6 @@ DataProcessorSpec specifyFairMQDeviceMultiOutputProxy(char const* name,
570582 // all downstream channels if a source is dry, make it available to other external
571583 // devices via a message of type {DPL/EOS/0}
572584 for (auto & channelInfo : device->fChannels ) {
573- // FIXME: in this function the channel name is hardcoded to 'downstream'
574- // have to check if this simply should be combined with the function below
575- // supporting multiple outputs
576585 auto & channelName = channelInfo.first ;
577586 auto checkChannel = [channelNames = std::move (*channelNames)](std::string const & name) -> bool {
578587 for (auto const & n : channelNames) {
0 commit comments