redis_server.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # License: BSD
00004 #   https://raw.github.com/robotics-in-concert/rocon_multimaster/master/multimaster_server/rocon_hub/LICENSE
00005 #
00006 ##############################################################################
00007 # Imports
00008 ##############################################################################
00009 
00010 import os
00011 import sys
00012 import re
00013 import shutil
00014 import subprocess
00015 
00016 # Ros imports
00017 import roslib
00018 roslib.load_manifest('rocon_hub')
00019 import rospy
00020 import rospkg
00021 try:
00022     import redis
00023 except ImportError:
00024     # actually unused right now while we use redis as a ros package
00025     sys.exit("\n[ERROR] No python-redis found - 'rosdep install rocon_hub'\n")
00026 
00027 # Local imports
00028 import utils
00029 
00030 ##############################################################################
00031 # Redis Server
00032 ##############################################################################
00033 
00034 
00035 class RedisServer:
00036     def __init__(self, parameters):
00037         self._parameters = parameters
00038         self._process = None
00039         self._home_dir = os.path.join(rospkg.get_ros_home(), 'redis', self._parameters['name'].lower().replace(" ", "_"))
00040         self._files = {}
00041         self._files['redis_conf'] = os.path.join(self._home_dir, 'redis.conf')
00042         self._files['redis_conf_local'] = os.path.join(self._home_dir, 'redis.conf.local')
00043         self._files['redis_server_log'] = os.path.join(self._home_dir, 'redis-server.log')
00044         self._server = None
00045 
00046         self._setup()
00047 
00048     def _setup(self):
00049         '''
00050           Clear and configure redis conf, log files in the ros home
00051           directories under a subdirectory styled by the name of this hub.
00052         '''
00053         if os.path.isdir(self._home_dir):
00054             shutil.rmtree(self._home_dir)
00055         os.makedirs(self._home_dir)
00056         rospack = rospkg.RosPack()
00057         redis_conf_template = utils.read_template(os.path.join(rospack.get_path('rocon_hub'), 'redis', 'redis.conf'))
00058         redis_conf_template = instantiate_redis_conf_template(redis_conf_template, self._files['redis_conf_local'])
00059         redis_local_template = utils.read_template(os.path.join(rospack.get_path('rocon_hub'), 'redis', 'redis.conf.local'))
00060         redis_local_template = instantiate_local_conf_template(redis_local_template,
00061                                                                self._parameters['port'],
00062                                                                self._parameters['max_memory'],
00063                                                                self._files['redis_server_log'])
00064         try:
00065             f = open(self._files['redis_conf'], 'w')
00066             f.write(redis_conf_template.encode('utf-8'))
00067         finally:
00068             f.close()
00069         try:
00070             f = open(self._files['redis_conf_local'], 'w')
00071             f.write(redis_local_template.encode('utf-8'))
00072         finally:
00073             f.close()
00074 
00075     def start(self):
00076         '''
00077           Start the server. Also connect, delete all rocon:xxx
00078           variables and reinitialise with specified values.
00079 
00080           Aborts the program if the connection fails.
00081         '''
00082         self._process = subprocess.Popen(["redis-server", self._files['redis_conf']])
00083         pool = redis.ConnectionPool(host='localhost', port=int(self._parameters['port']), db=0)
00084         no_attempts = 5
00085         count = 0
00086         while count < no_attempts:
00087             try:
00088                 self._server = redis.Redis(connection_pool=pool)
00089                 rocon_keys = self._server.keys("rocon:*")
00090                 pattern = re.compile("rocon:*")
00091                 keys_to_delete = []
00092                 for key in rocon_keys:
00093                     if pattern.match(key):
00094                         keys_to_delete.append(key)
00095                 pipe = self._server.pipeline()
00096                 if len(keys_to_delete) != 0:
00097                     pipe.delete(*keys_to_delete)  # * unpacks the list args - http://stackoverflow.com/questions/2921847/python-once-and-for-all-what-does-the-star-operator-mean-in-python
00098                 pipe.set("rocon:hub:index", 0)
00099                 pipe.set("rocon:hub:name", self._parameters['name'])
00100                 pipe.execute()
00101                 rospy.loginfo("Hub : reset hub variables on the redis server.")
00102                 break
00103             except redis.ConnectionError:
00104                 count += 1
00105                 if count == no_attempts:
00106                     self.shutdown()
00107                     sys.exit(utils.logfatal("Hub : could not connect to the redis server - is it running?"))
00108                 else:
00109                     rospy.sleep(0.1)
00110 
00111     def shutdown(self):
00112         '''
00113           Clears rocon: keys on the server.
00114         '''
00115         try:
00116             rocon_keys = self._server.keys("rocon:*")
00117             pattern = re.compile("rocon:*")
00118             keys_to_delete = []
00119             for key in rocon_keys:
00120                 if pattern.match(key):
00121                     keys_to_delete.append(key)
00122             pipe = self._server.pipeline()
00123             if len(keys_to_delete) != 0:
00124                 pipe.delete(*keys_to_delete)  # * unpacks the list args - http://stackoverflow.com/questions/2921847/python-once-and-for-all-what-does-the-star-operator-mean-in-python
00125             pipe.execute()
00126             rospy.logdebug("Hub : clearing hub variables on the redis server.")
00127         except redis.ConnectionError:
00128             pass
00129         self._process.terminate()
00130 
00131 ##############################################################################
00132 # Functions
00133 ##############################################################################
00134 
00135 
00136 def instantiate_redis_conf_template(template, local_conf_filename):
00137     '''
00138       Variable substitution in a template file.
00139 
00140       @param local_conf_filename : where to find the local redis configuration file
00141       @type string
00142     '''
00143     return template % locals()
00144 
00145 
00146 def instantiate_local_conf_template(template, port, max_memory, logfile):
00147     '''
00148       Variable substitution in a template file.
00149 
00150       @param port : port on which the server will run
00151       @type int
00152       @param pid_file : pathname to where the pid file will be stored
00153       @type string
00154       @param max_memory: how much memory to allocate to the redis server in bytes
00155       @type string (e.g. 10mb)
00156     '''
00157     return template % locals()
00158 
00159 if __name__ == "__main__":
00160     pool = redis.ConnectionPool(host='localhost', port='6380', db=0)
00161     try:
00162         print "dude"
00163     except redis.exceptions.ConnectionError:
00164         print "err"
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


rocon_hub
Author(s): Daniel Stonier, Jihoon Lee
autogenerated on Tue Jan 15 2013 17:43:33