def main(): # IPC pupil_queue = Queue() timebase = Value(c_double, 0) cmd_world_end, cmd_launcher_end = Pipe() com0 = Pipe(True) eyes_are_alive = Value(c_bool, 0), Value(c_bool, 0) com1 = Pipe(True) com_world_ends = com0[0], com1[0] com_eye_ends = com0[1], com1[1] p_world = Process( target=world, args=( pupil_queue, timebase, cmd_world_end, com_world_ends, eyes_are_alive, user_dir, app_version, video_sources["world"], ), ) p_world.start() while True: # block and listen for commands from world process. cmd = cmd_launcher_end.recv() if cmd == "Exit": break else: eye_id = cmd p_eye = Process( target=eye, args=( pupil_queue, timebase, com_eye_ends[eye_id], eyes_are_alive[eye_id], user_dir, app_version, eye_id, video_sources["eye%s" % eye_id], ), ) p_eye.start() for p in active_children(): p.join() logger.debug("Laucher exit")
def main(): #IPC pupil_queue = Queue() timebase = Value(c_double, 0) cmd_world_end, cmd_launcher_end = Pipe() com0 = Pipe(True) eyes_are_alive = Value(c_bool, 0), Value(c_bool, 0) com1 = Pipe(True) com_world_ends = com0[0], com1[0] com_eye_ends = com0[1], com1[1] p_world = Process(target=world, args=(pupil_queue, timebase, cmd_world_end, com_world_ends, eyes_are_alive, user_dir, app_version, video_sources['world'])) p_world.start() while True: #block and listen for commands from world process. cmd = cmd_launcher_end.recv() if cmd == "Exit": break else: eye_id = cmd p_eye = Process(target=eye, args=(pupil_queue, timebase, com_eye_ends[eye_id], eyes_are_alive[eye_id], user_dir, app_version, eye_id, video_sources['eye%s' % eye_id])) p_eye.start() for p in active_children(): p.join() logger.debug('Laucher exit')
def launcher(): """Starts eye processes. Hosts the IPC Backbone and Logging functions. Reacts to notifications: ``launcher_process.should_stop``: Stops the launcher process ``eye_process.should_start``: Starts the eye process """ #Reliable msg dispatch to the IPC via push bridge. def pull_pub(ipc_pub_url,pull): ctx = zmq.Context.instance() pub = ctx.socket(zmq.PUB) pub.connect(ipc_pub_url) while True: m = pull.recv_multipart() pub.send_multipart(m) #The delay proxy handles delayed notififications. def delay_proxy(ipc_pub_url,ipc_sub_url): ctx = zmq.Context.instance() sub = zmq_tools.Msg_Receiver(ctx,ipc_sub_url,('delayed_notify',)) pub = zmq_tools.Msg_Dispatcher(ctx,ipc_pub_url) poller = zmq.Poller() poller.register(sub.socket, zmq.POLLIN) waiting_notifications = {} while True: if poller.poll(timeout=250): #Recv new delayed notification and store it. topic,n = sub.recv() n['_notify_time_'] = time()+n['delay'] waiting_notifications[n['subject']] = n #When a notifications time has come, pop from dict and send it as notification for n in waiting_notifications.values(): if n['_notify_time_'] < time(): del n['_notify_time_'] del n['delay'] del waiting_notifications[n['subject']] pub.notify(n) #Recv log records from other processes. def log_loop(ipc_sub_url,log_level_debug): import logging #Get the root logger logger = logging.getLogger() #set log level if log_level_debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) #Stream to file fh = logging.FileHandler(os.path.join(user_dir,'capture.log'),mode='w') fh.setFormatter(logging.Formatter('%(asctime)s - %(processName)s - [%(levelname)s] %(name)s: %(message)s')) logger.addHandler(fh) #Stream to console. ch = logging.StreamHandler() ch.setFormatter(logging.Formatter('%(processName)s - [%(levelname)s] %(name)s: %(message)s')) logger.addHandler(ch) # IPC setup to receive log messages. Use zmq_tools.ZMQ_handler to send messages to here. sub = zmq_tools.Msg_Receiver(zmq_ctx,ipc_sub_url,topics=("logging",)) while True: topic,msg = sub.recv() record = logging.makeLogRecord(msg) logger.handle(record) ## IPC timebase = Value(c_double,0) eyes_are_alive = Value(c_bool,0),Value(c_bool,0) zmq_ctx = zmq.Context() #Let the OS choose the IP and PORT ipc_pub_url = 'tcp://*:*' ipc_sub_url = 'tcp://*:*' ipc_push_url = 'tcp://*:*' # Binding IPC Backbone Sockets to URLs. # They are used in the threads started below. # Using them in the main thread is not allowed. xsub_socket = zmq_ctx.socket(zmq.XSUB) xsub_socket.bind(ipc_pub_url) ipc_pub_url = xsub_socket.last_endpoint.replace("0.0.0.0","127.0.0.1") xpub_socket = zmq_ctx.socket(zmq.XPUB) xpub_socket.bind(ipc_sub_url) ipc_sub_url = xpub_socket.last_endpoint.replace("0.0.0.0","127.0.0.1") pull_socket = zmq_ctx.socket(zmq.PULL) pull_socket.bind(ipc_push_url) ipc_push_url = pull_socket.last_endpoint.replace("0.0.0.0","127.0.0.1") # Starting communication threads: # A ZMQ Proxy Device serves as our IPC Backbone ipc_backbone_thread = Thread(target=zmq.proxy, args=(xsub_socket,xpub_socket)) ipc_backbone_thread.setDaemon(True) ipc_backbone_thread.start() pull_pub = Thread(target=pull_pub, args=(ipc_pub_url,pull_socket)) pull_pub.setDaemon(True) pull_pub.start() log_thread = Thread(target=log_loop, args=(ipc_sub_url,'debug'in sys.argv)) log_thread.setDaemon(True) log_thread.start() delay_thread = Thread(target=delay_proxy, args=(ipc_push_url,ipc_sub_url)) delay_thread.setDaemon(True) delay_thread.start() del xsub_socket,xpub_socket,pull_socket sleep(0.2) topics = ( 'notify.eye_process.', 'notify.launcher_process.', 'notify.meta.should_doc') cmd_sub = zmq_tools.Msg_Receiver(zmq_ctx,ipc_sub_url,topics=topics ) cmd_push = zmq_tools.Msg_Dispatcher(zmq_ctx,ipc_push_url) if app == 'service': Process(target=service, name= 'service', args=(timebase, eyes_are_alive, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version )).start() else: Process(target=world, name= 'world', args=(timebase, eyes_are_alive, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version, )).start() with Prevent_Idle_Sleep(): while True: #block and listen for relevant messages. topic,n = cmd_sub.recv() if "notify.eye_process.should_start" in topic: eye_id = n['eye_id'] if not eyes_are_alive[eye_id].value: Process(target=eye, name='eye%s'%eye_id, args=(timebase, eyes_are_alive[eye_id], ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version, eye_id )).start() elif "notify.launcher_process.should_stop" in topic: break elif "notify.meta.should_doc" in topic: cmd_push.notify({ 'subject':'meta.doc', 'actor':'launcher', 'doc':launcher.__doc__}) for p in active_children(): p.join()
def launcher(): """Starts eye processes. Hosts the IPC Backbone and Logging functions. Reacts to notifications: ``launcher_process.should_stop``: Stops the launcher process ``eye_process.should_start``: Starts the eye process """ #Reliable msg dispatch to the IPC via push bridge. def pull_pub(ipc_pub_url, pull): ctx = zmq.Context.instance() pub = ctx.socket(zmq.PUB) pub.connect(ipc_pub_url) while True: m = pull.recv_multipart() pub.send_multipart(m) #The delay proxy handles delayed notififications. def delay_proxy(ipc_pub_url, ipc_sub_url): ctx = zmq.Context.instance() sub = zmq_tools.Msg_Receiver(ctx, ipc_sub_url, ('delayed_notify', )) pub = zmq_tools.Msg_Dispatcher(ctx, ipc_pub_url) poller = zmq.Poller() poller.register(sub.socket, zmq.POLLIN) waiting_notifications = {} while True: if poller.poll(timeout=250): #Recv new delayed notification and store it. topic, n = sub.recv() n['_notify_time_'] = time() + n['delay'] waiting_notifications[n['subject']] = n #When a notifications time has come, pop from dict and send it as notification for n in waiting_notifications.values(): if n['_notify_time_'] < time(): del n['_notify_time_'] del n['delay'] del waiting_notifications[n['subject']] pub.notify(n) #Recv log records from other processes. def log_loop(ipc_sub_url, log_level_debug): import logging #Get the root logger logger = logging.getLogger() #set log level if log_level_debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) #Stream to file fh = logging.FileHandler(os.path.join(user_dir, 'capture.log'), mode='w') fh.setFormatter( logging.Formatter( '%(asctime)s - %(processName)s - [%(levelname)s] %(name)s: %(message)s' )) logger.addHandler(fh) #Stream to console. ch = logging.StreamHandler() ch.setFormatter( logging.Formatter( '%(processName)s - [%(levelname)s] %(name)s: %(message)s')) logger.addHandler(ch) # IPC setup to receive log messages. Use zmq_tools.ZMQ_handler to send messages to here. sub = zmq_tools.Msg_Receiver(zmq_ctx, ipc_sub_url, topics=("logging", )) while True: topic, msg = sub.recv() record = logging.makeLogRecord(msg) logger.handle(record) ## IPC timebase = Value(c_double, 0) eyes_are_alive = Value(c_bool, 0), Value(c_bool, 0) zmq_ctx = zmq.Context() #Let the OS choose the IP and PORT ipc_pub_url = 'tcp://*:*' ipc_sub_url = 'tcp://*:*' ipc_push_url = 'tcp://*:*' # Binding IPC Backbone Sockets to URLs. # They are used in the threads started below. # Using them in the main thread is not allowed. xsub_socket = zmq_ctx.socket(zmq.XSUB) xsub_socket.bind(ipc_pub_url) ipc_pub_url = xsub_socket.last_endpoint.replace("0.0.0.0", "127.0.0.1") xpub_socket = zmq_ctx.socket(zmq.XPUB) xpub_socket.bind(ipc_sub_url) ipc_sub_url = xpub_socket.last_endpoint.replace("0.0.0.0", "127.0.0.1") pull_socket = zmq_ctx.socket(zmq.PULL) pull_socket.bind(ipc_push_url) ipc_push_url = pull_socket.last_endpoint.replace("0.0.0.0", "127.0.0.1") # Starting communication threads: # A ZMQ Proxy Device serves as our IPC Backbone ipc_backbone_thread = Thread(target=zmq.proxy, args=(xsub_socket, xpub_socket)) ipc_backbone_thread.setDaemon(True) ipc_backbone_thread.start() pull_pub = Thread(target=pull_pub, args=(ipc_pub_url, pull_socket)) pull_pub.setDaemon(True) pull_pub.start() log_thread = Thread(target=log_loop, args=(ipc_sub_url, 'debug' in sys.argv)) log_thread.setDaemon(True) log_thread.start() delay_thread = Thread(target=delay_proxy, args=(ipc_push_url, ipc_sub_url)) delay_thread.setDaemon(True) delay_thread.start() del xsub_socket, xpub_socket, pull_socket sleep(0.2) topics = ('notify.eye_process.', 'notify.launcher_process.', 'notify.meta.should_doc') cmd_sub = zmq_tools.Msg_Receiver(zmq_ctx, ipc_sub_url, topics=topics) cmd_push = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url) if app == 'service': Process(target=service, name='service', args=(timebase, eyes_are_alive, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version)).start() else: Process(target=world, name='world', args=( timebase, eyes_are_alive, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version, )).start() with Prevent_Idle_Sleep(): while True: #block and listen for relevant messages. topic, n = cmd_sub.recv() if "notify.eye_process.should_start" in topic: eye_id = n['eye_id'] if not eyes_are_alive[eye_id].value: Process(target=eye, name='eye%s' % eye_id, args=(timebase, eyes_are_alive[eye_id], ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir, app_version, eye_id)).start() elif "notify.launcher_process.should_stop" in topic: break elif "notify.meta.should_doc" in topic: cmd_push.notify({ 'subject': 'meta.doc', 'actor': 'launcher', 'doc': launcher.__doc__ }) for p in active_children(): p.join()