def _send(self, message, dest_id=0, dest_seq=0): """_send(message, dest_id=0, dest_seq=0) Sends a message of raw bytes without checking whether they're bytes. Optionally, dest_id and dest_seq represent the message that this message replies to. These are used for the request/reply pattern. Returns the package that will be send (or None). The context will set _source_id on the package right before sending it away. """ # Check if still open if self._closed: className = self.__class__.__name__ raise IOError("Cannot send from closed %s %i." % (className, id(self))) if message: # If send_locked, wait at most one second if self._is_send_locked: self._send_condition.acquire() try: self._send_condition.wait(1.0) # wait for notify finally: self._send_condition.release() if time.time() > self._is_send_locked: self._is_send_locked = 0 # Push it on the queue as a package slot = self._slot_out_h cid = self._context._id p = Package(message, slot, cid, 0, dest_id, dest_seq, 0) self._context._send_package(p) # Return package return p else: return None
def connect(self, address, timeout=1.0, name=''): """ connect(self, address, timeout=1.0, name='') Setup a connection with another context, by connection to a hosting context. An error is raised when the connection could not be made. Returns a Connection instance that represents the connection to the other context. These connection objects can also be obtained via the Context.connections property. Parameters ---------- address : str Should be of the shape hostname:port. The port should be an integer number between 1024 and 2**16. If port does not represent a number, a valid port number is created using a hash function. max_tries : int The number of ports to try; starting from the given port, subsequent ports are tried until a free port is available. The final port can be obtained using the 'port' property of the returned Connection instance. name : string The name for the created Connection instance. It can be used as a key in the connections property. Notes on hostname ----------------- The hostname can be: * The IP address, or the string hostname of this computer. * 'localhost': the connection is only visible from this computer. Also some low level networking layers are bypassed, which results in a faster connection. The other context should also host as 'localhost'. * 'publichost': the connection is visible by other computers on the same network. Optionally an integer index can be appended if the machine has multiple IP addresses (see socket.gethostbyname_ex). """ # Trigger cleanup of closed connections self.connections # Split address in protocol, real hostname and port number protocol, hostname, port = split_address(address) # Based on protocol, instantiate connection class (currently only tcp) if False: #protocol == 'itc': connection = ItcConnection(self, name) else: connection = TcpConnection(self, name) # Create new connection and connect it connection._connect(hostname, port, timeout) # Save connection instance self._connections_lock.acquire() try: # Push packages from startup queue while self._startupQueue: connection._inject_package(self._startupQueue.pop()) # Add connection object to list of connections self._connections.append(connection) finally: self._connections_lock.release() # Send message in the network to signal a new connection bb = 'NEW_CONNECTION'.encode('utf-8') p = Package(bb, SLOT_CONTEXT, self._id, 0, 0, 0, 0) self._send_package(p) # Return Connection instance return connection