@@ -1854,11 +1854,59 @@ void DataProcessingDevice::handleData(ServiceRegistryRef ref, InputChannelInfo&
18541854 VariableContextHelpers::getTimeslice (variables);
18551855 forwardInputs (ref, slot, dropped, oldestOutputInfo, false , true );
18561856 };
1857+
1858+ auto onInsertion = [](ServiceRegistryRef& ref, std::span<fair::mq::MessagePtr>& messages) {
1859+ O2_LOG_ENABLE (forwarding);
1860+ O2_SIGNPOST_ID_GENERATE (sid, forwarding);
1861+
1862+ auto & spec = ref.get <DeviceSpec const >();
1863+ auto & context = ref.get <DataProcessorContext>();
1864+ if (!context.canForwardEarly || spec.forwards .empty ()) {
1865+ O2_SIGNPOST_EVENT_EMIT (device, sid, " device" , " Early forwardinding not enabled / needed." );
1866+ return ;
1867+ }
1868+
1869+ O2_SIGNPOST_EVENT_EMIT (device, sid, " device" , " Early forwardinding before injecting data into relayer." );
1870+ auto & timesliceIndex = ref.get <TimesliceIndex>();
1871+ auto oldestTimeslice = timesliceIndex.getOldestPossibleOutput ();
1872+
1873+ auto & proxy = ref.get <FairMQDeviceProxy>();
1874+
1875+ O2_SIGNPOST_START (forwarding, sid, " forwardInputs" ,
1876+ " Starting forwarding for incoming messages with oldestTimeslice %zu with copy" ,
1877+ oldestTimeslice.timeslice .value );
1878+ std::vector<fair::mq::Parts> forwardedParts (proxy.getNumForwardChannels ());
1879+ DataProcessingHelpers::routeForwardedMessages (proxy, messages, forwardedParts, true , false );
1880+
1881+ for (int fi = 0 ; fi < proxy.getNumForwardChannels (); fi++) {
1882+ if (forwardedParts[fi].Size () == 0 ) {
1883+ continue ;
1884+ }
1885+ ForwardChannelInfo info = proxy.getForwardChannelInfo (ChannelIndex{fi});
1886+ auto & parts = forwardedParts[fi];
1887+ if (info.policy == nullptr ) {
1888+ O2_SIGNPOST_EVENT_EMIT_ERROR (forwarding, sid, " forwardInputs" , " Forwarding to %{public}s %d has no policy." , info.name .c_str (), fi);
1889+ continue ;
1890+ }
1891+ O2_SIGNPOST_EVENT_EMIT (forwarding, sid, " forwardInputs" , " Forwarding to %{public}s %d" , info.name .c_str (), fi);
1892+ info.policy ->forward (parts, ChannelIndex{fi}, ref);
1893+ }
1894+ auto & asyncQueue = ref.get <AsyncQueue>();
1895+ auto & decongestion = ref.get <DecongestionService>();
1896+ O2_SIGNPOST_ID_GENERATE (aid, async_queue);
1897+ O2_SIGNPOST_EVENT_EMIT (async_queue, aid, " forwardInputs" , " Queuing forwarding oldestPossible %zu" , oldestTimeslice.timeslice .value );
1898+ AsyncQueueHelpers::post (asyncQueue, AsyncTask{.timeslice = oldestTimeslice.timeslice , .id = decongestion.oldestPossibleTimesliceTask , .debounce = -1 , .callback = decongestionCallbackLate}
1899+ .user <DecongestionContext>({.ref = ref, .oldestTimeslice = oldestTimeslice}));
1900+ O2_SIGNPOST_END (forwarding, sid, " forwardInputs" , " Forwarding done" );
1901+ O2_LOG_DISABLE (forwarding);
1902+ };
1903+
18571904 auto relayed = relayer.relay (parts.At (headerIndex)->GetData (),
18581905 &parts.At (headerIndex),
18591906 input,
18601907 nMessages,
18611908 nPayloadsPerHeader,
1909+ onInsertion,
18621910 onDrop);
18631911 switch (relayed.type ) {
18641912 case DataRelayer::RelayChoice::Type::Backpressured:
@@ -2273,9 +2321,13 @@ bool DataProcessingDevice::tryDispatchComputation(ServiceRegistryRef ref, std::v
22732321 bool consumeSomething = action.op == CompletionPolicy::CompletionOp::Consume || action.op == CompletionPolicy::CompletionOp::ConsumeExisting;
22742322
22752323 if (context.canForwardEarly && hasForwards && consumeSomething) {
2276- O2_SIGNPOST_EVENT_EMIT (device, aid, " device" , " Early forwainding: %{public}s." , fmt::format (" {}" , action.op ).c_str ());
2277- auto & timesliceIndex = ref.get <TimesliceIndex>();
2278- forwardInputs (ref, action.slot , currentSetOfInputs, timesliceIndex.getOldestPossibleOutput (), true , action.op == CompletionPolicy::CompletionOp::Consume);
2324+ // We used to do fowarding here, however we now do it much earlier.
2325+ // We still need to clean the inputs which were already consumed
2326+ // via ConsumeExisting and which still have an header to hold the slot.
2327+ // FIXME: do we? This should really happen when we do the forwarding on
2328+ // insertion, because otherwise we lose the relevant information on how to
2329+ // navigate the set of headers. We could actually rely on the messageset index,
2330+ // is that the right thing to do though?
22792331 }
22802332 markInputsAsDone (action.slot );
22812333
0 commit comments