def _stop_server(node, expr): """Instruct single server to stop. Send stop command and then terminate process. Add port back to those available to new servers. """ root, path = lib.expr_split(expr) try: RemoteProcedureCall._send_to_server(node, root, 'stop') time.sleep(0.1) server_dict[expr]["process"].terminate() port_number_lock.acquire() allocated_port_number.append(server_dict[expr]["port"]) port_number_lock.release() node.print_info(TAG, "Server stopped with expr: %s" % expr) except Exception as e: node.print_error( TAG, "Error occured with 'stop' command for expression '%s': %s" % (expr, e)) raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(expr) }, code='-32603')
def _start_new_server(node, expr): """Create a single (new) server. Use next available port to start server process. Store server process and port. """ root, path = lib.expr_split(expr) try: try: port_number_lock.acquire() port = allocated_port_number.popleft() port_number_lock.release() except IndexError: node.print_error( TAG, "No ports remaining in allocation, cannot start new server." ) return False process = multiprocessing.Process(target=server.Server, args=(node, root, port)) process.daemon = True process.start() server_dict[expr] = {"process": process, "port": port} node.print_info(TAG, "New server started with expr: %s" % expr) except Exception as e: node.print_error( TAG, "Error occured with 'start' (new server) for expression '%s': %s" % (expr, e)) raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(expr) }, code='-32603')
def _call_method(self, rpc): try: result = getattr(self.controller, rpc.method)(rpc) return result except AttributeError: raise lib.RemoteProcedureCallError( data=('Controller has no method named: %s' % rpc.method), code='-32601')
def stat(self, rpc): """Retrieve statistics from the database. Handle the three permutations of node descriptions (all, list or single). Do final calculations and conversion for the aggregate statistic. """ try: total_result = dict([('total_cache_miss', 0), ('total_cache_miss_size', 0), ('total_cache_hit', 0), ('total_cache_hit_size', 0), ('total_cache_object', 0), ('total_cache_object_size', 0), ('start', 0), ('stop', 0), ('pause', 0), ('total_response_count', 0), ('total_node_id_count', 0), ('total_expr_count', 0), ('node_id_seen', set()), ('expr_seen', set()), ('node_expr_pairs_seen', set())]) if rpc.node_id == '*': for node in self._state.list_nodes(): total_result = self._stat_node(rpc.expr, node, total_result) elif "|" in rpc.node_id: for node in rpc.node_id.split("|"): total_result = self._stat_node(rpc.expr, node, total_result) else: total_result = self._stat_node(rpc.expr, rpc.node_id, total_result) total_result['total_node_id_count'] = len( total_result['node_id_seen']) total_result['total_expr_count'] = len(total_result['expr_seen']) total_result['total_response_count'] = len( total_result['node_expr_pairs_seen']) total_result['node_id_seen'] = list(total_result['node_id_seen']) total_result['expr_seen'] = list(total_result['expr_seen']) total_result['node_expr_pairs_seen'] = list( total_result['node_expr_pairs_seen']) return total_result except Exception as e: raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(rpc.expr) }, code='-32603')
def _validate_request(self, rpc): try: if "id" not in rpc.request: raise Exception else: rpc.id = str(rpc.request["id"]) if "method" not in rpc.request or "params" not in rpc.request or "jsonrpc" not in rpc.request: raise Exception else: rpc.method = str(rpc.request["method"]) rpc.params = rpc.request["params"] return rpc except Exception: raise lib.RemoteProcedureCallError( data='The JSON sent is not a valid Request object.', code='-32600')
def _stat_server(node, expr): """Instruct single server to return statistics to controller.""" root, path = lib.expr_split(expr) try: RemoteProcedureCall._send_to_server(node, root, 'stat') node.print_info(TAG, "Server stat'ed with expr: %s" % expr) except Exception as e: node.print_error( TAG, "Error occured with 'stat' command for expression '%s': %s" % (expr, e)) raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(expr) }, code='-32603')
def _seed_server(node, expr, transaction): root, path = lib.expr_split(expr) object_dict[expr] = transaction try: key = hashlib.sha224(path).hexdigest() path = node.config["cache_path"] + 'shared/' + transaction node.database.create({'key': key, 'path': path}) node.print_info(TAG, "Server seeded with expression: %s" % expr) except Exception as e: node.print_error( TAG, "Error occured with 'seed' command for expression '%s': %s" % (expr, e)) raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(expr) }, code='-32603')
def _validate_method_params(self, rpc): try: if rpc.method == 'hello': if "host" in rpc.params and "port" in rpc.params: rpc.host = str(rpc.params["host"]) rpc.port = str(rpc.params["port"]) else: raise Exception elif rpc.method == "keep_alive" or rpc.method == "goodbye": if "node-id" in rpc.params: rpc.node_id = str(rpc.params["node-id"]) else: raise Exception else: if "node-id" in rpc.params: rpc.node_id = str(rpc.params["node-id"]) if "expr" in rpc.params: rpc.expr = str(rpc.params["expr"]) return rpc except Exception: raise lib.RemoteProcedureCallError( data='Invalid method parameter(s).', code='-32602')
def fetch(self, rpc): """Send fetch requests to given nodes. Handle the three permutations of node descriptions (all, list or single). """ try: if rpc.node_id == '*': for node in self._state.list_nodes(): self._fetch_node(rpc.expr, node) elif "|" in rpc.node_id: for node in rpc.node_id.split("|"): self._fetch_node(rpc.expr, node) else: self._fetch_node(rpc.expr, rpc.node_id) return True except Exception as e: raise lib.RemoteProcedureCallError(data={ 'exception': str(e), 'node_id': str(node.node_id), 'expr': str(rpc.expr) }, code='-32603')