Fawkes API  Fawkes Development Version
event_trigger_manager.h
1 /***************************************************************************
2  * event_trigger_manager.h - Manager to realize triggers on events in the robot memory
3  *
4  *
5  * Created: 3:53:45 PM 2016
6  * Copyright 2016 Frederik Zwilling
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #ifndef FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
23 #define FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
24 
25 #include "event_trigger.h"
26 
27 #include <aspect/configurable.h>
28 #include <aspect/logging.h>
29 #include <core/exception.h>
30 #include <core/threading/mutex_locker.h>
31 #include <plugin/loader.h>
32 #include <plugins/mongodb/aspect/mongodb_conncreator.h>
33 #include <plugins/mongodb/utils.h>
34 
35 #include <boost/bind/bind.hpp>
36 #include <bsoncxx/builder/basic/document.hpp>
37 #include <list>
38 
39 namespace fawkes {
40 #ifdef USE_TIMETRACKER
41 class TimeTracker;
42 #endif
43 } // namespace fawkes
44 
45 using namespace boost::placeholders;
46 
48 {
49  /// Access for robot memory to use the check_events function in the loop
50  friend class RobotMemory;
51 
52 public:
54  fawkes::Configuration * config,
55  fawkes::MongoDBConnCreator *mongo_connection_manager);
56  virtual ~EventTriggerManager();
57 
58  /**
59  * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
60  * @param query Query the updated document has to match
61  * @param dbcollection db.collection to use
62  * @param callback Callback function (e.g. &Class::callback)
63  * @param obj Pointer to class the callback is a function of (usaually this)
64  * @return Trigger object pointer, save it to remove the trigger later
65  */
66  template <typename T>
67  EventTrigger *
68  register_trigger(const bsoncxx::document::view &query,
69  std::string dbcollection,
70  void (T::*callback)(const bsoncxx::document::view &),
71  T *obj)
72  {
73  //logger_->log_warn("RM|EventTriggerManager", "Registering trigger on %s", dbcollection.c_str());
74  //lock to be thread safe (e.g. registration during checking)
75  fawkes::MutexLocker lock(mutex_);
76 
77  if (!query.empty()) {
78  throw fawkes::Exception("Non-empty queries are not implemented!");
79  }
80 
81  //check if dbcollection is local or replicated
82  mongocxx::client *con;
83  if (std::find(dbnames_distributed_.begin(),
84  dbnames_distributed_.end(),
85  get_db_name(dbcollection))
86  != dbnames_distributed_.end()) {
87  con = con_replica_;
88  } else {
89  con = con_local_;
90  }
91  auto db_coll_pair = split_db_collection_string(dbcollection);
92  auto collection = con->database(db_coll_pair.first)[db_coll_pair.second];
93  EventTrigger *trigger = new EventTrigger(create_change_stream(collection, query),
94  query,
95  dbcollection,
96  boost::bind(callback, obj, _1));
97  triggers.push_back(trigger);
98  return trigger;
99  }
100 
101  void remove_trigger(EventTrigger *trigger);
102 
103  static std::string get_db_name(const std::string &ns);
104 
105 private:
106  void check_events();
107  mongocxx::change_stream create_change_stream(mongocxx::collection & collection,
108  bsoncxx::document::view query);
109 
110  std::string name = "RobotMemory EventTriggerManager";
111  fawkes::Logger * logger_;
112  fawkes::Configuration *config_;
113  fawkes::Mutex * mutex_;
114 
115  fawkes::MongoDBConnCreator *mongo_connection_manager_;
116  //MongoDB connections (necessary because the mongos instance used by the robot memory has no access to the oplog)
117  mongocxx::client *con_local_;
118  mongocxx::client *con_replica_;
119 
120  std::vector<std::string> dbnames_distributed_;
121  std::vector<std::string> dbnames_local_;
122  bool cfg_debug_;
123 
124  std::list<EventTrigger *> triggers;
125 
126 #ifdef USE_TIMETRACKER
127  fawkes::TimeTracker *tt_;
128  unsigned int tt_loopcount_;
129  unsigned int ttc_trigger_loop_;
130  unsigned int ttc_callback_loop_;
131  unsigned int ttc_callback_;
132  unsigned int ttc_reinit_;
133 #endif
134 };
135 
136 #endif //FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
Manager to realize triggers on events in the robot memory.
EventTrigger * register_trigger(const bsoncxx::document::view &query, std::string dbcollection, void(T::*callback)(const bsoncxx::document::view &), T *obj)
Register a trigger to be notified when the robot memory is updated and the updated document matches t...
Class holding all information about an EventTrigger.
Definition: event_trigger.h:32
Access to the robot memory based on mongodb.
Definition: robot_memory.h:47
void remove_trigger(EventTrigger *trigger)
Remove a previously registered trigger.
mongocxx::cursor query(bsoncxx::document::view query, const std::string &collection_name="", mongocxx::options::find query_options=mongocxx::options::find())
Query information from the robot memory.
Interface for configuration handling.
Definition: config.h:68
Base class for exceptions in Fawkes.
Definition: exception.h:36
Interface for logging.
Definition: logger.h:42
Interface for a MongoDB connection creator.
Mutex locking helper.
Definition: mutex_locker.h:34
Mutex mutual exclusion lock.
Definition: mutex.h:33
Time tracking utility.
Definition: tracker.h:37
Fawkes library namespace.