Gets the existing connection for a given address. If it does not exist, the system will try to connect
        asynchronously. In this case, it returns a Future. When the connection is established at some point in time, it
        can be retrieved by using the get_connection(:class:`~hazelcast.core.Address`) or from Future.

        :param address: (:class:`~hazelcast.core.Address`), the address to connect to.
        :param authenticator: (Function), function to be used for authentication (optional).
        :return: (:class:`~hazelcast.connection.Connection`), the existing connection or it returns a Future which includes asynchronously.

def get_or_connect(self, address, authenticator=None):
        """
        Gets the existing connection for a given address. If it does not exist, the system will try to connect
        asynchronously. In this case, it returns a Future. When the connection is established at some point in time, it
        can be retrieved by using the get_connection(:class:`~hazelcast.core.Address`) or from Future.

        :param address: (:class:`~hazelcast.core.Address`), the address to connect to.
        :param authenticator: (Function), function to be used for authentication (optional).
        :return: (:class:`~hazelcast.connection.Connection`), the existing connection or it returns a Future which includes asynchronously.
        """
        if address in self.connections:
            return ImmediateFuture(self.connections[address])
        else:
            with self._new_connection_mutex:
                if address in self._pending_connections:
                    return self._pending_connections[address]
                else:
                    authenticator = authenticator or self._cluster_authenticator
                    try:
                        translated_address = self._address_translator.translate(address)
                        if translated_address is None:
                            raise ValueError("Address translator could not translate address: {}".format(address))
                        connection = self._new_connection_func(translated_address,
                                                               self._client.config.network_config.connection_timeout,
                                                               self._client.config.network_config.socket_options,
                                                               connection_closed_callback=self._connection_closed,
                                                               message_callback=self._client.invoker._handle_client_message,
                                                               network_config=self._client.config.network_config)
                    except IOError:
                        return ImmediateExceptionFuture(sys.exc_info()[1], sys.exc_info()[2])

                    future = authenticator(connection).continue_with(self.on_auth, connection, address)
                    if not future.done():
                        self._pending_connections[address] = future
                    return future