예제 #1
0
def main():
    platform = Platform()
    # you can register a method of a class
    platform.register('hello.world.1', Hi().hello, 5)
    # or register a function
    platform.register('hello.world.2', hello, 10)

    po = PostOffice()
    # demonstrate sending asynchronously. Note that key-values in the headers will be encoded as strings
    po.send('hello.world.1', headers={'one': 1}, body='hello world one')
    po.send('hello.world.2', headers={'two': 2}, body='hello world two')

    # demonstrate a RPC request
    try:
        result = po.request('hello.world.2', 2.0, headers={'some_key': 'some_value'}, body='hello world')
        if isinstance(result, EventEnvelope):
            print('Received RPC response:')
            print("HEADERS =", result.get_headers(), ", BODY =", result.get_body(),
                  ", STATUS =",  result.get_status(),
                  ", EXEC =", result.get_exec_time(), ", ROUND TRIP =", result.get_round_trip(), "ms")
    except TimeoutError as e:
        print("Exception: ", str(e))

    # illustrate parallel RPC requests
    event_list = list()
    event_list.append(EventEnvelope().set_to('hello.world.1').set_body("first request"))
    event_list.append(EventEnvelope().set_to('hello.world.2').set_body("second request"))
    try:
        result = po.parallel_request(event_list, 2.0)
        if isinstance(result, list):
            print('Received', len(result), 'RPC responses:')
            for res in result:
                print("HEADERS =", res.get_headers(), ", BODY =", res.get_body(),
                      ", STATUS =",  res.get_status(),
                      ", EXEC =", res.get_exec_time(), ", ROUND TRIP =", res.get_round_trip(), "ms")
    except TimeoutError as e:
        print("Exception: ", str(e))

    # connect to the network
    platform.connect_to_cloud()
    # wait until connected
    while not platform.cloud_ready():
        try:
            time.sleep(0.1)
        except KeyboardInterrupt:
            # this allows us to stop the application while waiting for cloud connection
            platform.stop()
            return

    # Demonstrate broadcast feature
    # the event will be broadcast to multiple application instances that serve the same route
    po.broadcast("hello.world.1", body="this is a broadcast message from "+platform.get_origin())

    # demonstrate deferred delivery
    po.send_later('hello.world.1', headers={'hello': 'world'}, body='this message arrives 5 seconds later', seconds=5.0)

    #
    # this will keep the main thread running in the background
    # so we can use Control-C or KILL signal to stop the application
    platform.run_forever()
예제 #2
0
class ObjectStreamWriter:
    def __init__(self, route: str):
        if not isinstance(route, str):
            raise ValueError('output stream-ID must be str')
        self.closed = False
        self.po = PostOffice()
        self.output_stream = route

    def write(self, payload: any):
        if not self.closed:
            if isinstance(payload, dict) or isinstance(payload, str) \
                    or isinstance(payload, bytes) \
                    or isinstance(payload, int) or isinstance(payload, float) or isinstance(payload, bool):
                # for orderly write, use RPC request to guarantee that payload is written into the object stream
                self.po.send(self.output_stream,
                             headers={'type': 'data'},
                             body=payload)
            else:
                raise ValueError(
                    'payload must be dict, str, bool, int or float')

    def close(self):
        if not self.closed:
            self.closed = True
            self.po.send(self.output_stream, headers={'type': 'eof'})
예제 #3
0
def main():
    platform = Platform()
    # register a function
    platform.register('hello.world', hello, 10)

    po = PostOffice()
    # demonstrate sending asynchronously. Note that key-values in the headers will be encoded as strings
    po.send('hello.world', headers={'one': 1}, body='hello world one')
    po.send('hello.world', headers={'two': 2}, body='hello world two')

    # demonstrate a RPC request
    try:
        result = po.request('hello.world',
                            2.0,
                            headers={'some_key': 'some_value'},
                            body='hello world')
        if isinstance(result, EventEnvelope):
            print('Received RPC response:')
            print("HEADERS =", result.get_headers(), ", BODY =",
                  result.get_body(), ", STATUS =", result.get_status(),
                  ", EXEC =", result.get_exec_time(), ", ROUND TRIP =",
                  result.get_round_trip(), "ms")
    except TimeoutError as e:
        print("Exception: ", str(e))

    # demonstrate drop-n-forget
    for n in range(20):
        po.send('hello.world', body='just a drop-n-forget message ' + str(n))

    #
    # this will keep the main thread running in the background
    # so we can use Control-C or KILL signal to stop the application
    platform.run_forever()
