async def video_handler(self): requestId = self.application.request_id_gen.get() img_format = self.get_argument('dtype', 'uint8') url = self.get_argument('url', None) mode = self.get_argument('mode', None) callback_id = self.get_argument('callback_id', None) video_type = self.get_argument('video_type', 'live') meta = {'id': requestId, 'status': -1} if url is not None: meta['url'] = url meta['dtype'] = img_format meta['video_type'] = video_type if callback_id: meta['callback_id'] = callback_id else: self.write(json.dumps(meta)) return # print("%s:%f Starting service" % (callback_id, time.time())) loop = tornado.ioloop.IOLoop.instance() result = await loop.run_in_executor(ServiceManager()._threadpool, ServiceManager().run, self.handlers['service'], np.zeros(0), meta) # print("%s:%f:Returned from service" % (callback_id, time.time())) if result is not None: (meta, buf) = result else: # print("No return from video_handler") pass # print(json.dumps(meta)) self.write(json.dumps(meta))
def check_exit(self): if self.do_exit: self.xspub.end("__server__") self.xs2server.join() self.heartbeat_thread.join() self.ws_server.stop() self.web_server.stop() cancel_async_tasks() del self.xserver elif self.hbeat > 4: self.hbeat = 0 service_manager = ServiceManager() services_list = service_manager.list() started_services = [] for name, svc in services_list.items(): if svc['state'] >= service_manager.STARTING: started_services.append(name) for service in started_services: msg = json.dumps({ '__heartbeat__': service, 'id': 'hbeat_' + str(self.hbeat_id) }) service_manager.send(service, 0, np.zeros(1), msg) self.hbeat_id = (self.hbeat_id + 1) % 9999 else: self.hbeat += 1
async def image_handler(self): requestId = self.application.request_id_gen.get() img = self.get_argument('image', None) img_format = self.get_argument('dtype', 'uint8') url = self.get_argument('url', None) meta = {'id': requestId, 'status': -1} if img is not None: dat = json.loads(img) image = np.asarray(dat["data"], dtype=getattr(np, img_format)) meta['dtype'] = img_format meta['mode'] = "image" elif url is not None: meta['url'] = url meta['mode'] = 'url' meta['dtype'] = img_format image = np.zeros(0) else: self.write(json.dumps(meta)) return loop = tornado.ioloop.IOLoop.instance() result = await loop.run_in_executor(ServiceManager()._threadpool, ServiceManager().run, self.handlers['service'], image, meta) if result is not None: (meta, buf) = result # print(json.dumps(meta)) self.write(json.dumps(meta))
def xstream2server(): xs = xstream.Subscribe("__server__") while True: # subscribe to special "__server__" channel for # other processes to send messages to this server # e.g. speedodata -> websockets msg_str = xs.get_msg() if msg_str is None: break try: msg = json.loads(msg_str) if msg['topic'] == 'speedodata': WebSocketHandler.broadcast(msg['topic'], msg['message']) elif msg['topic'] == 'callback' and 'callback_id' in msg: # print("sending callback message") # print(msg['message']) WebSocketHandler.send_to_client(\ msg['callback_id'], msg['topic'], msg['message']) elif msg['topic'] == 'xs_throughput': report = json.loads(msg['message']) #print(report) for name, throughput in report.items(): serviceName = name.split('.')[0] edgeName = name[name.find('.') + 1:] ServiceManager().update_throughput_stats( serviceName, edgeName, throughput) except: pass cancel_async_tasks()
def get(self, *args): ret = {'services': []} try: services_list = ServiceManager().list() services = [] for name, svc in services_list.items(): services.append({ 'name': name, 'state': svc['state'], 'url': svc['url'], 'throughput': svc['throughput'] }) services.sort(key=lambda x: x['name']) ret = {'services': services} except Exception as e: logger.exception("List service error") self.write(json.dumps(ret, sort_keys=True))
def post(self, *args): data = json.loads(self.request.body) service_name = data["id"] # in unicode runtime_args = data["args"] if 'args' in data else {} ServiceManager().start(service_name, runtime_args) self.write("service started")
def get(self, *args): service_name = self.get_argument("service") ret = {} try: services_list = ServiceManager().list() if service_name in services_list: ret = services_list[service_name] del ret['service'] except Exception as e: logger.exception("Query service error") self.write(json.dumps(ret, sort_keys=True))
def post(self, *args): found_index, name, url = self._destroy() if found_index != -1: del self.application.default_router.rules[found_index] ServiceManager().remove(name) recipe_cache = os.environ["VAI_HOME"] + "/demo/neptune/recipes/recipe_%s.bak" % name os.remove(recipe_cache) self.write("service destroyed at /serve/%s" % url) else: self.write("Service %s cannot be destroyed as it does not exist" % name)
def _construct(graph, args, name, url, handlers): # Plasma, for whatever reason, enforces this for their IDs. Since these # names are used as IDs, we have to enforce this too. This name gets # appended with other strings (the overall length must be <20 chars) so # ours needs to be less than 12 chars if len(name) >= 12: print("Cannot construct service, name too long (must be <12 chars") return get_artifacts(args) (graphObj, module, args) = parse_graph(graph, args, name) if url == '': url = generate_hash(graph) serve_url = "/serve/%s" % url new_service = service.Service(name, {}, graphObj) ServiceManager().add(name, new_service, serve_url, args) handler_methods = {'service': name} if 'get' in handlers: get_methods = [] for method in handlers['get']: handler_module = 'neptune.handlers.' + method.split('.')[0] module_0 = __import__(handler_module, fromlist=[method.split('.')[1]]) func = getattr(module_0, method.split('.')[1]) get_methods.append(func) handler_methods['get'] = get_methods if 'post' in handlers: post_methods = [] for method in handlers['post']: handler_module = 'neptune.handlers.' + method.split('.')[0] module_0 = __import__(handler_module, fromlist=[method.split('.')[1]]) func = getattr(module_0, method.split('.')[1]) post_methods.append(func) handler_methods['post'] = post_methods if 'patch' in handlers: patch_methods = [] for method in handlers['patch']: handler_module = 'neptune.handlers.' + method.split('.')[0] module_0 = __import__(handler_module, fromlist=[method.split('.')[1]]) func = getattr(module_0, method.split('.')[1]) patch_methods.append(func) handler_methods['patch'] = patch_methods return [(r"" + serve_url, GenericHandler, dict(handlers=handler_methods))]
async def ping_handler(self): meta = {'id': self.application.request_id_gen.get()} #callback_id = self.get_argument('callback_id', None) #if callback_id: # meta['callback_id'] = callback_id loop = tornado.ioloop.IOLoop.instance() result = await loop.run_in_executor(ServiceManager()._threadpool, ServiceManager().run, self.handlers['service'], np.zeros(1), meta) # print("Returned from service_manager run") if result: (meta, buf) = result self.write( json.dumps(meta, sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False)) else: logger.warning("Nothing returned from ping handler") self.set_status(500) self.write("Ping service is not active")
def signal_handler(self, signum, frame): logger.status("Shutting down server...") ServiceManager().stop_all() self.do_exit = True
def heartbeat(stop): xs = xstream.Subscribe("__heartbeat__", timeout=5000) service_manager = ServiceManager() node_status = {} def check_services(node_status): if stop: return invalid_services = [] for service, status in node_status.items(): last_valid = status['last_valid'] service_state = service_manager._services[service]['state'] is_starting = service_state == service_manager.STARTING is_started = service_state == service_manager.STARTED # if the service has been stopped, clear it if service_state == service_manager.STOPPED: invalid_services.append(service) # if there's a discrepancy in what the service_manager says # and what we have cached, clear it elif is_starting and node_status[service]['is_started']: invalid_services.append(service) # if it's started and hasn't been valid in the last n secs, # restart it elif is_started and now - last_valid > 5: logger.warning("Service %s is dead, restarting" % service) service_manager.stop(service) service_manager.start(service) node_status[service]['is_started'] = False for service in invalid_services: del node_status[service] logger = logging.getLogger(__name__) while True: if stop(): break # when enabling coverage, this line will raise an exception for some # reason. For now, just catching it try: msg_str = xs.get_msg() now = time.time() except Exception: logger.exception("Shouldn't happen") # the get_msg timed out, i.e. no heartbeats received if msg_str == (None, None): check_services(node_status) continue msg = json.loads(msg_str) service = msg['service'] channel = msg['channel'] # if this is the first time we've seen this service if service not in node_status: _first_edge, last_edge = service_manager._get_graph_io(service) node_status[service] = { 'last_valid': 0, # saves the last time this service was valid 'is_started': False, # our check that services haven't stopped 'last_edge': last_edge[0], # saves the last edge of the service 'channels': {} # save heartbeat times for each channel } node_status[service]['channels'][channel] = now service_state = service_manager._services[service]['state'] if node_status[service]['last_edge'] == channel: if service_state == service_manager.STARTING: if not node_status[service]['is_started']: service_manager._services[service][ 'state'] = service_manager.STARTED node_status[service]['is_started'] = True else: # there's a discrepancy. For example, the service may # have been stopped and something else started with # the same name. In this case, clear the cache del node_status[service] continue node_status[service]['last_valid'] = now check_services(node_status) cancel_async_tasks()
def get(self, *args): service_name = self.get_argument("id") ServiceManager().stop(service_name) self.write("service stopped")
def get(self, *args): service_name = self.get_argument("id") runtime_args = self.get_argument("args", {}) ServiceManager().start(service_name, runtime_args) self.write("service started")