def __init__(self, ez_props): if ez_props is None: raise Exception("Invalid EzProperties.") zk_con_str = ZookeeperConfiguration(ez_props).getZookeeperConnectionString() self.ezd_client = ServiceDiscoveryClient(zk_con_str) self.__applicationConfiguration = ApplicationConfiguration(ez_props) self.__applicationName = self.__applicationConfiguration.getApplicationName() self.__securityConfiguration = SecurityConfiguration(ez_props) self.__thriftConfiguration = ThriftConfiguration(ez_props) self.__rLock = threading.RLock() self.__serviceMap = {} self.__clientMap = {} self.__log = logging.getLogger(__name__) if self.__applicationName is None: self.__log.warn("No application name was found. Only common services will be discoverable.") else: self.__log.info("Application name: " + self.__applicationName) try: self.__common_services = list(self.ezd_client.get_common_services()) except Exception: self.__log.error("Unable to get common services") raise self.__refresh_end_points() self.__refresh_common_endpoints() thread = threading.Thread(target=self._evict_daemon) thread.setDaemon(True) thread.start()
class ThriftClientPool(object): """ """ def __init__(self, ez_props): if ez_props is None: raise Exception("Invalid EzProperties.") zk_con_str = ZookeeperConfiguration(ez_props).getZookeeperConnectionString() self.ezd_client = ServiceDiscoveryClient(zk_con_str) self.__applicationConfiguration = ApplicationConfiguration(ez_props) self.__applicationName = self.__applicationConfiguration.getApplicationName() self.__securityConfiguration = SecurityConfiguration(ez_props) self.__thriftConfiguration = ThriftConfiguration(ez_props) self.__rLock = threading.RLock() self.__serviceMap = {} self.__clientMap = {} self.__log = logging.getLogger(__name__) if self.__applicationName is None: self.__log.warn("No application name was found. Only common services will be discoverable.") else: self.__log.info("Application name: " + self.__applicationName) try: self.__common_services = list(self.ezd_client.get_common_services()) except Exception: self.__log.error("Unable to get common services") raise self.__refresh_end_points() self.__refresh_common_endpoints() thread = threading.Thread(target=self._evict_daemon) thread.setDaemon(True) thread.start() def _evict_daemon(self): check_interval_millis = self.__thriftConfiguration.getMillisBetweenClientEvictionChecks() idle_threshold_millis = self.__thriftConfiguration.getMillisIdleBeforeEviction() while True: time.sleep(check_interval_millis * 0.001) with self.__rLock: for client in self.__clientMap.itervalues(): client._pool.evict_check(idle_threshold_millis) def _get_service_map(self): return self.__serviceMap def _get_client_map(self): return self.__clientMap def __refresh_end_points(self): if (self.__applicationName is not None) and (self.__applicationName != ''): try: for service in self.ezd_client.get_services(self.__applicationName): try: endpoints = self.ezd_client.get_endpoints(self.__applicationName, service) self._add_endpoints(service, endpoints) except Exception: self.__log.warn("No " + service + " for application " + self.__applicationName + " was found") except Exception: self.__log.warn( "Failed to get application services. " "This might be okay if the application hasn't registered any services." ) def __refresh_common_endpoints(self): try: for service in self.ezd_client.get_common_services(): try: endpoints = self.ezd_client.get_common_endpoints(service) self._add_endpoints(service, endpoints) except Exception: self.__log.warn("No common service " + service + " was found.") except Exception: self.__log.warn("Failed to get common services. This might be okay if no common service has been defined.") def _add_endpoints(self, service, endpoints): with self.__rLock: if service in self.__serviceMap: del self.__serviceMap[service] self.__serviceMap[service] = [] for endpoint in endpoints: self.__serviceMap[service].append(endpoint) @staticmethod def __get_thrift_connection_key(service_name, client_class): return service_name + "|" + str(client_class) def __get_endpoints(self, service_name, retry=True): with self.__rLock: if service_name in self.__serviceMap: return self.__serviceMap[service_name] if retry: self.__refresh_end_points() self.__refresh_common_endpoints() return self.__get_endpoints(service_name, retry=False) return None def get_client(self, app_name=None, service_name=None, clazz=None): if not service_name: raise ValueError("'service_name' does not have a valid value (%s)." % service_name) if not clazz: raise ValueError("'clazz' does not have a valid value (%s)." % clazz) try: key = self.__get_thrift_connection_key(service_name, clazz) with self.__rLock: if app_name: service = self.__applicationConfiguration.getApplicationServiceName(app_name, service_name) if service not in self.__serviceMap: endpoints = self.ezd_client.get_endpoints(app_name, service_name) self._add_endpoints(service, endpoints) # get client from client pool, or initialize client if key in self.__clientMap: client = self.__clientMap[key] else: endpoints = self.__get_endpoints(service_name) if endpoints is None: return None pool_size = self.__thriftConfiguration.getMaxIdleClients() if self.__thriftConfiguration.useSSL(): sc = self.__securityConfiguration ca_certs = sc.getTrustedSslCerts() key_file = sc.getPrivateKey() cert = sc.getSslCertificate() client = PoolingThriftClient(endpoints, clazz, pool_size=pool_size, use_ssl=True, ca_certs=ca_certs, cert=cert, key=key_file) else: client = PoolingThriftClient(endpoints, clazz, pool_size=pool_size) self.__clientMap[key] = client return client except Exception, e: raise TException(str(e))