def dispy_provisional_result(result): """Sends provisional result of computation back to the client. In some cases, such as optimizations, computations may send current (best) result to the client and continue computation (for next iteration) so that the client may decide to terminate computations based on the results or alter computations if necessary. The computations can use this function in such cases with the current result of computation as argument. """ __dispy_job_reply = __dispy_job_info.job_reply logger.debug('Sending provisional result for job %s to %s', __dispy_job_reply.uid, __dispy_job_info.reply_addr) __dispy_job_reply.status = DispyJob.ProvisionalResult __dispy_job_reply.result = result sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = AsynCoroSocket(sock, blocking=True, keyfile=__dispy_job_keyfile, certfile=__dispy_job_certfile) sock.settimeout(2) try: sock.connect(__dispy_job_info.reply_addr) sock.send_msg(serialize(__dispy_job_reply)) ack = sock.recv_msg() except: logger.warning("Couldn't send provisional results %s:\n%s", str(result), traceback.format_exc()) sock.close()
def _send_job_reply(self, job_info, resending=False, coro=None): """Internal use only. """ assert coro is not None job_reply = job_info.job_reply logger.debug('Sending result for job %s (%s) to %s', job_reply.uid, job_reply.status, str(job_info.reply_addr)) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = AsynCoroSocket(sock, blocking=False, certfile=self.certfile, keyfile=self.keyfile) sock.settimeout(2) try: yield sock.connect(job_info.reply_addr) yield sock.send_msg(serialize(job_reply)) ack = yield sock.recv_msg() assert ack == 'ACK' except: logger.error("Couldn't send results for %s to %s", job_reply.uid, str(job_info.reply_addr)) # store job result even if computation has not enabled # fault recovery; user may be able to access node and # retrieve result manually f = os.path.join(job_info.compute_dest_path, '_dispy_job_reply_%s' % job_reply.uid) logger.debug('storing results for job %s', job_reply.uid) try: fd = open(f, 'wb') pickle.dump(job_reply, fd) fd.close() except: logger.debug('Could not save results for job %s', job_reply.uid) else: yield self.lock.acquire() compute = self.computations.get(job_info.compute_id, None) if compute is not None: compute.pending_results += 1 self.lock.release() finally: sock.close() if not resending: yield self.lock.acquire() self.avail_cpus += 1 compute = self.computations.get(job_info.compute_id, None) if compute is None: logger.warning('Computation for %s / %s is invalid!', job_reply.uid, job_info.compute_id) else: # technically last_pulse should be updated only # when successfully sent reply, but no harm if done # otherwise, too compute.last_pulse = time.time() compute.pending_jobs -= 1 if compute.pending_jobs == 0 and compute.zombie: self.cleanup_computation(compute) self.lock.release()
def _send_job_reply(self, job_info, resending=False, coro=None): """Internal use only. """ assert coro is not None job_reply = job_info.job_reply logger.debug('Sending result for job %s (%s) to %s', job_reply.uid, job_reply.status, str(job_info.reply_addr)) if not resending: self.avail_cpus += 1 assert self.avail_cpus <= self.num_cpus sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = AsynCoroSocket(sock, blocking=False, certfile=self.certfile, keyfile=self.keyfile) sock.settimeout(5) try: yield sock.connect(job_info.reply_addr) yield sock.send_msg(serialize(job_reply)) ack = yield sock.recv_msg() assert ack == 'ACK' compute = self.computations.get(job_info.compute_id, None) if compute is not None: compute.last_pulse = time.time() except: logger.error("Couldn't send results for %s to %s : %s", job_reply.uid, str(job_info.reply_addr), traceback.format_exc()) # store job result even if computation has not enabled # fault recovery; user may be able to access node and # retrieve result manually f = os.path.join(job_info.compute_dest_path, '_dispy_job_reply_%s' % job_reply.uid) logger.debug('storing results for job %s', job_reply.uid) try: fd = open(f, 'wb') pickle.dump(job_reply, fd) fd.close() except: logger.debug('Could not save results for job %s', job_reply.uid) else: compute = self.computations.get(job_info.compute_id, None) if compute is not None: compute.pending_results += 1 finally: sock.close() if not resending: compute = self.computations.get(job_info.compute_id, None) if compute is not None: compute.pending_jobs -= 1 if compute.pending_jobs == 0 and compute.zombie: self.cleanup_computation(compute)
class Peer_Remote(): # outbound connections def __init__(self, network_service, remote_ip, remote_port, context=None): self.exit = False self.network_service = network_service self.remote_ip = remote_ip self.remote_port = remote_port self.context = context Coro(self._server_connect) def _server_connect(self, coro=None): try: #logger.debug('CLIENT: connecting to peer at %s:%s', self.remote_ip, str(self.remote_port)) self.outbound_socket = AsynCoroSocket(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) self.outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) # if you're gonna act like UDP yield self.outbound_socket.connect((self.remote_ip, self.remote_port)) #logger.debug('CLIENT: connected to peer at %s:%s', self.remote_ip, str(self.remote_port)) self._send_coro = Coro(self._client_send) #Coro(self._client_recv) # unneeded if we don't utilize bi-directional communication in UDP style messaging self.network_service.on_server_connect(self, self.context) except: show_error() #raise def _client_recv(self, coro=None): while True: try: data = yield self.outbound_socket.recv_msg() if data == None or len(data) == 0 or self.exit: break #logger.debug('CLIENT: received data to peer at %s:%s (Data: %s)', self.remote_ip, str(self.remote_port), data) self.network_service.on_peer_data_received(data) except: show_error() #break #print "Coro(_client_recv) exiting" def _client_send(self, coro=None): coro.set_daemon() while True: try: cmd, state = yield self._send_coro.receive() data, context = state if cmd == NETWORK_PEER_DISCONNECT: self.network_service.on_client_disconnected(context) break #logger.debug('CLIENT: sending data to %s:%s (Data is: %s)', self.remote_ip, self.remote_port,data) yield self.outbound_socket.send_msg(data) self.network_service.on_client_data_sent(context) except: show_error() #break self.outbound_socket.shutdown(socket.SHUT_RDWR) self.outbound_socket.close() #logger.debug('CLIENT: disconnected from %s:%s', self.remote_ip, str(self.remote_port)) #print "Coro(_client_send) exiting" def send(self, data, context): if not self.exit: self._send_coro.send((None, (data, context))) def stop(self, context=None): self.exit = True #logger.debug('CLIENT: disconnecting from %s:%s', self.remote_ip, str(self.remote_port)) self._send_coro.send((NETWORK_PEER_DISCONNECT, (None,context)))