The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
main.cpp File Reference
#include <Gaudi/Application.h>
#include <Gaudi/Interfaces/IQueueingEventProcessor.h>
#include <GaudiKernel/AppReturnCode.h>
#include <GaudiKernel/IMessageSvc.h>
#include <GaudiKernel/IProperty.h>
#include <queue>
#include <thread>
Include dependency graph for main.cpp:

Go to the source code of this file.

Functions

int main ()
 

Function Documentation

◆ main()

int main ( )

Definition at line 42 of file main.cpp.

42 {
43 { // useless scope, just to get the same indentation as QueueingApplication.cpp (most of the code is identical)
44
46 { "ApplicationMgr.JobOptionsType", "\"NONE\"" },
47 { "ApplicationMgr.EventLoop", "\"Gaudi::TestSuite::QueueingEventLoopMgr/QueueingEventLoopMgr\"" },
48 { "ApplicationMgr.OutputLevel", "3" },
49 { "ApplicationMgr.TopAlg", "['GaudiTesting::SleepyAlg/Alg1']" },
50 { "Alg1.SleepTime", "1" },
51 { "QueueingEventLoopMgr.OutputLevel", "2" },
52 { "QueueingEventLoopMgr.Capacity", "3" } };
53
54 auto app = Gaudi::Application( std::move( opts ) );
55
56 return app.run( []( SmartIF<IStateful>& app ) -> int {
57 // - parameters for the job
58 const std::size_t n_of_batches = 2;
59 const std::size_t evts_in_batch = 5;
60
61 // - get ready to process events
62 app->initialize().ignore();
63
64 // - this MsgStream is useful to have uniform printout
65 MsgStream log( app.as<IMessageSvc>(), "<main>" );
66
67 // we print the parameters here so that they appear close to the Capacity in the log
68 log << MSG::INFO << " n_of_batches: " << n_of_batches << endmsg;
69 log << MSG::INFO << " evts_in_batch: " << evts_in_batch << endmsg;
70
71 app->start().ignore(); // this starts the QueueingEventLoopMgr processing thread
72
73 // - main processing loop
74 {
75 // - get the IQueueingEventProcessor interface of the application
77
78 // - processing state informations
79 // - events ready to be processed
80 std::queue<EventContext> ready;
81 // - count of events enqueued
82 std::size_t evt_count = 0;
83
84 // - loop over input batches
85 for ( std::size_t batch = 1; batch <= n_of_batches; ++batch ) {
86 // - prepare the batch
87 log << MSG::INFO << "prepare batch of events n. " << batch << endmsg;
88 if ( batch == 2 ) {
89 log << MSG::INFO << " (pretend we need time so that the processing thread drains the input queue)"
90 << endmsg;
91 sleep_for( 4s );
92 log << MSG::INFO << " (all events in the queue should have been processed by now)" << endmsg;
93 }
94 for ( std::size_t i = 0; i < evts_in_batch; ++i ) {
95 // - create a new EventContext for each event in the batch
96 auto ctx = qep->createEventContext();
97 // ... here you can do something with the context ... like setting I/O related stuff
98 // - declare the event as ready to be enqueued
99 ready.push( std::move( ctx ) );
100 }
101
102 // - once the batch is ready we can push all events, relying on the push to block if needed
103 log << MSG::INFO << "looping over the batch" << endmsg;
104 while ( !ready.empty() ) {
105 ++evt_count;
106 log << MSG::INFO << "- pushing event " << evt_count << " (" << ready.front() << ")..." << endmsg;
107 qep->push( std::move( ready.front() ) ); // this blocks if the system is full
108 ready.pop();
109 log << MSG::INFO << " ... event " << evt_count << " pushed" << endmsg;
110
111 // - for each push we try a pop, to avoid that the output queue gets too big
112 log << MSG::INFO << "- checking for completed events" << endmsg;
113 if ( auto result = qep->pop() ) { // this never blocks, but evaulates to false if there was nothing to pop
114 // - if an event completed, we can do something (e.g. I/O)
115 auto&& [sc, ctx] = std::move( *result );
116 log << MSG::INFO << " " << ctx << " -> " << sc << endmsg;
117 }
118 }
119 }
120 log << MSG::INFO << "no more inputs: let's drain the output queue" << endmsg;
121 while ( !qep->empty() ) {
122 if ( auto result = qep->pop() ) {
123 auto&& [sc, ctx] = std::move( *result );
124 log << MSG::INFO << " " << ctx << " -> " << sc << endmsg;
125 } else {
126 sleep_for( 10ms );
127 }
128 }
129
130 // - nothing else to do on the events
131 log << MSG::INFO << "all done" << endmsg;
132 }
133
134 // - terminate the application
135 app->stop().ignore(); // this stops the QueueingEventLoopMgr processing thread
136 app->finalize().ignore();
137
138 // - get and propagate the return code the ApplicationMgr whishes to expose
139 return Gaudi::getAppReturnCode( app.as<IProperty>() );
140 } );
141 }
142}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
Gaudi application entry point.
Definition Application.h:27
std::map< std::string, std::string > Options
Definition Application.h:29
The IMessage is the interface implemented by the message service.
Definition IMessageSvc.h:34
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition IProperty.h:32
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
int getAppReturnCode(const SmartIF< IProperty > &appmgr)
Get the application (current) return code.
@ INFO
Definition IMessageSvc.h:22
app
Definition Read.py:36