Пример #1
0
    def get_lock_count(self):
        """Returns the reentrant lock count if the lock is held by any thread
        in the cluster.

        Returns:
            hazelcast.future.Future[int]: The reentrant lock count if the lock is held
            by any thread in the cluster

        Raises:
            LockOwnershipLostError: If the underlying CP session was
                closed before the client releases the lock
        """
        current_thread_id = thread_id()
        session_id = self._get_session_id()

        try:
            self._verify_locked_session_id_if_present(current_thread_id, session_id, False)
        except LockOwnershipLostError as e:
            return ImmediateExceptionFuture(e)

        def check_response(f):
            state = _LockOwnershipState(f.result())
            if state.is_locked_by(session_id, current_thread_id):
                self._lock_session_ids[current_thread_id] = session_id
            else:
                self._verify_no_locked_session_id_present(current_thread_id)

            return state.lock_count

        return self._request_get_lock_ownership_state().continue_with(check_response)
Пример #2
0
    def is_locked_by_current_thread(self):
        """Returns whether the lock is held by the current thread or not.

        Returns:
            hazelcast.future.Future[bool]: ``True`` if the lock is held by the current thread,
            ``False`` otherwise.

        Raises:
            LockOwnershipLostError: If the underlying CP session was
                closed before the client releases the lock
        """
        current_thread_id = thread_id()
        session_id = self._get_session_id()

        try:
            self._verify_locked_session_id_if_present(current_thread_id, session_id, False)
        except LockOwnershipLostError as e:
            return ImmediateExceptionFuture(e)

        def check_response(f):
            state = _LockOwnershipState(f.result())
            locked_by_the_current_thread = state.is_locked_by(session_id, current_thread_id)
            if locked_by_the_current_thread:
                self._lock_session_ids[current_thread_id] = session_id
            else:
                self._verify_no_locked_session_id_present(current_thread_id)

            return locked_by_the_current_thread

        return self._request_get_lock_ownership_state().continue_with(check_response)
Пример #3
0
        def send_state_to_cluster_fn():
            counter.add(1)
            if counter.get() == 5:
                # Let's pretend it succeeds at some point
                return ImmediateFuture(None)

            return ImmediateExceptionFuture(RuntimeError("expected"))
Пример #4
0
 def setUp(self):
     try:
         raise RuntimeError("error")
     except:
         self.exc = sys.exc_info()[1]
         self.traceback = sys.exc_info()[2]
         self.f = ImmediateExceptionFuture(self.exc, self.traceback)
Пример #5
0
    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
    def test_read_many_on_illegal_argument_error_with_loss_tolerant_listener_when_head_sequence_fails(
        self, ):
        self.error_on_first_read_many(IllegalArgumentError("expected"))
        self.ringbuffer.head_sequence.return_value = ImmediateExceptionFuture(
            RuntimeError("expected"))

        class Listener(ReliableMessageListener):
            def on_message(self, message):
                pass

            def retrieve_initial_sequence(self):
                return 0

            def store_sequence(self, sequence):
                pass

            def is_loss_tolerant(self):
                return True

            def is_terminal(self, error):
                pass

        self.topic.add_listener(Listener())
        self.assertEqual(1, self.ringbuffer.read_many.call_count)
        self.assertEqual(0, len(self.topic._runners))
Пример #7
0
    def unlock(self):
        """Releases the lock if the lock is currently held by the current thread.

        Returns:
            hazelcast.future.Future[None]:

        Raises:
            LockOwnershipLostError: If the underlying CP session was
                closed before the client releases the lock
            IllegalMonitorStateError: If the lock is not held by
                the current thread
        """
        current_thread_id = thread_id()
        session_id = self._get_session_id()

        # the order of the following checks is important
        try:
            self._verify_locked_session_id_if_present(current_thread_id,
                                                      session_id, False)
        except LockOwnershipLostError as e:
            return ImmediateExceptionFuture(e)

        if session_id == _NO_SESSION_ID:
            self._lock_session_ids.pop(current_thread_id, None)
            return ImmediateExceptionFuture(
                self._new_illegal_monitor_state_error())

        def check_response(f):
            try:
                still_locked_by_the_current_thread = f.result()
                if still_locked_by_the_current_thread:
                    self._lock_session_ids[current_thread_id] = session_id
                else:
                    self._lock_session_ids.pop(current_thread_id, None)

                self._release_session(session_id)
            except SessionExpiredError:
                self._invalidate_session(session_id)
                self._lock_session_ids.pop(current_thread_id, None)
                raise self._new_lock_ownership_lost_error(session_id)
            except IllegalMonitorStateError as e:
                self._lock_session_ids.pop(current_thread_id, None)
                raise e

        return self._request_unlock(session_id, current_thread_id,
                                    uuid.uuid4()).continue_with(check_response)
    def _get_or_connect_to_member(self, member):
        connection = self.active_connections.get(member.uuid, None)
        if connection:
            return ImmediateFuture(connection)

        try:
            translated = self._translate(member.address)
            connection = self._create_connection(translated)
            return self._authenticate(connection).continue_with(self._on_auth, connection)
        except Exception as e:
            return ImmediateExceptionFuture(e)
    def _get_or_connect_to_address(self, address):
        for connection in list(six.itervalues(self.active_connections)):
            if connection.remote_address == address:
                return ImmediateFuture(connection)

        try:
            translated = self._translate(address)
            connection = self._create_connection(translated)
            return self._authenticate(connection).continue_with(self._on_auth, connection)
        except Exception as e:
            return ImmediateExceptionFuture(e)
