00001 #define TRACE_NAME "TransferOutput"
00002
00003 #include "art/Framework/Core/ModuleMacros.h"
00004 #include "art/Framework/Core/OutputModule.h"
00005 #include "art/Framework/Principal/EventPrincipal.h"
00006 #include "art/Framework/Principal/OutputHandle.h"
00007 #include "art/Framework/Principal/RunPrincipal.h"
00008 #include "art/Framework/Principal/SubRunPrincipal.h"
00009 #include "art/Framework/Services/Registry/ServiceHandle.h"
00010 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
00011 #include "art/Persistency/Provenance/ProductMetaData.h"
00012
00013 #include "canvas/Persistency/Provenance/BranchDescription.h"
00014 #include "canvas/Persistency/Provenance/BranchKey.h"
00015 #include "canvas/Persistency/Provenance/History.h"
00016 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
00017 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
00018 #include "canvas/Persistency/Provenance/ProcessConfigurationID.h"
00019 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
00020 #include "canvas/Persistency/Provenance/ProductList.h"
00021 #include "canvas/Persistency/Provenance/ProductProvenance.h"
00022 #include "canvas/Persistency/Provenance/RunAuxiliary.h"
00023 #include "canvas/Persistency/Provenance/SubRunAuxiliary.h"
00024 #include "canvas/Utilities/DebugMacros.h"
00025 #include "canvas/Utilities/Exception.h"
00026 #include "cetlib/column_width.h"
00027 #include "cetlib/lpad.h"
00028 #include "cetlib/rpad.h"
00029 #include <algorithm>
00030 # include <iterator>
00031 #include "fhiclcpp/ParameterSet.h"
00032 #include "fhiclcpp/ParameterSetID.h"
00033 #include "fhiclcpp/ParameterSetRegistry.h"
00034
00035 #include "artdaq/TransferPlugins/TransferInterface.hh"
00036 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
00037 #include "artdaq-core/Data/detail/ParentageMap.hh"
00038 #include "artdaq/DAQdata/Globals.hh"
00039 #include "artdaq/DAQdata/NetMonHeader.hh"
00040
00041 #include <iomanip>
00042 #include <iostream>
00043 #include <sstream>
00044 #include <string>
00045 #include <vector>
00046
00047 #include <unistd.h>
00048
00049 #include <TClass.h>
00050 #include <TMessage.h>
00051
00052 namespace art
00053 {
00054 class TransferOutput;
00055 }
00056
00057
00063 class art::TransferOutput : public OutputModule
00064 {
00065 public:
00073 explicit TransferOutput(fhicl::ParameterSet const& ps);
00074
00078 ~TransferOutput();
00079
00080 private:
00081 virtual void openFile(FileBlock const&);
00082
00083 virtual void closeFile();
00084
00085 virtual void respondToCloseInputFile(FileBlock const&);
00086
00087 virtual void respondToCloseOutputFiles(FileBlock const&);
00088
00089 virtual void endJob();
00090
00091 virtual void write(EventPrincipal&);
00092
00093 virtual void writeRun(RunPrincipal&);
00094
00095 virtual void writeSubRun(SubRunPrincipal&);
00096
00097 void writeDataProducts(TBufferFile&, const Principal&,
00098 std::vector<BranchKey*>&);
00099
00100 private:
00101 bool initMsgSent_;
00102 size_t send_timeout_us_;
00103 size_t send_retry_count_;
00104 std::unique_ptr<artdaq::TransferInterface> transfer_;
00105
00106 void sendMessage_(uint64_t sequenceId, uint8_t messageType, TBufferFile& msg);
00107 void send_init_message();
00108
00109 };
00110
00111 art::TransferOutput::
00112 TransferOutput(fhicl::ParameterSet const& ps)
00113 : OutputModule(ps)
00114 , initMsgSent_(false)
00115 , send_timeout_us_(ps.get<size_t>("send_timeout_us", 5000000))
00116 , send_retry_count_(ps.get<size_t>("send_retry_count", 5))
00117 {
00118 TLOG(TLVL_DEBUG) << "Begin: TransferOutput::TransferOutput(ParameterSet const& ps)";
00119 transfer_ = artdaq::MakeTransferPlugin(ps, "transfer_plugin", artdaq::TransferInterface::Role::kSend);
00120 TLOG(TLVL_DEBUG) << "END: TransferOutput::TransferOutput";
00121 }
00122
00123 art::TransferOutput::
00124 ~TransferOutput()
00125 {
00126 TLOG(TLVL_DEBUG) << "Begin: TransferOutput::~TransferOutput()";
00127
00128 auto sts = transfer_->moveFragment(std::move(*artdaq::Fragment::eodFrag(0)));
00129 if (sts != artdaq::TransferInterface::CopyStatus::kSuccess) TLOG(TLVL_ERROR) << "Error sending EOD Fragment!";
00130 transfer_.reset(nullptr);
00131 TLOG(TLVL_DEBUG) << "End: TransferOutput::~TransferOutput()";
00132 }
00133
00134 void
00135 art::TransferOutput::
00136 openFile(FileBlock const&)
00137 {
00138 TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::openFile(const FileBlock&)";
00139 }
00140
00141 void
00142 art::TransferOutput::
00143 closeFile()
00144 {
00145 TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::closeFile()";
00146 }
00147
00148 void
00149 art::TransferOutput::
00150 respondToCloseInputFile(FileBlock const&)
00151 {
00152 TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::" <<
00153 "respondToCloseOutputFiles(FileBlock const&)";
00154 }
00155
00156 void
00157 art::TransferOutput::
00158 respondToCloseOutputFiles(FileBlock const&)
00159 {
00160 TLOG(TLVL_TRACE) << "Begin/End: TransferOutput::" <<
00161 "respondToCloseOutputFiles(FileBlock const&)";
00162 }
00163
00164 void
00165 art::TransferOutput::
00166 endJob()
00167 {
00168 TLOG(TLVL_TRACE) << "Begin: TransferOutput::endJob()";
00169 }
00170
00171
00172
00173 void
00174 art::TransferOutput::
00175 send_init_message()
00176 {
00177 TLOG(TLVL_TRACE) << "Begin: TransferOutput static send_init_message()";
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 static TClass* product_list_class = TClass::GetClass(
00188 "std::map<art::BranchKey,art::BranchDescription>");
00189 if (product_list_class == nullptr)
00190 {
00191 throw art::Exception(art::errors::DictionaryNotFound) <<
00192 "TransferOutput static send_init_message(): "
00193 "Could not get TClass for "
00194 "map<art::BranchKey,art::BranchDescription>!";
00195 }
00196
00197
00198
00199
00200 static TClass* process_history_map_class = TClass::GetClass(
00201 "std::map<const art::Hash<2>,art::ProcessHistory>");
00202 if (process_history_map_class == nullptr)
00203 {
00204 throw art::Exception(art::errors::DictionaryNotFound) <<
00205 "TransferOutput static send_init_message(): "
00206 "Could not get class for "
00207 "std::map<const art::Hash<2>,art::ProcessHistory>!";
00208 }
00209
00210
00211
00212 static TClass* parentage_map_class = TClass::GetClass("art::ParentageMap");
00213 if (parentage_map_class == nullptr)
00214 {
00215 throw art::Exception(art::errors::DictionaryNotFound) <<
00216 "TransferOutput static send_init_message(): "
00217 "Could not get class for ParentageMap";
00218 }
00219
00220
00221
00222 TBufferFile msg(TBuffer::kWrite);
00223 msg.SetWriteMode();
00224
00225
00226
00227 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
00228 "Streaming message type code ...";
00229 msg.WriteULong(1);
00230 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
00231 "Finished streaming message type code.";
00232
00233
00234
00235
00236 unsigned long ps_cnt = fhicl::ParameterSetRegistry::size();
00237 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): parameter set count: " << ps_cnt;
00238 msg.WriteULong(ps_cnt);
00239 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Streaming parameter sets ...";
00240 for (
00241 auto I = std::begin(fhicl::ParameterSetRegistry::get()),
00242 E = std::end(fhicl::ParameterSetRegistry::get());
00243 I != E; ++I)
00244 {
00245 std::string pset_str = I->second.to_string();
00246
00247 msg.WriteStdString(pset_str);
00248 }
00249 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Finished streaming parameter sets.";
00250
00251
00252
00253
00254 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Streaming MasterProductRegistry ...";;
00255 art::ProductList productList(art::ProductMetaData::instance().productList());
00256 msg.WriteObjectAny(&productList, product_list_class);
00257 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): Finished streaming MasterProductRegistry.";
00258
00259 art::ProcessHistoryMap phr;
00260 for (auto const& pr : art::ProcessHistoryRegistry::get())
00261 {
00262 phr.emplace(pr);
00263 }
00264
00265
00266
00267 if (art::debugit() >= 1)
00268 {
00269 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
00270 "Dumping ProcessHistoryRegistry ...";
00271
00272
00273 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
00274 "phr: size: " + std::to_string(phr.size());
00275 for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
00276 {
00277 std::ostringstream OS;
00278 I->first.print(OS);
00279 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
00280 "phr: id: '" + OS.str() + "'";
00281 }
00282 }
00283
00284
00285
00286
00287 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
00288 "Streaming ProcessHistoryRegistry ...";
00289
00290
00291 const art::ProcessHistoryMap& phm = phr;
00292 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
00293 "phm: size: " << phm.size();
00294 msg.WriteObjectAny(&phm, process_history_map_class);
00295 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): " <<
00296 "Finished streaming ProcessHistoryRegistry.";
00297
00298
00299
00300
00301 #if 0
00302 TLOG(TLVL_DEBUG) << "TransferOutput static send_init_message(): " <<
00303 "Streaming ParentageRegistry ... sz=" << msg.Length();
00304 #endif
00305 art::ParentageMap parentageMap{};
00306 for (auto const& pr : art::ParentageRegistry::get())
00307 {
00308 parentageMap.emplace(pr.first, pr.second);
00309 }
00310
00311 TLOG(TLVL_TRACE) << "Before WriteObjectAny ParentageMap";
00312 #if 0
00313 auto sts =
00314 #endif
00315 msg.WriteObjectAny(&parentageMap, parentage_map_class);
00316 TLOG(TLVL_TRACE) << "After WriteObjectAny ParentageMap";
00317 #if 0
00318 TLOG(TLVL_DEBUG) << "TransferOutput: TransferOutput static send_init_message(): " <<
00319 "Finished streaming ParentageRegistry." << " sts=" << sts << ", sz=" << msg.Length();
00320 #endif
00321
00322
00323
00324
00325
00326 TLOG(TLVL_DEBUG) << "TransferOutput: TransferOutput static send_init_message(): " << "Sending the init message.";
00327 sendMessage_(artdaq::Fragment::InvalidSequenceID - 1, artdaq::Fragment::InitFragmentType, msg);
00328 TLOG(TLVL_TRACE) << " TransferOutput static send_init_message(): "
00329 "Init message(s) sent.";
00330
00331 TLOG(TLVL_TRACE) << " End: TransferOutput static send_init_message()";
00332 }
00333
00334 #//pragma GCC pop_options
00335
00336 void
00337 art::TransferOutput::
00338 writeDataProducts(TBufferFile& msg, const Principal& principal,
00339 std::vector<BranchKey*>& bkv)
00340 {
00341 TLOG(TLVL_TRACE) << " Begin: TransferOutput::writeDataProducts(...)";
00342
00343
00344
00345
00346 static TClass* branch_key_class = TClass::GetClass("art::BranchKey");
00347 if (branch_key_class == nullptr)
00348 {
00349 throw art::Exception(art::errors::DictionaryNotFound) <<
00350 "TransferOutput::writeDataProducts(...): "
00351 "Could not get TClass for art::BranchKey!";
00352 }
00353 static TClass* prdprov_class = TClass::GetClass("art::ProductProvenance");
00354 if (prdprov_class == nullptr)
00355 {
00356 throw art::Exception(art::errors::DictionaryNotFound) <<
00357 "TransferOutput::writeDataProducts(...): "
00358 "Could not get TClass for art::ProductProvenance!";
00359 }
00360
00361
00362
00363 unsigned long prd_cnt = 0;
00364
00365 for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
00366 {
00367 auto const& productDescription = I->second->productDescription();
00368 auto const& refs = keptProducts()[productDescription.branchType()];
00369 bool found = false;
00370 for (auto const& ref : refs)
00371 {
00372 if (*ref == productDescription)
00373 {
00374 found = true;
00375 break;
00376 }
00377 }
00378 if (I->second->productUnavailable() || !found)
00379 {
00380 continue;
00381 }
00382 ++prd_cnt;
00383 }
00384
00385
00386
00387 {
00388 TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
00389 "Streaming product count: " << prd_cnt;
00390 msg.WriteULong(prd_cnt);
00391 TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
00392 "Finished streaming product count.";
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 bkv.reserve(prd_cnt);
00405
00406 for (auto I = principal.begin(), E = principal.end(); I != E; ++I)
00407 {
00408 auto const& productDescription = I->second->productDescription();
00409 auto const& refs = keptProducts()[productDescription.branchType()];
00410 bool found = false;
00411 for (auto const& ref : refs)
00412 {
00413 if (*ref == productDescription)
00414 {
00415 found = true;
00416 break;
00417 }
00418 }
00419 if (I->second->productUnavailable() || !found)
00420 {
00421 continue;
00422 }
00423 const BranchDescription& bd(I->second->productDescription());
00424 bkv.push_back(new BranchKey(bd));
00425 if (art::debugit() >= 2)
00426 {
00427 TLOG(TLVL_TRACE) << "TransferOutput::writeDataProducts(...): "
00428 "Dumping branch key of class: '"
00429 << bkv.back()->friendlyClassName_
00430 << "' modlbl: '"
00431 << bkv.back()->moduleLabel_
00432 << "' instnm: '"
00433 << bkv.back()->productInstanceName_
00434 << "' procnm: '"
00435 << bkv.back()->processName_
00436 << "'";
00437 }
00438 {
00439 TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
00440 "Streaming branch key of class: '"
00441 + bd.producedClassName()
00442 + "' modlbl: '"
00443 + bd.moduleLabel()
00444 + "' instnm: '"
00445 + bd.productInstanceName()
00446 + "' procnm: '"
00447 + bd.processName()
00448 + "'";
00449 msg.WriteObjectAny(bkv.back(), branch_key_class);
00450 }
00451 {
00452 TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
00453 "Streaming product of class: '"
00454 + bd.producedClassName()
00455 + "' modlbl: '"
00456 + bd.moduleLabel()
00457 + "' instnm: '"
00458 + bd.productInstanceName()
00459 + "' procnm: '"
00460 + bd.processName()
00461 + "'";
00462
00463 OutputHandle oh = principal.getForOutput(bd.productID(), true);
00464 const EDProduct* prd = oh.wrapper();
00465 msg.WriteObjectAny(prd, TClass::GetClass(bd.wrappedName().c_str()));
00466 }
00467 {
00468 TLOG(TLVL_TRACE) << " TransferOutput::writeDataProducts(...): "
00469 "Streaming product provenance of class: '"
00470 + bd.producedClassName()
00471 + "' modlbl: '"
00472 + bd.moduleLabel()
00473 + "' instnm: '"
00474 + bd.productInstanceName()
00475 + "' procnm: '"
00476 + bd.processName()
00477 + "'";
00478 const ProductProvenance* prdprov =
00479 I->second->productProvenancePtr().get();
00480 msg.WriteObjectAny(prdprov, prdprov_class);
00481 }
00482 }
00483 TLOG(TLVL_TRACE) << " End: TransferOutput::writeDataProducts(...)";
00484 }
00485
00486 void
00487 art::TransferOutput::
00488 write(EventPrincipal& ep)
00489 {
00490
00491
00492
00493 TLOG(TLVL_TRACE) << " Begin: TransferOutput::"
00494 "write(const EventPrincipal& ep)";
00495 if (!initMsgSent_)
00496 {
00497 send_init_message();
00498 initMsgSent_ = true;
00499 }
00500
00501
00502
00503 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
00504 if (run_aux_class == nullptr)
00505 {
00506 throw art::Exception(art::errors::DictionaryNotFound) <<
00507 "TransferOutput::write(const EventPrincipal& ep): "
00508 "Could not get TClass for art::RunAuxiliary!";
00509 }
00510 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
00511 if (subrun_aux_class == nullptr)
00512 {
00513 throw art::Exception(art::errors::DictionaryNotFound) <<
00514 "TransferOutput::write(const EventPrincipal& ep): "
00515 "Could not get TClass for art::SubRunAuxiliary!";
00516 }
00517 static TClass* event_aux_class = TClass::GetClass("art::EventAuxiliary");
00518 if (event_aux_class == nullptr)
00519 {
00520 throw art::Exception(art::errors::DictionaryNotFound) <<
00521 "TransferOutput::write(const EventPrincipal& ep): "
00522 "Could not get TClass for art::EventAuxiliary!";
00523 }
00524 static TClass* history_class = TClass::GetClass("art::History");
00525 if (history_class == nullptr)
00526 {
00527 throw art::Exception(art::errors::DictionaryNotFound) <<
00528 "TransferOutput::write(const EventPrincipal& ep): "
00529 "Could not get TClass for art::History!";
00530 }
00531
00532
00533
00534 TBufferFile msg(TBuffer::kWrite);
00535 msg.SetWriteMode();
00536
00537
00538
00539 {
00540 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00541 "Streaming message type code ...";
00542 msg.WriteULong(4);
00543 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00544 "Finished streaming message type code.";
00545 }
00546
00547
00548
00549 {
00550 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00551 "Streaming RunAuxiliary ...";
00552 msg.WriteObjectAny(&ep.subRunPrincipal().runPrincipal().aux(),
00553 run_aux_class);
00554 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00555 "Finished streaming RunAuxiliary.";
00556 }
00557
00558
00559
00560 {
00561 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00562 "Streaming SubRunAuxiliary ...";
00563 msg.WriteObjectAny(&ep.subRunPrincipal().aux(),
00564 subrun_aux_class);
00565 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00566 "Finished streaming SubRunAuxiliary.";
00567 }
00568
00569
00570
00571 {
00572 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00573 "Streaming EventAuxiliary ...";
00574 msg.WriteObjectAny(&ep.aux(), event_aux_class);
00575 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00576 "Finished streaming EventAuxiliary.";
00577 }
00578
00579
00580
00581 {
00582 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00583 "Streaming History ...";
00584 msg.WriteObjectAny(&ep.history(), history_class);
00585 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00586 "Finished streaming History.";
00587 }
00588
00589
00590
00591 std::vector<BranchKey*> bkv;
00592 writeDataProducts(msg, ep, bkv);
00593
00594
00595
00596 {
00597 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00598 "Sending a message ...";
00599 sendMessage_(ep.id().event(), artdaq::Fragment::DataFragmentType, msg);
00600 TLOG(TLVL_TRACE) << " TransferOutput::write(const EventPrincipal& ep): "
00601 "Message sent.";
00602 }
00603
00604
00605
00606 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
00607 {
00608 delete *I;
00609 *I = 0;
00610 }
00611 TLOG(TLVL_TRACE) << " End: TransferOutput::write(const EventPrincipal& ep)";
00612 }
00613
00614 void
00615 art::TransferOutput::
00616 writeRun(RunPrincipal& rp)
00617 {
00618
00619
00620
00621 TLOG(TLVL_TRACE) << " Begin: TransferOutput::writeRun(const RunPrincipal& rp)";
00622 (void)rp;
00623 if (!initMsgSent_)
00624 {
00625 send_init_message();
00626 initMsgSent_ = true;
00627 }
00628 #if 0
00629
00630
00631
00632
00633 static TClass* run_aux_class = TClass::GetClass("art::RunAuxiliary");
00634 assert(run_aux_class != nullptr && "writeRun: Could not get TClass for "
00635 "art::RunAuxiliary!");
00636
00637
00638
00639 TBufferFile msg(TBuffer::kWrite);
00640 msg.SetWriteMode();
00641
00642
00643
00644 {
00645 TLOG(TLVL_TRACE) << " writeRun: streaming message type code ...");
00646 msg.WriteULong(2);
00647 TLOG(TLVL_TRACE) << " writeRun: finished streaming message type code.");
00648 }
00649
00650
00651
00652 {
00653 TLOG(TLVL_TRACE) << " writeRun: streaming RunAuxiliary ...");
00654 if (art::debugit() >= 1)
00655 {
00656 TLOG(TLVL_TRACE) << " writeRun: dumping ProcessHistoryRegistry ...");
00657
00658
00659 art::ProcessHistoryMap const& phr =
00660 art::ProcessHistoryRegistry::get();
00661 TLOG(TLVL_TRACE) << " writeRun: phr: size: " << phr.size() << '\n';
00662 for (auto I = phr.begin(), E = phr.end(); I != E; ++I)
00663 {
00664 std::ostringstream OS;
00665 I->first.print(OS);
00666 TLOG(TLVL_TRACE) << " writeRun: phr: id: '" << OS.str() << "'");
00667 OS.str("");
00668 TLOG(TLVL_TRACE) << " writeRun: phr: data.size(): "
00669 << I->second.data().size() << '\n';
00670 if (I->second.data().size())
00671 {
00672 I->second.data().back().id().print(OS);
00673 TLOG(TLVL_TRACE) << " writeRun: phr: data.back().id(): '"
00674 << OS.str() << "'");
00675 }
00676 }
00677 if (!rp.aux().processHistoryID().isValid())
00678 {
00679 TLOG(TLVL_TRACE) << " writeRun: ProcessHistoryID: 'INVALID'");
00680 }
00681 else
00682 {
00683 std::ostringstream OS;
00684 rp.aux().processHistoryID().print(OS);
00685 TLOG(TLVL_TRACE) << " writeRun: ProcessHistoryID: '"
00686 << OS.str() << "'");
00687 OS.str("");
00688 const ProcessHistory& processHistory =
00689 ProcessHistoryRegistry::get(rp.aux().processHistoryID());
00690 if (processHistory.data().size())
00691 {
00692
00693 processHistory.data().back().id().print(OS);
00694 TLOG(TLVL_TRACE) << " writeRun: ProcessConfigurationID: '"
00695 << OS.str() << "'");
00696 OS.str("");
00697 TLOG(TLVL_TRACE) << " writeRun: ProcessConfiguration: '"
00698 << processHistory.data().back() << '\n';
00699 }
00700 }
00701 }
00702 msg.WriteObjectAny(&rp.aux(), run_aux_class);
00703 TLOG(TLVL_TRACE) << " writeRun: streamed RunAuxiliary.");
00704 }
00705
00706
00707
00708 std::vector<BranchKey*> bkv;
00709 writeDataProducts(msg, rp, bkv);
00710
00711
00712
00713 {
00714 TLOG(TLVL_TRACE) << " writeRun: sending a message ...");
00715 sendMessage_(0, artdaq::Fragment::EndOfRunFragmentType, msg);
00716 TLOG(TLVL_TRACE) << " writeRun: message sent.");
00717 }
00718
00719
00720
00721 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
00722 {
00723 delete *I;
00724 *I = 0;
00725 }
00726 #endif // 0
00727 TLOG(TLVL_TRACE) << " End: TransferOutput::writeRun(const RunPrincipal& rp)";
00728 }
00729
00730 void
00731 art::TransferOutput::writeSubRun(SubRunPrincipal& srp)
00732 {
00733
00734
00735
00736 TLOG(TLVL_TRACE) << " Begin: TransferOutput::"
00737 "writeSubRun(const SubRunPrincipal& srp)";
00738 if (!initMsgSent_)
00739 {
00740 send_init_message();
00741 initMsgSent_ = true;
00742 }
00743
00744
00745
00746
00747 static TClass* subrun_aux_class = TClass::GetClass("art::SubRunAuxiliary");
00748 if (subrun_aux_class == nullptr)
00749 {
00750 throw art::Exception(art::errors::DictionaryNotFound) <<
00751 "TransferOutput::writeSubRun: "
00752 "Could not get TClass for art::SubRunAuxiliary!";
00753 }
00754
00755
00756
00757 TBufferFile msg(TBuffer::kWrite);
00758 msg.SetWriteMode();
00759
00760
00761
00762 {
00763 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00764 "streaming message type code ...";
00765 msg.WriteULong(3);
00766 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00767 "finished streaming message type code.";
00768 }
00769
00770
00771
00772 {
00773 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00774 "streaming SubRunAuxiliary ...";
00775 if (art::debugit() >= 1)
00776 {
00777 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00778 "dumping ProcessHistoryRegistry ...";
00779
00780
00781 for (auto I = std::begin(art::ProcessHistoryRegistry::get())
00782 , E = std::end(art::ProcessHistoryRegistry::get()); I != E; ++I)
00783 {
00784 std::ostringstream OS;
00785 I->first.print(OS);
00786 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00787 "phr: id: '" + OS.str() + "'";
00788 OS.str("");
00789 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00790 "phr: data.size(): " << I->second.data().size();
00791 if (I->second.data().size())
00792 {
00793 I->second.data().back().id().print(OS);
00794 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00795 "phr: data.back().id(): '"
00796 + OS.str() + "'";
00797 }
00798 }
00799 if (!srp.aux().processHistoryID().isValid())
00800 {
00801 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00802 "ProcessHistoryID: 'INVALID'";;
00803 }
00804 else
00805 {
00806 std::ostringstream OS;
00807 srp.aux().processHistoryID().print(OS);
00808 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: ProcessHistoryID: '"
00809 + OS.str() + "'";
00810 OS.str("");
00811 ProcessHistory processHistory;
00812 ProcessHistoryRegistry::get(srp.aux().processHistoryID(), processHistory);
00813 if (processHistory.data().size())
00814 {
00815
00816 processHistory.data().back().id().print(OS);
00817 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00818 "ProcessConfigurationID: '"
00819 + OS.str() + "'";
00820 OS.str("");
00821 OS << processHistory.data().back();
00822 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00823 "ProcessConfiguration: '"
00824 + OS.str();
00825 }
00826 }
00827 }
00828 msg.WriteObjectAny(&srp.aux(), subrun_aux_class);
00829 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: streamed SubRunAuxiliary.";
00830 }
00831
00832
00833
00834 std::vector<BranchKey*> bkv;
00835 writeDataProducts(msg, srp, bkv);
00836
00837
00838
00839 {
00840 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00841 "Sending the EndOfSubrun message.";
00842 sendMessage_(0, artdaq::Fragment::EndOfSubrunFragmentType, msg);
00843 TLOG(TLVL_TRACE) << " TransferOutput::writeSubRun: "
00844 "EndOfSubrun message(s) sent.";
00845
00846 }
00847
00848
00849
00850 for (auto I = bkv.begin(), E = bkv.end(); I != E; ++I)
00851 {
00852 delete *I;
00853 *I = 0;
00854 }
00855 TLOG(TLVL_TRACE) << " End: TransferOutput::writeSubRun(const SubRunPrincipal& srp)";
00856 }
00857
00858
00859 void
00860 art::TransferOutput::sendMessage_(uint64_t sequenceId, uint8_t messageType, TBufferFile& msg)
00861 {
00862 TLOG(TLVL_DEBUG) << "Sending message with sequenceID=" << sequenceId << ", type=" << (int)messageType << ", length=" << msg.Length();
00863 artdaq::NetMonHeader header;
00864 header.data_length = static_cast<uint64_t>(msg.Length());
00865 artdaq::Fragment
00866 fragment(std::ceil(msg.Length() /
00867 static_cast<double>(sizeof(artdaq::RawDataType))),
00868 sequenceId, 0, messageType, header);
00869
00870 memcpy(&*fragment.dataBegin(), msg.Buffer(), msg.Length());
00871 auto sts = artdaq::TransferInterface::CopyStatus::kErrorNotRequiringException;
00872 size_t retries = 0;
00873 while (sts != artdaq::TransferInterface::CopyStatus::kSuccess && retries <= send_retry_count_)
00874 {
00875 sts = transfer_->copyFragment(fragment, send_timeout_us_);
00876 retries++;
00877 }
00878
00879 #if 0
00880 if (messageType == artdaq::Fragment::InitFragmentType)
00881 {
00882 std::fstream ostream("sendInitMessage_TransferOutput.bin", std::ios::out | std::ios::binary);
00883 ostream.write(msg.Buffer(), msg.Length());
00884 ostream.close();
00885 }
00886 #endif
00887
00888 }
00889
00890 DEFINE_ART_MODULE(art::TransferOutput)