Example #1
0
    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)
Example #2
0
File: proc.py Project: jepst/ciel
    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
Example #3
0
    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