Пример #10
0
    def execute(self, sql, params, kwargs):
        """Constructs a statement and executes it.

        Args:
            sql (str): SQL string.
            params (tuple): Query parameters.
            kwargs (dict): Arguments to customize the query.

        Returns:
            hazelcast.future.Future[SqlResult]: The execution result.
        """
        statement = _SqlStatement(sql, params, **kwargs)

        connection = None
        try:
            connection = self._get_query_connection()
            # Create a new, unique query id.
            query_id = _SqlQueryId.from_uuid(connection.remote_uuid)

            # Serialize the passed parameters.
            serialized_params = [
                self._serialization_service.to_data(param)
                for param in statement.parameters
            ]

            request = sql_execute_codec.encode_request(
                statement.sql,
                serialized_params,
                # to_millis expects None to produce -1
                to_millis(None if statement.timeout ==
                          -1 else statement.timeout),
                statement.cursor_buffer_size,
                statement.schema,
                statement.expected_result_type,
                query_id,
                False,
            )

            invocation = Invocation(
                request,
                connection=connection,
                response_handler=sql_execute_codec.decode_response)
            self._invocation_service.invoke(invocation)
            return invocation.future.continue_with(lambda future: SqlResult(
                self,
                connection,
                query_id,
                statement.cursor_buffer_size,
                self._handle_execute_response(future, connection),
            ))
        except Exception as e:
            return ImmediateExceptionFuture(self.re_raise(e, connection))
Пример #11
0
    def _get_or_create_session(self, group_id):
        with self._lock:
            if self._shutdown:
                error = HazelcastClientNotActiveError("Session manager is already shut down!")
                return ImmediateExceptionFuture(error)

            session = self._sessions.get(group_id, None)
            if session is None or not session.is_valid():
                with self._mutex(group_id):
                    session = self._sessions.get(group_id)
                    if session is None or not session.is_valid():
                        return self._create_new_session(group_id)
            return ImmediateFuture(session)
Пример #12
0
    def _get_or_connect(self, address):
        connection = self.get_connection_from_address(address)
        if connection:
            return ImmediateFuture(connection)

        with self._lock:
            connection = self.get_connection_from_address(address)
            if connection:
                return ImmediateFuture(connection)
            else:
                pending = self._pending_connections.get(address, None)
                if pending:
                    return pending
                else:
                    try:
                        translated = self._address_provider.translate(address)
                        if not translated:
                            error = ValueError(
                                "Address translator could not translate address %s"
                                % address)
                            return ImmediateExceptionFuture(error)

                        factory = self._reactor.connection_factory
                        connection = factory(
                            self,
                            self._connection_id_generator.get_and_increment(),
                            translated,
                            self._client.config,
                            self._invocation_service.handle_client_message,
                        )
                    except IOError:
                        error = sys.exc_info()
                        return ImmediateExceptionFuture(error[1], error[2])

                    future = self._authenticate(connection).continue_with(
                        self._on_auth, connection, address)
                    self._pending_connections[address] = future
                    return future
Пример #13
0
    def get_or_create_unique_thread_id(self, group_id):
        with self._lock:
            if self._shutdown:
                error = HazelcastClientNotActiveError(
                    "Session manager is already shut down!")
                return ImmediateExceptionFuture(error)

            key = (group_id, thread_id())
            global_thread_id = self._thread_ids.get(key)
            if global_thread_id:
                return ImmediateFuture(global_thread_id)

            return self._request_generate_thread_id(group_id).continue_with(
                lambda t_id: self._thread_ids.setdefault(key, t_id.result()))
    def prepare_acquire_session(self, session_id, err=None):
        if err:
            val = ImmediateExceptionFuture(err)
        else:
            val = ImmediateFuture(session_id)

        acquire_mock = MagicMock(return_value=val)
        release_mock = MagicMock()
        invalidate_mock = MagicMock()
        self.session_manager.acquire_session = acquire_mock
        self.session_manager.release_session = release_mock
        self.session_manager.invalidate_session = invalidate_mock
        self.acquire_session = acquire_mock
        self.release_session = release_mock
        self.invalidate_session = invalidate_mock
