app_manager.cpp
Go to the documentation of this file.
1 
24 
25 namespace micros_swarm{
26 
28  {
29  id_ = id;
30  thread_ = new boost::thread(&Worker::workFunc, this);
31  run_ = true;
32  apps_.clear();
33  }
34 
36  {
37  run_ = false;
38  for(int i = 0; i < apps_.size(); i++) {
39  apps_[i]->app_ptr_.reset();
40  delete apps_[i];
41  }
42  apps_.clear();
43  thread_->interrupt();
44  thread_->join();
45  delete thread_;
46  }
47 
49  {
50  apps_.push_back(app);
51  }
52 
53  void Worker::removeApp(const std::string& app_name)
54  {
55  std::vector<AppInstance*>::iterator app_it;
56  for(app_it = apps_.begin(); app_it != apps_.end(); app_it++) {
57  if((*app_it)->app_name_ == app_name) {
58  //(*app_it)->app_ptr_->stop();
59  (*app_it)->running_ = false;
60  (*app_it)->app_ptr_.reset();
61  delete (*app_it);
62  app_it = apps_.erase(app_it);
63  return;
64  }
65  }
66  }
67 
69  {
70  return apps_.size();
71  }
72 
73  AppInstance* Worker::getAppInstance(const std::string& app_name)
74  {
75  std::vector<AppInstance*>::iterator app_it;
76  for(app_it = apps_.begin(); app_it != apps_.end(); app_it++) {
77  if((*app_it)->app_name_ == app_name) {
78  return (*app_it);
79  }
80  }
81 
82  AppInstance *app_ins = NULL;
83  return app_ins;
84  }
85 
87  {
88  while(run_) {
89  std::vector<AppInstance*>::iterator app_it;
90  for(app_it = apps_.begin(); app_it != apps_.end(); app_it++) {
91  if(!(*app_it)->running_) {
92  (*app_it)->app_ptr_->init();
93  (*app_it)->app_ptr_->start();
94  (*app_it)->running_ = true;
95  }
96  }
97  ros::Duration(0.2).sleep();
98  }
99  }
100 
101  AppManager::AppManager():app_loader_("micros_swarm", "micros_swarm::Application")
102  {
103  ros::NodeHandle nh;
104  app_load_srv_ = nh.advertiseService("app_loader_load_app", &AppManager::loadService, this);
105  app_unload_srv_ = nh.advertiseService("app_loader_unload_app", &AppManager::unloadService, this);
106  worker_num_ = 4;
107  worker_table_.clear();
108  load_table_.clear();
109  for(int i = 0; i < worker_num_; i++) {
110  Worker *worker = new Worker(i);
111  worker_table_.push_back(worker);
112  load_table_.push_back(0);
113  }
114  apps_record_.clear();
115  plugin_use_count_.clear();
116  }
117 
118  AppManager::AppManager(int worker_num):app_loader_("micros_swarm", "micros_swarm::Application")
119  {
120  ros::NodeHandle nh;
121  app_load_srv_ = nh.advertiseService("app_loader_load_app", &AppManager::loadService, this);
122  app_unload_srv_ = nh.advertiseService("app_loader_unload_app", &AppManager::unloadService, this);
123  worker_num_ = worker_num;
124  worker_table_.clear();
125  load_table_.clear();
126  for(int i = 0; i < worker_num_; i++) {
127  Worker *worker = new Worker(i);
128  worker_table_.push_back(worker);
129  load_table_.push_back(0);
130  }
131  apps_record_.clear();
132  plugin_use_count_.clear();
133  }
134 
136  {
137  ros::NodeHandle nh;
138  std::map<std::string, int>::iterator it;
139  for(it = apps_record_.begin(); it != apps_record_.end(); it++) {
140  std::string topic_name = "runtime_core_destroy_" + it->first;
141  ros::ServiceClient client = nh.serviceClient<app_loader::RTDestroy>(topic_name);
142  app_loader::RTDestroy srv;
143  srv.request.code = 1;
144 
145  if (client.call(srv)) {
146  //ROS_INFO("[RTPManager]: App %s unloaded successfully.", app_it->app_name_.c_str());
147  }
148  else {
149  //ROS_ERROR("[RTPManager]: Failed to unload App %s.", app_it->app_name_.c_str());
150  }
151  ros::Duration(0.1).sleep();
152  }
153 
154  for(it = apps_record_.begin(); it != apps_record_.end(); ) {
155  int worker_id = it->second;
156  AppInstance *instance = worker_table_[worker_id]->getAppInstance(it->first);
157  if(instance != NULL) {
158  instance->app_ptr_->stop();
159  instance->app_ptr_.reset();
160  std::string app_type = instance->app_type_;
161  worker_table_[worker_id]->removeApp(it->first);
162  load_table_[worker_id] -= 1;
163  decreasePluginUseCount(app_type);
164  if(getPluginUseCount(app_type) == 0) {
165  app_loader_.unloadLibraryForClass(app_type);
166  }
167  }
168 
169  apps_record_.erase(it++);
170  }
171  std::cout<<"[AppManager]: all Apps were unloaded successfully."<<std::endl;
172 
173  for(int i = 0; i < worker_table_.size(); i++) {
174  delete worker_table_[i];
175  }
176  worker_table_.clear();
177  std::cout<<"[AppManager]: destroy all the worker successfully."<<std::endl;
178  }
179 
181 
182  bool AppManager::recordExist(const std::string& name)
183  {
184  std::map<std::string, int>::iterator it = apps_record_.find(name);
185 
186  if(it != apps_record_.end()) {
187  return true;
188  }
189 
190  return false;
191  }
192 
193  void AppManager::addRecord(const std::string& name, int worker_id)
194  {
195  apps_record_.insert(std::pair<std::string, int>(name, worker_id));
196  }
197 
198  void AppManager::removeRecord(const std::string& name)
199  {
200  apps_record_.erase(name);
201  }
202 
204  {
205  int min_index = 0;
206  for(int i = 1; i < worker_num_; i++) {
207  if(load_table_[i] < load_table_[min_index]) {
208  min_index = i;
209  }
210  }
211 
212  return min_index;
213  }
214 
215  void AppManager::insertOrUpdatePluginUseCount(const std::string& type)
216  {
217  std::map<std::string, int>::iterator it;
218  it = plugin_use_count_.find(type);
219  if(it != plugin_use_count_.end()) {
220  it->second += 1;
221  }
222  else {
223  plugin_use_count_.insert(std::pair<std::string, int>(type, 1));
224  }
225  }
226 
227  void AppManager::decreasePluginUseCount(const std::string& type)
228  {
229  std::map<std::string, int>::iterator it;
230  it = plugin_use_count_.find(type);
231  if(it != plugin_use_count_.end()) {
232  it->second -= 1;
233  if(it->second == 0) {
234  plugin_use_count_.erase(type);
235  }
236  }
237  }
238 
239  int AppManager::getPluginUseCount(const std::string& type)
240  {
241  std::map<std::string, int>::iterator it;
242  it = plugin_use_count_.find(type);
243  if(it != plugin_use_count_.end()) {
244  return plugin_use_count_[type];
245  }
246 
247  return 0;
248  }
249 
250  bool AppManager::loadService(app_loader::AppLoad::Request &req, app_loader::AppLoad::Response &resp)
251  {
252  std::string app_name = req.name;
253  std::string app_type = req.type;
254 
255  bool app_exist = recordExist(app_name);
256  if(app_exist) {
257  ROS_WARN("[AppManager]: App %s was already existed.", app_name.c_str());
258  ros::Duration(0.1).sleep();
259  resp.success = false;
260  return false;
261  }
262  else {
264  try {
265  app = app_loader_.createInstance(app_type);
266  }
267  catch(pluginlib::PluginlibException& ex) {
268  ROS_ERROR("[AppManager]: App %s failed to load for some reason. Error: %s", app_name.c_str(), ex.what());
269  }
270 
271  AppInstance* app_instance = new AppInstance();
272  app_instance->app_name_ = app_name;
273  app_instance->app_type_ = app_type;
274  app_instance->app_ptr_ = app;
275  app_instance->running_ = false;
276 
277  int worker_index = allocateWorker();
278  worker_table_[worker_index]->addApp(app_instance);
279  load_table_[worker_index] += 1;
280  addRecord(app_name, worker_index);
282  ROS_INFO("[AppManager]: App %s was loaded successfully.", app_name.c_str());
283  ros::Duration(0.1).sleep();
284  resp.success = true;
285  return true;
286  }
287  }
288 
289  bool AppManager::unloadService(app_loader::AppUnload::Request &req, app_loader::AppUnload::Response &resp)
290  {
291  std::string app_name = req.name;
292  std::string app_type = req.type;
293 
294  if(recordExist(app_name)) {
295  int worker_id = apps_record_[app_name];
296  AppInstance *instance = worker_table_[worker_id]->getAppInstance(app_name);
297  if(instance == NULL) {
298  ROS_WARN("[AppManager]: Get App instance %s failed.", app_name.c_str());
299  ros::Duration(0.1).sleep();
300  resp.success = false;
301  return false;
302  }
303  instance->app_ptr_.reset();
304  worker_table_[worker_id]->removeApp(app_name);
305  load_table_[worker_id] -= 1;
306  removeRecord(app_name);
307  decreasePluginUseCount(app_type);
308  if(getPluginUseCount(app_type) == 0) {
309  app_loader_.unloadLibraryForClass(app_type);
310  }
311  ROS_INFO("[AppManager]: App %s was unloaded successfully.", app_name.c_str());
312  ros::Duration(0.1).sleep();
313  resp.success = true;
314  return true;
315  }
316  ROS_WARN("[AppManager]: App %s does not exist.", app_name.c_str());
317  ros::Duration(0.1).sleep();
318  resp.success = false;
319  return false;
320  }
321 };
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
void insertOrUpdatePluginUseCount(const std::string &type)
std::vector< Worker * > worker_table_
Definition: app_manager.h:90
void addRecord(const std::string &name, int worker_id)
pluginlib::ClassLoader< micros_swarm::Application > app_loader_
Definition: app_manager.h:86
bool sleep() const
std::vector< AppInstance * > apps_
Definition: app_manager.h:66
bool call(MReq &req, MRes &res)
bool unloadService(app_loader::AppUnload::Request &req, app_loader::AppUnload::Response &resp)
int getPluginUseCount(const std::string &type)
AppInstance * getAppInstance(const std::string &app_name)
Definition: app_manager.cpp:73
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
#define ROS_WARN(...)
std::map< std::string, int > apps_record_
Definition: app_manager.h:92
void decreasePluginUseCount(const std::string &type)
void addApp(AppInstance *app)
Definition: app_manager.cpp:48
#define ROS_INFO(...)
std::vector< uint16_t > load_table_
Definition: app_manager.h:91
boost::shared_ptr< Application > app_ptr_
Definition: app_manager.h:48
void removeRecord(const std::string &name)
void removeApp(const std::string &app_name)
Definition: app_manager.cpp:53
bool loadService(app_loader::AppLoad::Request &req, app_loader::AppLoad::Response &resp)
ros::ServiceServer app_load_srv_
Definition: app_manager.h:87
ros::ServiceServer app_unload_srv_
Definition: app_manager.h:87
bool recordExist(const std::string &name)
#define ROS_ERROR(...)
boost::thread * thread_
Definition: app_manager.h:65
volatile bool run_
Definition: app_manager.h:64
std::map< std::string, int > plugin_use_count_
Definition: app_manager.h:93


micros_swarm
Author(s):
autogenerated on Mon Jun 10 2019 14:02:06