예제 #4
0
class ObjectStreamIO:

    STREAM_IO_MANAGER = 'object.streams.io'

    def __init__(self, route: str = None, expiry_seconds: int = 1800):
        self.platform = Platform()
        self.po = PostOffice()
        self.util = Utility()
        self.route = None
        self.input_stream = None
        self.output_stream = None
        self.eof = False
        self.input_closed = False
        self.output_closed = False

        if route is not None:
            # open an existing stream
            if isinstance(route, str):
                name: str = route
                if name.startswith('stream.') and '@' in name:
                    self.route = name
            if self.route is None:
                raise ValueError('Invalid stream route')
        else:
            # create a new stream
            if not isinstance(expiry_seconds, int):
                raise ValueError('expiry_seconds must be int')
            result = self.po.request(self.STREAM_IO_MANAGER,
                                     6.0,
                                     headers={
                                         'type': 'create',
                                         'expiry_seconds': expiry_seconds
                                     })
            if isinstance(result, EventEnvelope) and isinstance(result.get_body(), str) \
                    and result.get_status() == 200:
                name: str = result.get_body()
                if name.startswith('stream.') and '@' in name:
                    self.route = name
            if self.route is None:
                raise IOError('Stream manager is not responding correctly')

    def get_route(self):
        return self.route

    def is_eof(self):
        return self.eof

    def read(self, timeout_seconds: float):
        if self.input_stream:
            return self.input_stream()

        if isinstance(timeout_seconds, int):
            timeout_seconds = float(timeout_seconds)

        if isinstance(timeout_seconds, float):
            # minimum read timeout is one second
            if timeout_seconds < 1.0:
                timeout_seconds = 1.0
        else:
            raise ValueError('Read timeout must be float or int')

        def reader():
            while not self.eof:
                # if input stream has nothing, it will throw TimeoutError
                result = self.po.request(self.route,
                                         timeout_seconds,
                                         headers={'type': 'read'})
                if isinstance(result, EventEnvelope):
                    if result.get_status() == 200:
                        payload_type = result.get_headers().get('type')
                        if 'eof' == payload_type:
                            self.eof = True
                            break
                        if 'body' == payload_type:
                            yield result.get_body()
                    else:
                        raise AppException(result.get_status(),
                                           str(result.get_body()))

        self.input_stream = reader
        return reader()

    def write(self, payload: any, timeout_seconds: float = 10.0):
        if isinstance(timeout_seconds, int):
            timeout_seconds = float(timeout_seconds)

        if isinstance(timeout_seconds, float):
            # minimum write timeout is five second
            if timeout_seconds < 5.0:
                timeout_seconds = 5.0
        else:
            raise ValueError('Write timeout must be float or int')

        if not self.output_closed:
            if isinstance(payload, dict) or isinstance(payload, str) or isinstance(payload, bool) \
                    or isinstance(payload, int) or isinstance(payload, float):
                # for orderly write, use RPC request to guarantee that payload is written into the object stream
                self.po.request(self.route,
                                timeout_seconds,
                                headers={'type': 'write'},
                                body=payload)
            else:
                raise ValueError(
                    'payload must be dict, str, bool, int or float')

    def send_eof(self):
        if not self.output_closed:
            self.output_closed = True
            self.po.send(self.route, headers={'type': 'eof'})

    def is_output_closed(self):
        return self.output_closed

    def get_local_streams(self):
        result = self.po.request(self.STREAM_IO_MANAGER,
                                 6.0,
                                 headers={'type': 'query'})
        if isinstance(result, EventEnvelope) and isinstance(result.get_body(), dict) \
                and result.get_status() == 200:
            return result.get_body()
        else:
            return dict()

    def close(self):
        if not self.input_closed:
            self.input_closed = True
            self.po.send(self.route, headers={'type': 'close'})

    def is_input_closed(self):
        return self.input_closed