Пример #15
0
    def test_heartbeat_on_failure(self):
        reactor = self.mock_reactor()
        self.mock_request_new_session()
        self.manager._request_heartbeat = MagicMock(
            return_value=ImmediateExceptionFuture(SessionExpiredError()))

        m = MagicMock(side_effect=self.manager.invalidate_session)
        self.manager.invalidate_session = m

        self.manager.acquire_session(self.raft_group_id, 1).result()
        time.sleep(2)
        self.manager.shutdown()
        reactor.shutdown()
        self.assertGreater(self.context.reactor.add_timer.call_count,
                           1)  # assert that the heartbeat task is executed
        m.assert_called_once_with(self.raft_group_id, self.session_id)
        self.assertEqual(0, len(self.manager._sessions))
Пример #16
0
    def release(self, permits=1):
        check_true(permits > 0, "Permits must be positive")
        session_id = self._get_session_id()
        if session_id == _NO_SESSION_ID:
            return ImmediateExceptionFuture(self._new_illegal_state_error())

        current_thread_id = thread_id()
        invocation_uuid = uuid.uuid4()

        def check_response(response):
            try:
                response.result()
            except SessionExpiredError as e:
                self._invalidate_session(session_id)
                raise self._new_illegal_state_error(e)
            finally:
                self._release_session(session_id, permits)

        return self._request_release(session_id, current_thread_id, invocation_uuid, permits).continue_with(
            check_response)
Пример #17
0
    def get_or_connect(self, address, authenticator=None):
        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:
                        connection = self._new_connection_func(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)
                    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
 def prepare_thread_id(self, thread_id, err=None):
     if err:
         value = ImmediateExceptionFuture(err)
     else:
         value = ImmediateFuture(thread_id)
     self.session_manager.get_or_create_unique_thread_id = MagicMock(return_value=value)
Пример #19
0
 def mock(expected_round, invocation_uuid):
     if called_count.get_and_increment() < 2:
         return ImmediateExceptionFuture(OperationTimeoutError("xx"))
     return original(expected_round, invocation_uuid)
 def read_many_mock(*_):
     if next(counter) == 0:
         return ImmediateExceptionFuture(error)
     return Future()
 def mock(*_, **__):
     if called.get_and_increment() == 0 and first_call_err:
         return ImmediateExceptionFuture(first_call_err)
     return ImmediateFuture(result)
Пример #22
0
    def execute(self, sql, params, cursor_buffer_size, timeout,
                expected_result_type, schema):
        """Constructs a statement and executes it.

        Args:
            sql (str): SQL string.
            params (tuple): Query parameters.
            cursor_buffer_size (int): Cursor buffer size.
            timeout (float): Timeout of the query.
            expected_result_type (SqlExpectedResultType): Expected result type
                of the query.
            schema (str or None): The schema name.

        Returns:
            hazelcast.future.Future[SqlResult]: The execution result.
        """
        statement = _SqlStatement(sql, params, cursor_buffer_size, timeout,
                                  expected_result_type, schema)

        connection = None
        try:
            try:
                # Serialize the passed parameters.
                serialized_params = [
                    self._serialization_service.to_data(param)
                    for param in statement.parameters
                ]
            except SchemaNotReplicatedError as e:
                return self._send_schema_and_retry_fn(
                    e,
                    self.execute,
                    sql,
                    params,
                    cursor_buffer_size,
                    timeout,
                    expected_result_type,
                    schema,
                )

            connection = self._get_query_connection()
            # Create a new, unique query id.
            query_id = _SqlQueryId.from_uuid(connection.remote_uuid)

            request = sql_execute_codec.encode_request(
                statement.sql,
                serialized_params,
                # to_millis expects None to produce -1
                to_millis(None if statement.timeout ==
                          -1 else statement.timeout),
                statement.cursor_buffer_size,
                statement.schema,
                statement.expected_result_type,
                query_id,
                False,
            )

            invocation = Invocation(
                request,
                connection=connection,
                response_handler=sql_execute_codec.decode_response)
            self._invocation_service.invoke(invocation)
            return invocation.future.continue_with(lambda future: SqlResult(
                self,
                connection,
                query_id,
                statement.cursor_buffer_size,
                self._handle_execute_response(future, connection),
            ))
        except Exception as e:
            return ImmediateExceptionFuture(self.re_raise(e, connection))