def test_invocation_timeout(self): invocation_service = self.client.invoker invocation = Invocation(invocation_service, None, partition_id=-1) def mocked_has_partition_id(): time.sleep(2) return True invocation.has_partition_id = mocked_has_partition_id with self.assertRaises(TimeoutError): invocation_service.invoke(invocation).result()
def _request_generate_thread_id(self, group_id): codec = cp_session_generate_thread_id_codec request = codec.encode_request(group_id) invocation = Invocation(request, response_handler=codec.decode_response) self._context.invocation_service.invoke(invocation) return invocation.future
def _register_on_connection(self, user_registration_id, listener_registration, connection): registration_map = listener_registration.connection_registrations if connection in registration_map: return registration_request = listener_registration.registration_request.copy( ) invocation = Invocation(registration_request, connection=connection, event_handler=listener_registration.handler, response_handler=lambda m: m, urgent=True) self._invocation_service.invoke(invocation) def callback(f): try: response = f.result() server_registration_id = listener_registration.decode_register_response( response) correlation_id = registration_request.get_correlation_id() registration = _EventRegistration(server_registration_id, correlation_id) registration_map[connection] = registration except Exception as e: if connection.live: _logger.exception( "Listener %s can not be added to a new connection: %s", user_registration_id, connection) raise e return invocation.future.continue_with(callback)
def _invoke_on_key(self, request, key_data, response_handler=_no_op_response_handler): partition_id = self._partition_service.get_partition_id(key_data) invocation = Invocation( request, partition_id=partition_id, response_handler=response_handler ) self._invocation_service.invoke(invocation) return invocation.future
def begin(self): """ Begins this transaction. """ if hasattr(self._locals, 'transaction_exists') and self._locals.transaction_exists: raise TransactionError("Nested transactions are not allowed.") if self.state != _STATE_NOT_STARTED: raise TransactionError("Transaction has already been started.") self._locals.transaction_exists = True self.start_time = time.time() self.thread_id = thread_id() try: request = transaction_create_codec.encode_request( timeout=int(self.timeout * 1000), durability=self.durability, transaction_type=self.transaction_type, thread_id=self.thread_id) invocation = Invocation(request, connection=self.connection, response_handler=lambda m: m) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) response = invocation.future.result() self.id = transaction_create_codec.decode_response(response) self.state = _STATE_ACTIVE except: self._locals.transaction_exists = False raise
def _authenticate(self, connection): client = self._client cluster_name = self._config.cluster_name client_name = client.name if self._config.token_provider: token = self._config.token_provider.token( connection.connected_address) request = client_authentication_custom_codec.encode_request( cluster_name, token, self.client_uuid, CLIENT_TYPE, SERIALIZATION_VERSION, __version__, client_name, self._labels, ) else: request = client_authentication_codec.encode_request( cluster_name, self._config.creds_username, self._config.creds_password, self.client_uuid, CLIENT_TYPE, SERIALIZATION_VERSION, __version__, client_name, self._labels, ) invocation = Invocation(request, connection=connection, urgent=True, response_handler=lambda m: m) self._invocation_service.invoke(invocation) return invocation.future
def _get_group_id(self, proxy_name): codec = cp_group_create_cp_group_codec request = codec.encode_request(proxy_name) invocation = Invocation(request, response_handler=codec.decode_response) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) return invocation.future.result()
def _try_register(self, connection): if not self._connection_manager.live: # There is no point on trying the register a backup listener # if the client is about to shutdown. return if self._listener_added_connection: return self._listener_added_connection = connection request = client_add_cluster_view_listener_codec.encode_request() invocation = Invocation(request, connection=connection, event_handler=self._handler(connection), urgent=True) self._cluster_service.clear_member_list_version() self._invocation_service.invoke(invocation) def callback(f): try: f.result() except: self._try_register_to_random_connection(connection) invocation.future.add_done_callback(callback)
def _request_new_session(self, group_id): codec = cp_session_create_session_codec request = codec.encode_request(group_id, self._context.name) invocation = Invocation(request, response_handler=codec.decode_response) self._context.invocation_service.invoke(invocation) return invocation.future
def get_distributed_objects(self): """Returns all distributed objects such as; queue, map, set, list, topic, lock, multimap. Also, as a side effect, it clears the local instances of the destroyed proxies. Returns: list[hazelcast.proxy.base.Proxy]: List of instances created by Hazelcast. """ request = client_get_distributed_objects_codec.encode_request() invocation = Invocation(request, response_handler=lambda m: m) self._invocation_service.invoke(invocation) local_distributed_object_infos = { DistributedObjectInfo(dist_obj.service_name, dist_obj.name) for dist_obj in self._proxy_manager.get_distributed_objects() } response = client_get_distributed_objects_codec.decode_response( invocation.future.result()) for dist_obj_info in response: local_distributed_object_infos.discard(dist_obj_info) self._proxy_manager.get_or_create(dist_obj_info.service_name, dist_obj_info.name, create_on_remote=False) for dist_obj_info in local_distributed_object_infos: self._proxy_manager.destroy_proxy(dist_obj_info.service_name, dist_obj_info.name, destroy_on_remote=False) return self._proxy_manager.get_distributed_objects()
def _invoke_on_target(self, request, uuid, response_handler=_no_op_response_handler): invocation = Invocation(request, uuid=uuid, response_handler=response_handler) self._invocation_service.invoke(invocation) return invocation.future
def _invoke_on_partition(self, request, partition_id, response_handler=_no_op_response_handler): invocation = Invocation(request, partition_id=partition_id, response_handler=response_handler) self._invocation_service.invoke(invocation) return invocation.future
def _create_proxy(self, service_name, name, create_on_remote): if create_on_remote: request = client_create_proxy_codec.encode_request(name, service_name) invocation = Invocation(request) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) invocation.future.result() return _proxy_init[service_name](service_name, name, self._context)
def test_invocation_not_timed_out_when_there_is_no_exception(self): request = OutboundMessage(bytearray(22), True) invocation_service = self.client._invocation_service invocation = Invocation(request) invocation_service.invoke(invocation) time.sleep(2) self.assertFalse(invocation.future.done()) self.assertEqual(1, len(invocation_service._pending))
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))
def deregister_listener(self, user_registration_id): check_not_none(user_registration_id, "None user_registration_id is not allowed!") with self._registration_lock: listener_registration = self._active_registrations.pop( user_registration_id, None) if not listener_registration: return ImmediateFuture(False) futures = [] for ( connection, event_registration, ) in listener_registration.connection_registrations.items(): # Remove local handler self.remove_event_handler(event_registration.correlation_id) # The rest is for deleting the remote registration server_registration_id = event_registration.server_registration_id deregister_request = listener_registration.encode_deregister_request( server_registration_id) if deregister_request is None: # None means no remote registration (e.g. for backup acks) continue invocation = Invocation(deregister_request, connection=connection, timeout=sys.maxsize, urgent=True) self._invocation_service.invoke(invocation) def handler(f, captured_connection=connection): e = f.exception() if not e: return if isinstance(e, (HazelcastClientNotActiveError, IOError, TargetDisconnectedError)): return _logger.warning( "Deregistration of listener with ID %s has failed for address %s: %s", user_registration_id, captured_connection.remote_address, e, ) invocation.future.add_done_callback(handler) futures.append(invocation.future) listener_registration.connection_registrations.clear() return combine_futures(futures).continue_with(lambda _: True)
def send_all_schemas(self) -> Future: schemas = self._compact_serializer.get_schemas() if not schemas: _logger.debug("There is no schema to send to the cluster.") return ImmediateFuture(None) _logger.debug("Sending the following schemas to the cluster: %s", schemas) request = client_send_all_schemas_codec.encode_request(schemas) invocation = Invocation(request, urgent=True) self._invocation_service.invoke(invocation) return invocation.future
def fetch_schema(self, schema_id: int) -> Future: _logger.debug( "Could not find schema with the id %s locally. It will be fetched from the cluster.", schema_id, ) request = client_fetch_schema_codec.encode_request(schema_id) fetch_schema_invocation = Invocation( request, response_handler=client_fetch_schema_codec.decode_response, ) self._invocation_service.invoke(fetch_schema_invocation) return fetch_schema_invocation.future
def destroy_proxy(self, service_name, name, destroy_on_remote=True): ns = (service_name, name) try: self._proxies.pop(ns) if destroy_on_remote: request = client_destroy_proxy_codec.encode_request(name, service_name) invocation = Invocation(request) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) invocation.future.result() return True except KeyError: return False
def _authenticate(self, connection): client = self._client cluster_name = client.config.cluster_name client_name = client.name request = client_authentication_codec.encode_request( cluster_name, None, None, self.client_uuid, CLIENT_TYPE, SERIALIZATION_VERSION, __version__, client_name, self._labels) invocation = Invocation(request, connection=connection, urgent=True, response_handler=lambda m: m) self._invocation_service.invoke(invocation) return invocation.future
def test_invocation_timeout(self): request = OutboundMessage(bytearray(22), True) invocation_service = self.client._invocation_service invocation = Invocation(request, partition_id=1) def mock(*_): time.sleep(2) return False invocation_service._invoke_on_partition_owner = mock invocation_service._invoke_on_random_connection = lambda _: False invocation_service.invoke(invocation) with self.assertRaises(HazelcastTimeoutError): invocation.future.result()
def test_invocation_timeout(self): request = OutboundMessage(bytearray(22), True) invocation_service = self.client._invocation_service invocation = Invocation(request, partition_id=1) def mock(*_): time.sleep(2) return False invocation_service._invoke_on_partition_owner = MagicMock(side_effect=mock) invocation_service._invoke_on_random_connection = MagicMock(return_value=False) invocation_service.invoke(invocation) with self.assertRaises(OperationTimeoutError): invocation.future.result()
def _create_semaphore(self, group_id, proxy_name, object_name): codec = semaphore_get_semaphore_type_codec request = codec.encode_request(proxy_name) invocation = Invocation(request, response_handler=codec.decode_response) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) jdk_compatible = invocation.future.result() if jdk_compatible: return SessionlessSemaphore( self._context, group_id, SEMAPHORE_SERVICE, proxy_name, object_name ) else: return SessionAwareSemaphore( self._context, group_id, SEMAPHORE_SERVICE, proxy_name, object_name )
def _check_connection(self, now, connection): if not connection.live: return if (now - connection.last_read_time) > self._heartbeat_timeout: _logger.warning("Heartbeat failed over the connection: %s", connection) connection.close( "Heartbeat timed out", TargetDisconnectedError("Heartbeat timed out to connection %s" % connection), ) return if (now - connection.last_write_time) > self._heartbeat_interval: request = client_ping_codec.encode_request() invocation = Invocation(request, connection=connection, urgent=True) self._invocation_service.invoke(invocation)
def rollback(self): """Rollback of this current transaction.""" self._check_thread() if self.state not in (_STATE_ACTIVE, _STATE_PARTIAL_COMMIT): raise TransactionError("Transaction is not active.") try: if self.state != _STATE_PARTIAL_COMMIT: request = transaction_rollback_codec.encode_request( self.id, self.thread_id) invocation = Invocation(request, connection=self.connection) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) invocation.future.result() self.state = _STATE_ROLLED_BACK finally: self._locals.transaction_exists = False
def close(self, connection, query_id): """Closes the remote query cursor. Args: connection (hazelcast.connection.Connection): Connection that the first execute request, hence the close request must route to. query_id (_SqlQueryId): The query id to close. Returns: Future: """ request = sql_close_codec.encode_request(query_id) invocation = Invocation(request, connection=connection) self._invocation_service.invoke(invocation) return invocation.future
def commit(self): """Commits this transaction.""" self._check_thread() if self.state != _STATE_ACTIVE: raise TransactionError("Transaction is not active.") try: self._check_timeout() request = transaction_commit_codec.encode_request( self.id, self.thread_id) invocation = Invocation(request, connection=self.connection) invocation_service = self._context.invocation_service invocation_service.invoke(invocation) invocation.future.result() self.state = _STATE_COMMITTED except: self.state = _STATE_PARTIAL_COMMIT raise finally: self._locals.transaction_exists = False
def send_schema_and_retry( self, error: SchemaNotReplicatedError, func: typing.Callable[..., Future], *args: typing.Any, **kwargs: typing.Any, ) -> Future: schema = error.schema clazz = error.clazz request = client_send_schema_codec.encode_request(schema) invocation = Invocation(request) def continuation(future): future.result() self._compact_serializer.register_schema_to_type(schema, clazz) return func(*args, **kwargs) self._invocation_service.invoke(invocation) return invocation.future.continue_with(continuation)
def _try_register(self, connection): if self._listener_added_connection: return self._cluster_service.clear_member_list_version() self._listener_added_connection = connection request = client_add_cluster_view_listener_codec.encode_request() invocation = Invocation(request, connection=connection, event_handler=self._handler(connection), urgent=True) self._invocation_service.invoke(invocation) def callback(f): try: f.result() except: self._try_register_to_random_connection(connection) invocation.future.add_done_callback(callback)
def fetch(self, connection, query_id, cursor_buffer_size): """Fetches the next page of the query execution. Args: connection (hazelcast.connection.Connection): Connection that the first execute request, hence the fetch request must route to. query_id (_SqlQueryId): Unique id of the query. cursor_buffer_size (int): Size of cursor buffer. Same as the one used in the first execute request. Returns: Future: Decoded fetch response. """ request = sql_fetch_codec.encode_request(query_id, cursor_buffer_size) invocation = Invocation( request, connection=connection, response_handler=sql_fetch_codec.decode_response) self._invocation_service.invoke(invocation) return invocation.future