Package node_manager_fkie :: Module update_handler
[frames] | no frames]

Source Code for Module node_manager_fkie.update_handler

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  import threading 
 34  from python_qt_binding import QtCore 
 35   
 36  from master_discovery_fkie.master_info import MasterInfo 
 37  from update_thread import UpdateThread 
 38   
39 -class UpdateHandler(QtCore.QObject):
40 ''' 41 A class to retrieve the state about ROS master from remote discovery node and 42 publish it be sending a QT signal. To retrieve the state a new thread will be 43 created. 44 ''' 45 master_info_signal = QtCore.Signal(MasterInfo) 46 ''' 47 @ivar: master_info_signal is a signal, which is emitted, if a new 48 L{aster_discovery_fkie.MasterInfo} is retrieved. 49 ''' 50 master_errors_signal = QtCore.Signal(str, list) 51 ''' 52 @ivar: master_errors_signal is a signal (masteruri, error list) with errors which 53 are occured on remote master_discovery. 54 ''' 55 56 error_signal = QtCore.Signal(str, str) 57 ''' 58 @ivar: error_signal is a signal (masteruri, error message), which is emitted, 59 if an error while retrieving a master info was occurred. 60 ''' 61
62 - def __init__(self):
63 QtCore.QObject.__init__(self) 64 self.__updateThreads = {} 65 self.__requestedUpdates = {} 66 self._lock = threading.RLock()
67
68 - def stop(self):
69 print " Shutdown update threads..." 70 self.__requestedUpdates.clear() 71 for _, thread in self.__updateThreads.iteritems(): 72 thread.join(3) 73 print " Update threads are off!"
74
75 - def requestMasterInfo(self, masteruri, monitoruri, delayed_exec=0.0):
76 ''' 77 This method starts a thread to get the informations about the ROS master by 78 the given RCP uri of the master_discovery node. If all informations are 79 retrieved, a C{master_info_signal} of this class will be emitted. If for given 80 masteruri a thread is already running, it will be inserted to the requested 81 updates. For the same masteruri only one requested update can be stored. 82 On update error the requested update will be ignored. 83 This method is thread safe. 84 85 @param masteruri: the URI of the remote ROS master 86 @type masteruri: C{str} 87 @param monitoruri: the URI of the monitor RPC interface of the master_discovery node 88 @type monitoruri: C{str} 89 @param delayed_exec: Delay the execution of the request for given seconds. 90 @type delayed_exec: C{float} 91 ''' 92 with self._lock: 93 try: 94 if (self.__updateThreads.has_key(masteruri)): 95 self.__requestedUpdates[masteruri] = (monitoruri, delayed_exec) 96 else: 97 self.__create_update_thread(monitoruri, masteruri, delayed_exec) 98 # from urlparse import urlparse 99 # om = urlparse(masteruri) 100 except: 101 pass
102
103 - def _on_master_info(self, minfo):
104 self.master_info_signal.emit(minfo) 105 self.__handle_requests(minfo.masteruri)
106
107 - def _on_master_errors(self, masteruri, error_list):
108 self.master_errors_signal.emit(masteruri, error_list)
109
110 - def _on_error(self, masteruri, error):
111 self.error_signal.emit(masteruri, error) 112 self.__handle_requests(masteruri)
113
114 - def __handle_requests(self, masteruri):
115 with self._lock: 116 try: 117 thread = self.__updateThreads.pop(masteruri) 118 del thread 119 monitoruri, delayed_exec = self.__requestedUpdates.pop(masteruri) 120 self.__create_update_thread(monitoruri, masteruri, delayed_exec) 121 except KeyError: 122 # import traceback 123 # print traceback.format_exc(1) 124 pass 125 except: 126 import traceback 127 print traceback.format_exc(1)
128
129 - def __create_update_thread(self, monitoruri, masteruri, delayed_exec):
130 upthread = UpdateThread(monitoruri, masteruri, delayed_exec) 131 self.__updateThreads[masteruri] = upthread 132 upthread.update_signal.connect(self._on_master_info) 133 upthread.master_errors_signal.connect(self._on_master_errors) 134 upthread.error_signal.connect(self._on_error) 135 upthread.start()
136