def receive_message(self, block=True): try: if block: pargs = [] else: pargs = [0.0] reads, _, _ = select.select([self.in_fd], [], [], *pargs) have_message = self.in_fd in reads if have_message: (method, args) = read_framed_json(self.in_fp) if method == "subscribe" or method == "unsubscribe": if self.active_outputs is None: print >>sys.stderr, "Ignored request", method, "args", args, "because I have no active outputs dict" else: self.active_outputs.handle_request(method, args) elif method == "die": raise ShutdownException(args["reason"]) else: if self.pending_request is not None: if method != self.pending_request.method: print >>sys.stderr, "Ignored response of type", method, \ "because I'm waiting for", self.pending_request.method self.pending_request.response = args else: print >>sys.stderr, "Ignored request", method, "args", args return have_message except IOError: print >>sys.stderr, "RPC error when receiving message: process dying." sys.exit(-1)
def json_event_loop(self, reader, writer): while True: try: (method, args) = read_framed_json(reader) except: ciel.log('Error reading in JSON event loop', 'PROC', logging.WARN, True) return PROC_ERROR #ciel.log('Method is %s' % repr(method), 'PROC', logging.INFO) response = None response_fd = None try: if method == 'open_ref': if "ref" not in args: ciel.log('Missing required argument key: ref', 'PROC', logging.ERROR, False) return PROC_ERROR try: response = self.open_ref(**args) except ReferenceUnavailableException: response = {'error' : 'EWOULDBLOCK'} elif method == "open_ref_async": if "ref" not in args or "chunk_size" not in args: ciel.log("Missing required argument key: open_ref_async needs both 'ref' and 'chunk_size'", "PROC", logging.ERROR, False) return PROC_ERROR try: response, response_fd = self.open_ref_async(**args) except ReferenceUnavailableException: response = {"error": "EWOULDBLOCK"} elif method == "wait_stream": response = self.wait_async_file(**args) elif method == "close_stream": self.close_async_file(args["id"], args["chunk_size"]) elif method == 'spawn': response = self.spawn(args) elif method == 'tail_spawn': response = self.tail_spawn(args) elif method == 'allocate_output': response = self.allocate_output(**args) elif method == 'publish_string': response = self.publish_string(**args) elif method == 'log': # No response. self.log(**args) elif method == 'open_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log('Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log('Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response, response_fd = self.open_output(**args) elif method == 'close_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log('Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log('Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response = self.close_output(**args) elif method == 'rollback_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log('Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log('Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response = {'ref' : self.rollback_output(**args)} elif method == "advert": self.output_size_update(**args) elif method == "package_lookup": response = {"value": package_lookup(self.task_record, self.block_store, args["key"])} elif method == 'error': ciel.log('Task reported error: %s' % args["report"], 'PROC', logging.ERROR, False) raise TaskFailedError(args["report"]) elif method == 'exit': if args["keep_process"] == "must_keep": return PROC_MUST_KEEP elif args["keep_process"] == "may_keep": self.soft_cache_keys = args.get("soft_cache_keys", []) return PROC_MAY_KEEP elif args["keep_process"] == "no": return PROC_EXITED else: ciel.log("Bad exit status from task: %s" % args, "PROC", logging.ERROR) else: ciel.log('Invalid method: %s' % method, 'PROC', logging.WARN, False) return PROC_ERROR except MissingInputException, mie: ciel.log("Task died due to missing input", 'PROC', logging.WARN) raise except TaskFailedError: raise
def json_event_loop(self, reader, writer): while True: try: (method, args) = read_framed_json(reader) except: ciel.log('Error reading in JSON event loop', 'PROC', logging.WARN, True) return PROC_ERROR #ciel.log('Method is %s' % repr(method), 'PROC', logging.INFO) response = None response_fd = None try: if method == 'open_ref': if "ref" not in args: ciel.log('Missing required argument key: ref', 'PROC', logging.ERROR, False) return PROC_ERROR try: response = self.open_ref(**args) except ReferenceUnavailableException: response = {'error': 'EWOULDBLOCK'} elif method == "open_ref_async": if "ref" not in args or "chunk_size" not in args: ciel.log( "Missing required argument key: open_ref_async needs both 'ref' and 'chunk_size'", "PROC", logging.ERROR, False) return PROC_ERROR try: response, response_fd = self.open_ref_async(**args) except ReferenceUnavailableException: response = {"error": "EWOULDBLOCK"} elif method == "wait_stream": response = self.wait_async_file(**args) elif method == "close_stream": self.close_async_file(args["id"], args["chunk_size"]) elif method == 'spawn': response = self.spawn(args) elif method == 'tail_spawn': response = self.tail_spawn(args) elif method == 'allocate_output': response = self.allocate_output(**args) elif method == 'publish_string': response = self.publish_string(**args) elif method == 'log': # No response. self.log(**args) elif method == 'open_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log( 'Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log( 'Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response, response_fd = self.open_output(**args) elif method == 'close_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log( 'Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log( 'Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response = self.close_output(**args) elif method == 'rollback_output': try: index = int(args['index']) if index < 0 or index > len(self.expected_outputs): ciel.log( 'Invalid argument value: i (index) out of bounds [0, %s)' % self.expected_outputs, 'PROC', logging.ERROR, False) return PROC_ERROR except KeyError: if len(self.task_descriptor['expected_outputs']) == 1: args["index"] = 0 else: ciel.log( 'Missing argument key: i (index), and >1 expected output so could not infer index', 'PROC', logging.ERROR, False) return PROC_ERROR response = {'ref': self.rollback_output(**args)} elif method == "advert": self.output_size_update(**args) elif method == "package_lookup": response = { "value": package_lookup(self.task_record, self.block_store, args["key"]) } elif method == 'error': ciel.log('Task reported error: %s' % args["report"], 'PROC', logging.ERROR, False) raise TaskFailedError(args["report"]) elif method == 'exit': if args["keep_process"] == "must_keep": return PROC_MUST_KEEP elif args["keep_process"] == "may_keep": self.soft_cache_keys = args.get("soft_cache_keys", []) return PROC_MAY_KEEP elif args["keep_process"] == "no": return PROC_EXITED else: ciel.log("Bad exit status from task: %s" % args, "PROC", logging.ERROR) else: ciel.log('Invalid method: %s' % method, 'PROC', logging.WARN, False) return PROC_ERROR except MissingInputException, mie: ciel.log("Task died due to missing input", 'PROC', logging.WARN) raise except TaskFailedError: raise