Beispiel #1
0
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()
Beispiel #2
0
 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()
Beispiel #3
0
 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)
Beispiel #4
0
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)))