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()
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()
def main(): platform = Platform() # register a route name for a pub/sub subscriber function # setting number of instance to 1 because pub/sub subscriber is always a singleton platform.register('hello.world', hello, 1) # Once it connects to the network, it is ready to serve requests 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 pubsub = PubSub() if pubsub.feature_enabled(): # # the pub/sub topic name must be different from the subscriber function name # # Note: # For kafka, the parameter list includes the following: # client_id, group_id and optional offset number (as a string) # e.g. ["client1", "group1"] or ["client1", "group1", "0"] # # In this example, it is reading from the beginning of the topic. # For a real application, it should read without the offset so that it can fetch the latest events. # pubsub.subscribe("hello.topic", "hello.world", ["client1", "group1", "0"]) else: print("Pub/Sub feature not available from the underlying event stream") print("Did you start the language connector with Kafka?") print( "e.g. java -Dcloud.connector=kafka -Dcloud.services=kafka.reporter -jar language-connector-1.12.31.jar" ) # # 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()
def main(): platform = Platform() # this shows that we can register a route name for a function platform.register('hello.world', hello, 10) # Once it connects to the network, it is ready to serve requests 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 # # 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()
def main(): platform = Platform() # we should register the custom trace processor as a singleton platform.register('distributed.trace.processor', my_trace_processor, 1) # Once it connects to the network, it is ready to serve requests 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 # # 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()
class PubSub: def __init__(self): self.platform = Platform() self.po = PostOffice() self.util = Utility() self.subscription = dict() def subscription_sync(headers: dict, body: any): if 'type' in headers and headers['type'] == 'subscription_sync': if len(self.subscription) > 0: for topic in self.subscription: route_map = self.subscription[topic] for route in route_map: parameters = route_map[route] self.platform.log.info('Update subscription ' + topic + ' -> ' + route) self.subscribe(topic, route, parameters) else: self.platform.log.info('No subscription to update') self.platform.register('pub.sub.sync', subscription_sync, 1, is_private=True) def feature_enabled(self): result = self.po.request('pub.sub.controller', 10.0, headers={'type': 'feature'}) return self._normalize_result(result, True) def list_topics(self): result = self.po.request('pub.sub.controller', 10.0, headers={'type': 'list'}) return self._normalize_result(result, list()) def exists(self, topic: str): if isinstance(topic, str): result = self.po.request('pub.sub.controller', 10.0, headers={ 'type': 'exists', 'topic': topic }) return self._normalize_result(result, True) else: return False def create_topic(self, topic: str): if isinstance(topic, str): result = self.po.request('pub.sub.controller', 10.0, headers={ 'type': 'create', 'topic': topic }) return self._normalize_result(result, True) else: raise ValueError("topic must be str") def delete_topic(self, topic: str): if isinstance(topic, str): result = self.po.request('pub.sub.controller', 10.0, headers={ 'type': 'delete', 'topic': topic }) return self._normalize_result(result, True) else: raise ValueError("topic must be str") def publish(self, topic: str, headers: dict = None, body: any = None): if isinstance(topic, str): # encode payload payload = dict() payload['body'] = body payload['headers'] = self._normalize_headers(headers) result = self.po.request('pub.sub.controller', 10.0, headers={ 'type': 'publish', 'topic': topic }, body=payload) return self._normalize_result(result, True) else: raise ValueError("topic must be str") def subscribe(self, topic: str, route: str, parameters: list = None): if isinstance(topic, str) and isinstance(route, str): if self.platform.has_route(route): normalized_config = self._normalize_parameters(parameters) result = self.po.request('pub.sub.controller', 10.0, body=normalized_config, headers={ 'type': 'subscribe', 'topic': topic, 'route': route }) done = self._normalize_result(result, True) if done: if topic not in self.subscription: self.subscription[topic] = dict() self.platform.log.info('Subscribed topic ' + topic) route_map: dict = self.subscription[topic] if route not in route_map: route_map[route] = normalized_config self.platform.log.info('Adding ' + route + ' to topic ' + topic) return done else: raise ValueError("Unable to subscribe topic " + topic + " because route " + route + " not registered") else: raise ValueError("topic and route must be str") def unsubscribe(self, topic: str, route: str): if isinstance(topic, str) and isinstance(route, str): if self.platform.has_route(route): result = self.po.request('pub.sub.controller', 10.0, headers={ 'type': 'unsubscribe', 'topic': topic, 'route': route }) done = self._normalize_result(result, True) if done: if topic in self.subscription: route_map: dict = self.subscription[topic] if route in route_map: route_map.pop(route) self.platform.log.info('Removing ' + route + ' from topic ' + topic) if len(route_map) == 0: self.subscription.pop(topic) self.platform.log.info('Unsubscribed topic ' + topic) return done else: raise ValueError("Unable to unsubscribe topic " + topic + " because route " + route + " not registered") else: raise ValueError("topic and route must be str") @staticmethod def _normalize_result(result: EventEnvelope, result_obj: any): if isinstance(result, EventEnvelope): if result.get_status() == 200: if isinstance(result.get_body(), type(result_obj)): return result.get_body() else: raise AppException(500, str(result.get_body())) else: raise AppException(result.get_status(), str(result.get_body())) @staticmethod def _normalize_headers(headers: dict): if headers is None: return dict() if isinstance(headers, dict): result = dict() for h in headers: result[str(h)] = str(headers[h]) return result else: raise ValueError("headers must be dict of str key-values") @staticmethod def _normalize_parameters(parameters: list): if parameters is None: return list() if isinstance(parameters, list): result = list() for h in parameters: result.append(str(h)) return result else: raise ValueError("headers must be a list of str")