Jpp  18.2.1-ARCA-DF-PATCH
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JDAQClient.hh
Go to the documentation of this file.
1 #ifndef __JRUNCONTROL__JDAQCLIENT__
2 #define __JRUNCONTROL__JDAQCLIENT__
3 
4 #include <string>
5 #include <iostream>
6 #include <sstream>
7 #include <iomanip>
8 #include <exception>
9 #include <typeinfo>
10 #include <ctype.h>
11 
12 #include "JSystem/JNetwork.hh"
13 #include "JNet/JControlHost.hh"
15 #include "JNet/JSelectReader.hh"
16 #include "JLang/Jpp.hh"
17 #include "JLang/JSharedPointer.hh"
19 #include "JLang/JTimeval.hh"
20 #include "JLang/JRedirectStream.hh"
21 #include "JLang/JNullStream.hh"
22 #include "Jeep/JParser.hh"
23 #include "Jeep/JProperties.hh"
24 #include "Jeep/JArgs.hh"
25 #include "Jeep/JTimekeeper.hh"
27 #include "JLogger/JStreamLogger.hh"
30 #include "JDAQ/JDAQTags.hh"
32 #include "JRuncontrol/JEvent_t.hh"
34 #include "JRuncontrol/JDAQCHSM.hh"
35 
36 
37 /**
38  * \author mdejong
39  */
40 
41 namespace KM3NETDAQ {
42 
43  using namespace JLOGGER;
44  using JNET::JTag;
45  using JNET::JControlHost;
47  using JNET::JSubscription;
49  using JNET::JSelectReader;
52  using JLANG::JTimeval;
54  using JEEP::JArgs;
55  using JEEP::JTimekeeper;
56 
57 
58  /**
59  * Auxiliary data structure for DAQ client data.
60  */
61  struct JDAQClient_t {
62 
63  static const int TIMEOUT_S = 1; //!< time out of update [s]
64 
65 
66  /**
67  * Constructor.
68  *
69  * \param chsm state machine
70  */
72  {
73  using namespace std;
74  using namespace JPP;
75 
76  hostname = getHostname();
77  fullname = KM3NETDAQ::getFullName (hostname, chsm->getName());
78  unique_tag = KM3NETDAQ::getUniqueTag(hostname, chsm->getName());
79 
80  for (JTag buffer[] = { RC_CMD, unique_tag, DISPTAG_UNDEFINED }, *tag = buffer; *tag != DISPTAG_UNDEFINED; ++tag) {
81 
82  eventTable.insert(*tag, chsm->ev_init);
83  eventTable.insert(*tag, chsm->ev_configure);
84  eventTable.insert(*tag, chsm->ev_start);
85  eventTable.insert(*tag, chsm->ev_pause);
86  eventTable.insert(*tag, chsm->ev_continue);
87  eventTable.insert(*tag, chsm->ev_stop);
88  eventTable.insert(*tag, chsm->ev_reset);
89  eventTable.insert(*tag, chsm->ev_quit);
90  eventTable.insert(*tag, chsm->ev_off);
91 
92  eventTable.insert(*tag, chsm->ev_check);
93  eventTable.insert(*tag, chsm->ev_input);
94 
95  eventTable.insert(*tag, chsm->ev_recover);
96  }
97 
98  JControlHost::Throw(true);
99 
100  setClockInterval(TIMEOUT_S * 1000000LL);
101  }
102 
103 
104  /**
105  * Get hostname.
106  *
107  * \return host name
108  */
109  const std::string& getHostname() const
110  {
111  return hostname;
112  }
113 
114 
115  /**
116  * Get full name of this run control client.
117  *
118  * \return full name
119  */
120  const std::string& getFullName() const
121  {
122  return fullname;
123  }
124 
125 
126  /**
127  * Get unique tag of this run control client.
128  *
129  * \return unique tag
130  */
131  const JTag& getUniqueTag() const
132  {
133  return unique_tag;
134  }
135 
136 
137  /**
138  * Get total delay time.
139  *
140  * \return delay time [us]
141  */
142  long long int getClockDelay() const
143  {
144  return clock.getDelay();
145  }
146 
147 
148 
149  /**
150  * Get interval time.
151  *
152  * \return interval time [us]
153  */
154  long long int getClockInterval() const
155  {
156  return clock.getInterval();
157  }
158 
159 
160  /**
161  * Set interval time.
162  *
163  * \param interval_us interval time [us]
164  */
165  void setClockInterval(const long long int interval_us)
166  {
167  clock.setInterval(interval_us);
168  }
169 
170 
171  /**
172  * Reset clock.
173  */
174  void resetClock()
175  {
176  clock.reset();
177  }
178 
179 
180  /**
181  * Get last event information.
182  *
183  * \return event information
184  */
185  const std::string& getEventInfo() const
186  {
187  return event_info;
188  }
189 
190 
191  /**
192  * Set last event information.
193  *
194  * \param info event information
195  */
196  void setEventInfo(const std::string& info)
197  {
198  this->event_info = info;
199  }
200 
201 
202  protected:
203  JEventTable eventTable; //!< event table
207  JTimekeeper clock; //!< central clock
208  std::string event_info; //!< event information
209  };
210 
211 
212  /**
213  * Control unit client base class.
214  *
215  * This base class implements the protocol for the communication with the control unit.\n
216  * This protocol is based on ControlHost tags and CHSM event names.\n
217  * Normally, the primary input is provided to the constructor of this base class,
218  * e.g.\ via command line options of the application based on a derived class hereof.\n
219  * By calling the default method enter(),
220  * - the internal parameters will be configured; and
221  * - the client's state machine entered.
222  *
223  * The method run() can then be used to process command messages which will acoordingly update the state machine.\n
224  * For each state transition, a corresponding action method is called
225  * which could be re-implemented in the derived class (see JDAQCHSM).\n
226  * Optionally, a designated action method is repeatedly called in state <tt>Running</tt>.
227  *
228  * A state transition is triggered by a valid command message.\n
229  * The command message consists of a tag and some contents.\n
230  * The tag can be used to address all processes, a group of processes or an individual process.\n
231  * The contents of a command message must start with the name on the event and
232  * can contain additional data (separated by KM3NETDAQ::TOKEN_DELIMETER).\n
233  * A successful transition is certified by a reply message which is sent upon entering the targeted state.\n
234  * The reply message has tag "RC_REPLY" and the contents include the names of the original event as well as that of the final state.\n
235  * Optionally, information can be added to an event (separated by KM3NETDAQ::EVENTNAME_DELIMETER).\n
236  * This information is included in the following reply messages,
237  * until there is a command message with (other) information.
238  *
239  * Following a request for a state transition via a command message,
240  * four scenarios should be anticipated, namely:
241  *
242  * -# the process successfully completed the transition,
243  * a corresponding reply message is then send back;
244  * -# the process couldn't make the transition and goes to error state,
245  * a corresponding reply message is then send back,
246  * -# the process crashed,
247  * the process disappears from the process list and
248  * the server broadcasts a corresponding died message;
249  * -# the process takes longer than foreseen, leading to a timeout.
250  *
251  * The followup action after a timeout should be customised.\n
252  * In case of an invalid command message (e.g.\ request for a state transition that does not exist), no reply message will be sent.\n
253  * Instead, a message with tag "RC_FAIL" is sent.
254  *
255  * The default list of tags includes "RC_CMD" and a client specific tag.\n
256  * The latter is composed of the hexadecimal formatted IP sub-address of the client's host CPU (see JSYSTEM::getSubaddress(const int)) and \n
257  * the client's name extension (part following KM3NETDAQ::CLIENTNAME_DELIMETER), if any.\n
258  * The list of tags and the various delimiters are maintained in include file JDAQTags.hh.
259  *
260  * For client specific events requiring a different tag,
261  * the corresponding entry in the event table should be replaced.\n
262  * This should be done in the constructor of the derived class using method replaceEvent().
263  *
264  * The virtual method filter() can be re-implemented so that a specific action
265  * is made before the corresponding message is processed.\n
266  * The message is ignored if this method returns true, else it is normally processed.
267  *
268  * The method setSelect() can be used to set the file descriptor mask of the general select call.\n
269  * In conjunction, the method actionSelect() can be used
270  * to take client specific actions following the select call.
271  *
272  * If the clock interval is non-zero, the method actionRunning() is repeatedly called
273  * according the specified interval time when the client is in state <tt>Running</tt>.\n
274  * The clock interval can be set using method setClockInterval().
275  *
276  * Some input can be redefined during operation.\n
277  * For example the debug level can be set via the following command message.
278  * <pre>
279  * JPutMessage -H <host name> -t <tag> -m "debug=<level>;"
280  * </pre>
281  * where
282  * - <tt>host name</tt> is the name of the host of the command message server;
283  * - <tt>tag</tt> the tag; and
284  * - <tt>level</tt> the new debug level.
285  *
286  * In this, the tag "RC_CMD" applies to all applications and the client specific tag to an individual application.
287  *
288  * Additional custom tags can be added to the general list using method addSubscription().\n
289  * The method actionTagged() is then called when a command message is received with the specified tag.
290  *
291  * For tests and possible other setups, the base class can be configured to run stand-alone or forever.\n
292  * In stand-alone mode, the client can be steered from an regular input stream.\n
293  * When the client runs forever, it waits for a connection before going to the normal mode of operation.\n
294  * The primary input should then be sent via this connection.\n
295  * The method addParameter() can be used to add parameters of
296  * the derived class to the list that is parsed in method enter().
297  */
298  class JDAQClient :
299  public JDAQStateMachine,
300  public JDAQClient_t
301  {
302  using CHSM::machine::enter;
303  using CHSM::machine::exit;
304 
305  public:
306  /**
307  * Constructor.
308  *
309  * This constructor should be used in normal mode.\n
310  * The following methods methods should subsequently be called.
311  * - enter();
312  * - run().
313  *
314  * \param name name of client
315  * \param server name of command message server
316  * \param logger pointer to logger
317  * \param level debug level
318  */
320  const std::string& server,
321  JLogger* logger,
322  const int level) :
323  JDAQStateMachine(name),
325  {
326  this->logger = JMessageLogger(logger, name, level);
327 
328  try {
329  this->server.reset(new JControlHost(server));
330  }
331  catch(const std::exception& error) {
332  JErrorStream(this->logger) << error.what();
333  }
334 
335  std::string buffer;
336 
337  JControlHost::WhereIs(server, getFullName(), buffer);
338 
339  if (buffer != "") {
340  JErrorStream(this->logger) << "Process with nick name \"" << getFullName() << "\" already running on host(s) " << buffer;
341  }
342  }
343 
344 
345  /**
346  * Constructor.
347  *
348  * This constructor should be used when running stand-alone.\n
349  * The following methods methods should subsequently be called.
350  * - CHSM::machine::enter();
351  * - run(std::istream& in);
352  *
353  * \param name name of client
354  * \param logger pointer to logger
355  * \param level debug level
356  */
358  JLogger* logger,
359  const int level) :
360  JDAQStateMachine(name),
362  {
363  this->logger = JMessageLogger(logger, name, level);
364  }
365 
366 
367  /**
368  * Constructor.
369  *
370  * This constructor should be used when running forever.\n
371  * The following method should subsequently be called.
372  * - run(const int port);
373  *
374  * \param name name of client
375  */
377  JDAQStateMachine(name),
379  {}
380 
381 
382  /**
383  * Enter the state machine.
384  *
385  * This overloaded method enter reproduces the constructor.
386  * All necessary input is parsed from the list of arguments.
387  * In case of an error, the state machine is not entered.
388  *
389  * \param args array of command line arguments
390  * \return true if okay; else false
391  */
392  virtual bool enter(const JArgs& args)
393  {
394  using namespace std;
395 
396  string server;
397  string logger;
398  int level;
399  bool use_cout;
400 
401  try {
402 
403  parser['H'] = make_field(server) = "localhost";
404  parser['M'] = make_field(logger) = "localhost";
405  parser['d'] = make_field(level) = 0;
406  parser['c'] = make_field(use_cout);
407 
408  if (parser.read(args) != 0) {
409  return false;
410  }
411  }
412  catch(const std::exception &error) {
413  cerr << error.what() << endl;
414  return false;
415  }
416 
417  try {
418 
419  JLogger* out = NULL;
420 
421  if (use_cout)
422  out = new JStreamLogger(cout);
423  else
424  out = new JControlHostLogger(logger);
425 
426  this->logger = JMessageLogger(out, getName(), level);
427 
428  this->server.reset(new JControlHost(server));
429 
430  return enter();
431  }
432  catch(const std::exception& error) {
433  cerr << error.what() << endl;
434  return false;
435  }
436  }
437 
438 
439  /**
440  * Enter the state machine.
441  *
442  * This method activates the subscription to JNET::JControlHost messages.
443  * In case of an error, the state machine is not entered.
444  *
445  * \return true if okay; else false
446  */
447  virtual bool enter() override
448  {
449  using namespace std;
450  using namespace JPP;
451 
452  if (server.is_valid() && logger.is_valid()) {
453 
454  const JSubscriptionList buffer = getSubscription(eventTable) + subscription;
455 
456  try {
457 
458  server->Subscribe(buffer);
459  server->SendMeAlways();
460  server->MyId(getFullName());
461 
462  JStatusStream(logger) << "Process with nick name \"" << getFullName() << "\" version \"" << getGITVersion() << "\" subscription: " << buffer.toString();
463 
464  return CHSM::machine::enter();
465  }
466  catch(const std::exception& error) {
467  JErrorStream(logger) << error.what();
468  }
469 
470  } else {
471  cerr << "Message server or logger not properly initialised." << endl;
472  }
473 
474  return false;
475  }
476 
477 
478  /**
479  * Exit the state machine.
480  *
481  * This method releases the various resources.
482  *
483  * \return true if okay; else false
484  */
485  virtual bool exit() override
486  {
487  try {
488  if (server.is_valid()) { server.reset(NULL); }
489  }
490  catch(const std::exception& error) {
491  }
492 
493  try {
494  if (logger.is_valid()) { logger.reset(NULL); }
495  }
496  catch(const std::exception& error) {
497  }
498 
499  return CHSM::machine::exit();
500  }
501 
502 
503  /**
504  * Check if this client is in runnig state.
505  *
506  * \return true if running; else false
507  */
508  bool isRunning() const
509  {
510  return Main.RunControl.Operational.Running.active();
511  }
512 
513 
514  /**
515  * Replace tag of given event in event table.
516  *
517  * \param oldTag old tag
518  * \param newTag new tag
519  * \param event event
520  */
521  void replaceEvent(const JTag& oldTag,
522  const JTag& newTag,
523  JDAQEvent_t& event)
524  {
525  eventTable.replace(oldTag, newTag, event);
526  }
527 
528 
529  /**
530  * Find event in event table.
531  *
532  * \param tag tag
533  * \param event_name event name
534  * \return pointer to event or NULL
535  */
536  JDAQEvent_t* findEvent(const JTag& tag, const std::string& event_name)
537  {
538  JEventTable::const_iterator i = eventTable.find(tag, event_name);
539 
540  if (i != eventTable.end())
541  return i->second;
542  else
543  return NULL;
544  }
545 
546 
547  /**
548  * Add custom subscription.
549  *
550  * \param subscription subscription
551  */
552  void addSubscription(const JSubscription& subscription)
553  {
554  this->subscription.add(subscription);
555  }
556 
557 
558  /**
559  * Add parameter to parser used in method enter().
560  *
561  * \param option option
562  * \param parameter parameter
563  */
564  template<class T>
565  void addParameter(const char option, T& parameter)
566  {
567  parser[option] = make_field(parameter);
568  }
569 
570 
571  /**
572  * Add parameter to parser used in method enter().
573  *
574  * \param option option
575  * \param parameter parameter
576  * \param value default value
577  */
578  template<class T>
579  void addParameter(const char option, T& parameter, const T& value)
580  {
581  parser[option] = make_field(parameter) = value;
582  }
583 
584 
585  /**
586  * Set the file descriptor mask for the select call.
587  */
588  void setSelect()
589  {
590  select.reset();
591 
592  setSelect(select.getReaderMask());
593 
594  select.setReaderMask(*server);
595  }
596 
597 
598  /**
599  * Set the file descriptor mask for the select call.
600  * This implementation does nothing but may be redefined by the derived class.
601  *
602  * \param mask file descriptor mask
603  */
604  virtual void setSelect(JFileDescriptorMask& mask) const
605  {}
606 
607 
608  /**
609  * Action method following last select call.
610  * This implementation does nothing but may be redefined by the derived class.
611  *
612  * \param mask file descriptor mask
613  */
614  virtual void actionSelect(const JFileDescriptorMask& mask)
615  {}
616 
617 
618  /**
619  * This method is repeatedly called when this client machine is in state Running
620  * and the clock interval time is non-zero.
621  * This implementation does nothing but may be redefined by the derived class.
622  * Care has to be taken so that the time needed to execute this method should be
623  * less than the specified clock interval time (see method setClockInterval()).
624  */
625  virtual void actionRunning()
626  {}
627 
628 
629  /**
630  * This method is called at <tt>ev_input</tt>.
631  *
632  * \param length length of data
633  * \param buffer pointer to data
634  */
635  virtual void actionInput(int length, const char* buffer) override
636  {
637  using namespace std;
638 
639  JProperties properties(JEquationParameters("=", ";", "", ""), 1);
640 
641  int level = this->logger.getLevel();
642 
643  properties["debug"] = level;
644 
645  properties.read(string(buffer, length));
646 
647  this->logger.setLevel(level);
648  }
649 
650 
651  /**
652  * Filter message.
653  * The filter method can be overwritten so that a specific action is made
654  * before the corresponding message is processed by the state machine.
655  * The message is ignored if true is returned, else it is normally processed.
656  *
657  * \param tag tag
658  * \param length number of characters
659  * \param buffer message
660  * \return skip message or not
661  */
662  virtual bool filter(const JTag& tag, int length, const char* buffer)
663  {
664  return false;
665  }
666 
667 
668  /**
669  * This method is called when a custom tag is encountered.
670  *
671  * \param tag tag
672  * \param length length of data
673  * \param buffer pointer to data
674  */
675  virtual void actionTagged(const JTag& tag, int length, const char* buffer)
676  {
677  }
678 
679 
680  /**
681  * Run as run control client following command messages via JNET::JControlHost.
682  * This method can be called once the state machine is entered.
683  * It returns when the state machine is exited.
684  * If the clock interval is non-zero, the method actionRunning() is
685  * repeatedly called when this client machine is in state Running.
686  * The file descriptor mask can be set to interrupt the timeout of
687  * the select call and clock method wait() in this calling sequence
688  * (see methods setSelect() and actionSelect()).
689  */
690  void run()
691  {
692  using namespace std;
693  using namespace JPP;
694 
695  while (active()) {
696 
697  try {
698 
699  setSelect();
700 
701  if (select(JTimeval(TIMEOUT_S,0)) > 0) {
702 
703  if (select.hasReaderMask(*server)) {
704  update();
705  }
706 
707  actionSelect(select.getReaderMask());
708 
709  } else {
710 
711  continue;
712  }
713 
714 
715  if (isRunning() && clock.getInterval() != 0LL) {
716 
717  long long int numberOfCalls = 0;
718 
719  clock.reset();
720 
721  do {
722 
723  ++numberOfCalls;
724 
725  setSelect();
726 
727  if (clock.wait(select.getReaderMask())) {
728 
729  if (select.hasReaderMask(*server)) {
730  update();
731  }
732 
733  actionSelect(select.getReaderMask());
734 
735  } else {
736 
737  try {
738  actionRunning();
739  }
740  catch(const std::exception& error) {
741  logger.error(error.what());
742  }
743  }
744 
745  } while (isRunning());
746 
747  if (numberOfCalls != 0) {
748  JNoticeStream(logger) << "Delay per call " << clock.getDelay() / numberOfCalls / 1000 << " ms";
749  }
750  }
751  }
752  catch(const JPP::JSocketException& error) {
753  JErrorStream(logger) << "method run(): \"" << error.what() << "\" -> trigger ev_error.";
754  ev_error();
755  }
756  catch(const std::exception& error) {
757  JErrorStream(logger) << "method run(): \"" << error.what() << "\"";
758  }
759  }
760  }
761 
762 
763  /**
764  * Run for ever.
765  * This method can be used when the run control client is started before the run control
766  * (e.g.\ at boot time of the host processor).
767  * This method should be called before the state machine is entered.
768  * It launches a server which accepts a JNET::JControlHost connection from
769  * a designated application e.g.\ the JDAQClientStarter.cc program.
770  * The state machine is entered using the available data in the JNET::JControlHost message.
771  * After the state machine is exited, it accepts a new a JNET::JControlHost connection.
772  *
773  * \param port port number
774  */
775  void run(const int port)
776  {
777  JControlHostServer local_server(port);
778 
779  for ( ; ; ) {
780 
781  JControlHost* ps = local_server.AcceptClient();
782 
783  ps->Connected();
784 
785  JNET::JPrefix prefix;
786 
787  ps->WaitHead(prefix);
788 
789  const int length = prefix.getSize();
790 
791  char* buffer = new char[length];
792 
793  ps->GetFullData(buffer, length);
794  ps->PutFullData(prefix.toString(), buffer, length);
795 
796  delete ps;
797 
798  enter(JArgs(std::string(buffer, length)));
799 
800  delete [] buffer;
801 
802  run();
803 
804  exit();
805  }
806  }
807 
808 
809  /**
810  * Run client with commands from input stream (e.g.\ for debugging).
811  *
812  * Example input format:
813  * <pre>
814  * <tag> <event name>[\#data];
815  * <tag> <event name>[\#data];
816  * </pre>
817  *
818  * \param in input stream
819  */
820  void run(std::istream& in)
821  {
822  using namespace std;
823 
824  string tag;
825  string buffer;
826 
827  while (in >> tag && in >> skipws && getline(in, buffer, ';')) {
828  update(tag, buffer.length(), buffer.data());
829  }
830  }
831 
832  protected:
833 
835  JMessageLogger logger; //!< message logger
836 
837  private:
838  /**
839  * Update state machine.
840  * This method waits for a message from JNET::JControlHost server.
841  */
842  void update()
843  {
844  JNET::JPrefix prefix;
845 
846  server->WaitHead(prefix);
847 
848  const int length = prefix.getSize();
849 
850  char* buffer = new char[length];
851 
852  server->GetFullData(buffer, length);
853 
854  update(prefix.getTag(), length, buffer);
855 
856  delete [] buffer;
857  }
858 
859 
860  /**
861  * Update state machine.
862  *
863  * \param tag tag
864  * \param length number of characters
865  * \param buffer message
866  */
867  void update(const JTag& tag, int length, const char* buffer)
868  {
869  using namespace std;
870  using namespace JPP;
871 
872  if (filter(tag, length, buffer)) {
873  return;
874  }
875 
876  if (getSubscription(eventTable)->count(JSubscriptionAny(tag)) == 0 &&
877  getSubscription(eventTable)->count(JSubscriptionAll(tag)) == 0) {
878 
879  actionTagged(tag, length, buffer);
880 
881  return;
882  }
883 
884 
885  string::size_type pos = 0;
886 
887  while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) == string::npos) {
888  ++pos;
889  }
890 
891  const JEvent_t event = JEvent_t::toValue(string(buffer, pos));
892 
893  if (event.hasInfo()) {
894  setEventInfo(event.getInfo());
895  }
896 
897  while (pos != (string::size_type) length && TOKEN_DELIMETER.find(*(buffer + pos)) != string::npos) {
898  ++pos;
899  }
900 
901 
902  JEventTable::const_iterator i = eventTable.find(tag, event.getName());
903 
904  if (i != eventTable.end()) {
905 
906  const CHSM::state* const s0 = getState();
907 
908  if (!i->second->active()) {
909 
910  JWarningStream(logger) << "Event " << i->second->name() << " not active (" << (s0 != NULL ? s0->name() : "") << ")";
911 
912  if (server.is_valid() && s0 != NULL) {
913  server->PutFullString(RC_FAIL, getMessage(*s0, *i->second));
914  }
915  }
916 
917  // redirect all I/O
918 
919  {
920  JDebugStream debug(logger);
921  JErrorStream error(logger);
922 
923  JRedirectStream rs_cin (cin, JLANG::null);
924  JRedirectStream rs_cout(cout, debug);
925  JRedirectStream rs_cerr(cerr, error);
926 
927  if (rs_cin &&
928  rs_cout &&
929  rs_cerr) {
930 
931  (*(i->second))(length - pos, buffer + pos);
932  }
933  }
934 
935  const CHSM::state* const s1 = getState();
936 
937  JStatusStream(logger) << "Transition "
938  << (s0 != NULL ? s0->name() : "")
939  << "->(" << i->second->name() << ")->"
940  << (s1 != NULL ? s1->name() : "");
941  } else {
942 
943  JErrorStream(logger) << "Unknown key <" << tag << "," << event.getName() << ">";
944  }
945  }
946 
947 
948  /**
949  * Configure client.
950  * This method is used to setup the event table.
951  */
952  void configure()
953  {
954  }
955 
956 
957  /**
958  * Get event message.
959  *
960  * \param state state
961  * \param event event
962  * \return message
963  */
964  std::string getMessage(const CHSM::state& state, const CHSM::event& event) const
965  {
966  std::ostringstream os;
967 
968  os << getFullName()
969  << getTokenDelimeter()
970  << (getEventInfo() != "" ?
971  JEvent_t(event.name(), getEventInfo()) :
972  JEvent_t(event.name()))
973  << getTokenDelimeter()
974  << getStateName(state.name());
975 
976  return os.str();
977  }
978 
979 
980  /**
981  * Action when entering state.
982  * This method provides for the hand shaking with the run control program.
983  *
984  * \param state entered state
985  * \param event event that triggered transition
986  */
987  virtual void enterState(const CHSM::state& state, const CHSM::event& event) override
988  {
989  if (server.is_valid()) {
990  server->PutFullString(RC_REPLY, getMessage(state, event));
991  }
992  }
993 
994 
995  /**
996  * This method is called at <tt>ev_check</tt> and reports a system check by mimicing an enter state action.
997  *
998  * \param length number of characters
999  * \param buffer message
1000  */
1001  virtual void actionCheck(int length, const char* buffer) override
1002  {
1003  if (Main.RunControl.Error.active()) {
1004 
1005  enterState(Main.RunControl.Error, ev_check);
1006 
1007  } else {
1008 
1009  for (CHSM::parent::iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
1010 
1011  if (state->active()) {
1012 
1013  // mimic enter state
1014 
1015  enterState(*state, ev_check);
1016  }
1017  }
1018  }
1019  }
1020 
1021 
1022  /**
1023  * The method to execute the action.
1024  *
1025  * \param __action pointer to action method
1026  * \param __event event that triggered the action
1027  */
1028  void execute(action __action, const CHSM::event& __event) override
1029  {
1030  try {
1031 
1032  const JDAQStateMachine::ev_daq_event& event = dynamic_cast<const JDAQStateMachine::ev_daq_event&>(__event);
1033 
1034  (this->*__action)(event->length, event->buffer);
1035  }
1036  catch(const std::exception& error) {
1037  JErrorStream(logger) << "Error at event " << __event.name() << " \"" << error.what() << "\"; trigger ev_error.";
1038  ev_error();
1039  }
1040  }
1041 
1042 
1043  /**
1044  * Get current state.
1045  *
1046  * \return state
1047  */
1048  const CHSM::state* getState() const
1049  {
1050  for (CHSM::parent::const_iterator state = Main.RunControl.Operational.begin(); state != Main.RunControl.Operational.end(); ++state) {
1051  if (state->active()) {
1052  return &(*state);
1053  }
1054  }
1055 
1056  if (Main.RunControl.Error.active()) {
1057  return &Main.RunControl.Error;
1058  }
1059 
1060  return NULL;
1061  }
1062 
1063 
1064  JSelectReader select; //!< select call
1065  JParser<> parser; //!< parser method enter()
1066  JSubscriptionList subscription; //!< custom subscription
1067  };
1068 }
1069 
1070 #endif
set Main(RunControl, Responder) is
Definition: JDAQCHSM.chsm:188
JParser parser
parser method enter()
Definition: JDAQClient.hh:1065
ControlHost prefix.
Definition: JPrefix.hh:31
Utility class to parse command line options.
Definition: JParser.hh:1514
long long int getClockDelay() const
Get total delay time.
Definition: JDAQClient.hh:142
bool read(const JEquation &equation)
Read equation.
Definition: JProperties.hh:678
bool select(const Trk &trk, const Evt &evt)
Event selection.
JDAQStateMachine::ev_start_event ev_start
JDAQEvent_t * findEvent(const JTag &tag, const std::string &event_name)
Find event in event table.
Definition: JDAQClient.hh:536
JDAQStateMachine::ev_configure_event ev_configure
JTimekeeper clock
central clock
Definition: JDAQClient.hh:207
ControlHost class.
void resetClock()
Reset clock.
Definition: JDAQClient.hh:174
JDAQStateMachine::ev_pause_event ev_pause
Message logging based on std::ostream.
JDAQStateMachine::ev_continue_event ev_continue
virtual void setSelect(JFileDescriptorMask &mask) const
Set the file descriptor mask for the select call.
Definition: JDAQClient.hh:604
int Connected()
Send version.
JTag getUniqueTag(const std::string &hostname, const std::string &name)
Get unique tag of run control client.
JDAQStateMachine::ev_reset_event ev_reset
JSelectReader select
select call
Definition: JDAQClient.hh:1064
Message reporting compatible with STL output stream operations.
long long int getClockInterval() const
Get interval time.
Definition: JDAQClient.hh:154
void setEventInfo(const std::string &info)
Set last event information.
Definition: JDAQClient.hh:196
Auxiliary data structure for DAQ client data.
Definition: JDAQClient.hh:61
std::string toString() const
Convert subscription list to string.
Interface for logging messages.
Definition: JLogger.hh:22
Message logging based on ControlHost.
then echo Enter input within $TIMEOUT_S seconds echo n User name
Definition: JCookie.sh:42
Utility class to parse parameter values.
Definition: JProperties.hh:497
void setClockInterval(const long long int interval_us)
Set interval time.
Definition: JDAQClient.hh:165
JDAQClient(const std::string &name)
Constructor.
Definition: JDAQClient.hh:376
virtual bool exit() override
Exit the state machine.
Definition: JDAQClient.hh:485
virtual void actionCheck(int length, const char *buffer) override
This method is called at ev_check and reports a system check by mimicing an enter state action...
Definition: JDAQClient.hh:1001
exit
Definition: JPizza.sh:36
Simple data structure to support I/O of equations (see class JLANG::JEquation).
Time keeper.
Definition: JTimekeeper.hh:34
then usage $script< detector file >< detectorfile > nIf the range of floors is the first detector file is aligned to the second before the comparison nIn this
Jpp environment information.
const std::string & getEventInfo() const
Get last event information.
Definition: JDAQClient.hh:185
void configure()
Configure client.
Definition: JDAQClient.hh:952
JSharedPointer< JControlHost > server
message server
Definition: JDAQClient.hh:834
void replaceEvent(const JTag &oldTag, const JTag &newTag, JDAQEvent_t &event)
Replace tag of given event in event table.
Definition: JDAQClient.hh:521
static const std::string TOKEN_DELIMETER
Definition: JDAQTags.hh:52
virtual bool enter() override
Enter the state machine.
Definition: JDAQClient.hh:447
virtual void enterState(const CHSM::state &state, const CHSM::event &event) override
Action when entering state.
Definition: JDAQClient.hh:987
void run()
Run as run control client following command messages via JNET::JControlHost.
Definition: JDAQClient.hh:690
std::string event_info
event information
Definition: JDAQClient.hh:208
JDAQStateMachine::ev_init_event ev_init
virtual bool filter(const JTag &tag, int length, const char *buffer)
Filter message.
Definition: JDAQClient.hh:662
bool is_valid() const
Check validity of pointer.
int getSize() const
Get size.
Definition: JPrefix.hh:62
Subscription list.
Utility class to parse parameter values.
JDAQClient_t(JDAQStateMachine *chsm)
Constructor.
Definition: JDAQClient.hh:71
static JEvent_t toValue(const std::string &buffer)
Convert string to event.
Definition: JEvent_t.hh:99
Auxiliary class for time values.
Definition: JTimeval.hh:26
void run(const int port)
Run for ever.
Definition: JDAQClient.hh:775
JDAQStateMachine::ev_stop_event ev_stop
virtual void actionInput(int length, const char *buffer) override
This method is called at ev_input.
Definition: JDAQClient.hh:635
std::string getStateName(const std::string &name)
Get name of state.
const CHSM::state * getState() const
Get current state.
Definition: JDAQClient.hh:1048
Scheduling of actions via fixed latency intervals.
std::string getGITVersion(const std::string &tag)
Get GIT version for given GIT tag.
The template JSharedPointer class can be used to share a pointer to an object.
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
static const JNET::JTag RC_REPLY
Definition: JDAQTags.hh:61
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
void execute(action __action, const CHSM::event &__event) override
The method to execute the action.
Definition: JDAQClient.hh:1028
do set_variable OUTPUT_DIRECTORY $WORKDIR T
virtual void actionRunning()
This method is repeatedly called when this client machine is in state Running and the clock interval ...
Definition: JDAQClient.hh:625
Auxiliary class for method select.
Wrapper class for select call.
Auxiliary class for any subscription.
then awk string
virtual void actionTagged(const JTag &tag, int length, const char *buffer)
This method is called when a custom tag is encountered.
Definition: JDAQClient.hh:675
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
static const JTag DISPTAG_UNDEFINED(0)
Auxiliary class for handling event name and optional static information.
Definition: JEvent_t.hh:23
Level specific message streamers.
Exception for ControlHost.
Definition: JException.hh:484
Data structure to store command line arguments.
Definition: JArgs.hh:24
char getTokenDelimeter()
Get the token delimeter for command messages.
bool isRunning() const
Check if this client is in runnig state.
Definition: JDAQClient.hh:508
Auxiliary class for all subscription.
Definition: JControlHost.hh:97
void update(const JTag &tag, int length, const char *buffer)
Update state machine.
Definition: JDAQClient.hh:867
JSubscriptionList subscription
custom subscription
Definition: JDAQClient.hh:1066
JControlHost * AcceptClient(JTimeval timeout=JTimeval::max())
Accept new client.
const std::string & getHostname() const
Get hostname.
Definition: JDAQClient.hh:109
const JTag & getTag() const
Get tag.
Definition: JTag.hh:86
std::string getHostname()
Get host name.
Definition: JNetwork.hh:77
void update()
Update state machine.
Definition: JDAQClient.hh:842
JDAQStateMachine::ev_check_event ev_check
int WaitHead(JPrefix &prefix)
Wait for header.
void addParameter(const char option, T &parameter, const T &value)
Add parameter to parser used in method enter().
Definition: JDAQClient.hh:579
void addParameter(const char option, T &parameter)
Add parameter to parser used in method enter().
Definition: JDAQClient.hh:565
std::string toString() const
Convert tag to string.
Definition: JTag.hh:171
General purpose message reporting.
JEventTable eventTable
event table
Definition: JDAQClient.hh:203
JDAQStateMachine::ev_quit_event ev_quit
virtual const char * what() const override
Get error message.
Definition: JException.hh:64
int GetFullData(void *buffer, long long int length)
Receive data.
const std::string & getFullName() const
Get full name of this run control client.
Definition: JDAQClient.hh:120
JDAQStateMachine::ev_input_event ev_input
Control unit client base class.
Definition: JDAQClient.hh:298
Utility class to parse command line options.
event< ev_daq > ev_check
Definition: JDAQCHSM.chsm:183
void run(std::istream &in)
Run client with commands from input stream (e.g. for debugging).
Definition: JDAQClient.hh:820
ControlHost subscription.
Definition: JControlHost.hh:50
Exception for socket.
Definition: JException.hh:466
std::string getMessage(const CHSM::state &state, const CHSM::event &event) const
Get event message.
Definition: JDAQClient.hh:964
JSubscriptionList getSubscription(const JEventTable &event_table)
Convert event table to ControlHost subscription.
Definition: JEventTable.hh:129
virtual bool enter(const JArgs &args)
Enter the state machine.
Definition: JDAQClient.hh:392
const JTag & getUniqueTag() const
Get unique tag of this run control client.
Definition: JDAQClient.hh:131
JDAQClient(const std::string &name, const std::string &server, JLogger *logger, const int level)
Constructor.
Definition: JDAQClient.hh:319
const char * getName()
Get ROOT name of given data type.
Definition: JRootToolkit.hh:60
JMessageLogger logger
message logger
Definition: JDAQClient.hh:835
Fixed parameters and ControlHost tags for KM3NeT DAQ.
static const JNET::JTag RC_CMD
Definition: JDAQTags.hh:60
static int WhereIs(const std::string &host_name, const std::string &nick_name, std::string &answer)
Locate ControlHost client(s).
ControlHost tag.
Definition: JTag.hh:38
bool filter(const JDAQEvent &tev, const JEvt &evt, const Evt *const pE)
Event selection.
JDAQStateMachine::ev_off_event ev_off
const std::string & getName() const
Get name of state machine.
Definition: JDAQCHSM.chsm:78
std::string getFullName(const std::string &hostname, const std::string &name)
Get full name of run control client.
static JNullStream null
Null I/O stream.
Definition: JNullStream.hh:51
void setSelect()
Set the file descriptor mask for the select call.
Definition: JDAQClient.hh:588
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
static const JNET::JTag RC_FAIL
Definition: JDAQTags.hh:62
int PutFullData(const JTag &tag, const void *buffer, const long long int length)
Send data.
Hostname and IP address functions.
virtual void actionSelect(const JFileDescriptorMask &mask)
Action method following last select call.
Definition: JDAQClient.hh:614
void addSubscription(const JSubscription &subscription)
Add custom subscription.
Definition: JDAQClient.hh:552
static void Throw(const bool option)
Enable/disable throw option.
Definition: JThrow.hh:37
int debug
debug level
Light-weight wrapper class around server socket.
JDAQStateMachine::ev_recover_event ev_recover
JDAQClient(const std::string &name, JLogger *logger, const int level)
Constructor.
Definition: JDAQClient.hh:357