def sql(self, sql): check_true(isinstance(sql, str), "SQL must be a string") if not sql.strip(): raise ValueError("SQL cannot be empty") self._sql = sql
def try_acquire(self, permits=1, timeout=0): check_true(permits > 0, "Permits must be positive") timeout = max(0, timeout) current_thread_id = thread_id() invocation_uuid = uuid.uuid4() return self._do_try_acquire(current_thread_id, invocation_uuid, permits, timeout)
def acquire(self, permits=1): check_true(permits > 0, "Permits must be positive") def handler(f): f.result() return None return self._get_thread_id().continue_with(self._do_try_acquire, permits, -1).continue_with(handler)
def _get_object_name_for_proxy(name): idx = name.find("@") if idx == -1: return name group_name = name[idx + 1 :].strip() check_true(len(group_name) > 0, "Custom CP group name cannot be empty string") object_name = name[:idx].strip() check_true(len(object_name) > 0, "Object name cannot be empty string") return object_name
def check_capacity(capacity): try: capacity = capacity.result() check_true( min_count <= capacity, "min count: %d should be smaller or equal to capacity: %d" % (min_count, capacity)) f = self._invoke(request, handler) f.add_done_callback(set_result) except Exception as e: future.set_exception(e)
def read_many(self, start_sequence, min_count, max_count): """Reads a batch of items from the Ringbuffer. If the number of available items after the first read item is smaller than the max_count, these items are returned. So it could be the number of items read is smaller than the max_count. If there are less items available than min_count, then this call blocks. Reading a batch of items is likely to perform better because less overhead is involved. Args: start_sequence (int): The start_sequence of the first item to read. min_count (int): The minimum number of items to read. max_count (int): The maximum number of items to read. Returns: hazelcast.future.Future[list]: The list of read items. """ check_not_negative(start_sequence, "sequence can't be smaller than 0") check_true(max_count >= min_count, "max count should be greater or equal to min count") check_true(max_count < MAX_BATCH_SIZE, "max count can't be greater than %d" % MAX_BATCH_SIZE) future = Future() request = ringbuffer_read_many_codec.encode_request( self.name, start_sequence, min_count, max_count, None) def handler(message): return ImmutableLazyDataList( ringbuffer_read_many_codec.decode_response(message)["items"], self._to_object) def check_capacity(capacity): try: capacity = capacity.result() check_true( min_count <= capacity, "min count: %d should be smaller or equal to capacity: %d" % (min_count, capacity), ) f = self._invoke(request, handler) f.add_done_callback(set_result) except Exception as e: future.set_exception(e) def set_result(f): try: future.set_result(f.result()) except Exception as e: future.set_exception(e) self.capacity().add_done_callback(check_capacity) return future
def continuation(future): # Since the first call to capacity # is cached on the client-side, doing # a capacity check each time should not # be a problem capacity = future.result() check_true( max_count <= capacity, "max count: %d should be smaller or equal to capacity: %d" % (max_count, capacity), ) return self._invoke(request, handler)
def _without_default_group_name(name): name = name.strip() idx = name.find("@") if idx == -1: return name check_true( name.find("@", idx + 1) == -1, "Custom group name must be specified at most once") group_name = name[idx + 1:].strip() if group_name == _DEFAULT_GROUP_NAME: return name[:idx] return name
def _without_default_group_name(name): name = name.strip() idx = name.find("@") if idx == -1: return name check_true(name.find("@", idx + 1) == -1, "Custom group name must be specified at most once") group_name = name[idx + 1 :].strip() check_true( group_name.lower() != _METADATA_CP_GROUP_NAME, "CP data structures cannot run on the METADATA CP group!", ) if group_name.lower() == _DEFAULT_GROUP_NAME: return name[:idx] return name
def find_column(self, column_name: str) -> int: """ Args: column_name: Name of the column. Returns: Column index or :const:`COLUMN_NOT_FOUND` if a column with the given name is not found. Raises: AssertionError: If the column name is not a string. """ check_true(isinstance(column_name, str), "Column name must be a string") return self._name_to_index.get(column_name, SqlRowMetadata.COLUMN_NOT_FOUND)
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)
def try_set_count(self, count): """Sets the count to the given value if the current count is zero. If count is not zero, then this method does nothing and returns ``False``. Args: count (int): The number of times ``count_down()`` must be invoked before callers can pass through ``await_latch()``. Returns: hazelcast.future.Future[bool]: ``True`` if the new count was set, ``False`` if the current count is not zero. """ check_is_int(count) check_true(count > 0, "Count must be positive") codec = count_down_latch_try_set_count_codec request = codec.encode_request(self._group_id, self._object_name, count) return self._invoke(request, codec.decode_response)
def read_many(self, start_sequence, min_count, max_count): """ Reads a batch of items from the Ringbuffer. If the number of available items after the first read item is smaller than the max_count, these items are returned. So it could be the number of items read is smaller than the max_count. If there are less items available than min_count, then this call blocks. Reading a batch of items is likely to perform better because less overhead is involved. :param start_sequence: (long), the start_sequence of the first item to read. :param min_count: (int), the minimum number of items to read. :param max_count: (int), the maximum number of items to read. :return: (Sequence), the list of read items. """ check_not_negative(start_sequence, "sequence can't be smaller than 0") check_true(max_count >= min_count, "max count should be greater or equal to min count") check_true(min_count <= self.capacity().result(), "min count should be smaller or equal to capacity") check_true(max_count < MAX_BATCH_SIZE, "max count can't be greater than %d" % MAX_BATCH_SIZE) return self._encode_invoke( ringbuffer_read_many_codec, response_handler=self._read_many_response_handler, start_sequence=start_sequence, min_count=min_count, max_count=max_count, filter=None)
def read_many(self, start_sequence, min_count, max_count): check_not_negative(start_sequence, "sequence can't be smaller than 0") check_true(max_count >= min_count, "max count should be greater or equal to min count") check_true(min_count <= self.capacity().result(), "min count should be smaller or equal to capacity") check_true(max_count < MAX_BATCH_SIZE, "max count can't be greater than %d" % MAX_BATCH_SIZE) return self._encode_invoke( ringbuffer_read_many_codec, response_handler=self._read_many_response_handler, start_sequence=start_sequence, min_count=min_count, max_count=max_count, filter=None, )
def read_many(self, start_sequence, min_count, max_count): check_not_negative(start_sequence, "sequence can't be smaller than 0") check_true(max_count >= min_count, "max count should be greater or equal to min count") check_true(min_count <= self.capacity().result(), "min count should be smaller or equal to capacity") check_true(max_count < MAX_BATCH_SIZE, "max count can't be greater than %d" % MAX_BATCH_SIZE) return self._encode_invoke( ringbuffer_read_many_codec, response_handler=self._read_many_response_handler, start_sequence=start_sequence, min_count=min_count, max_count=max_count, filter=None)
def schema(self, schema): check_true( isinstance(schema, str) or schema is None, "Schema must be a string or None", ) self._schema = schema
def try_acquire(self, permits=1, timeout=0): check_true(permits > 0, "Permits must be positive") timeout = max(0, timeout) return self._get_thread_id().continue_with(self._do_try_acquire, permits, timeout)
def release(self, permits=1): check_true(permits > 0, "Permits must be positive") invocation_uuid = uuid.uuid4() return self._get_thread_id().continue_with(self._request_release, invocation_uuid, permits)
def read_many( self, start_sequence: int, min_count: int, max_count: int, filter: typing.Any = None ) -> Future[ReadResult]: """Reads a batch of items from the Ringbuffer. If the number of available items after the first read item is smaller than the ``max_count``, these items are returned. So it could be the number of items read is smaller than the ``max_count``. If there are less items available than ``min_count``, then this call blocks. Warnings: These blocking calls consume server memory and if there are many calls, it can be possible to see leaking memory or ``OutOfMemoryError`` s on the server. Reading a batch of items is likely to perform better because less overhead is involved. A filter can be provided to only select items that need to be read. If the filter is ``None``, all items are read. If the filter is not ``None``, only items where the filter function returns true are returned. Using filters is a good way to prevent getting items that are of no value to the receiver. This reduces the amount of IO and the number of operations being executed, and can result in a significant performance improvement. Note that, filtering logic must be defined on the server-side. If the ``start_sequence`` is smaller than the smallest sequence still available in the Ringbuffer (:func:`head_sequence`), then the smallest available sequence will be used as the start sequence and the minimum/maximum number of items will be attempted to be read from there on. If the ``start_sequence`` is bigger than the last available sequence in the Ringbuffer (:func:`tail_sequence`), then the last available sequence plus one will be used as the start sequence and the call will block until further items become available and it can read at least the minimum number of items. Args: start_sequence: The start sequence of the first item to read. min_count: The minimum number of items to read. max_count: The maximum number of items to read. filter: Filter to select returned elements. Returns: The list of read items. """ check_not_negative(start_sequence, "sequence can't be smaller than 0") check_not_negative(min_count, "min count can't be smaller than 0") check_true(max_count >= min_count, "max count should be greater or equal to min count") check_true( max_count < MAX_BATCH_SIZE, "max count can't be greater than %d" % MAX_BATCH_SIZE ) try: filter_data = self._to_data(filter) except SchemaNotReplicatedError as e: return self._send_schema_and_retry( e, self.read_many, start_sequence, min_count, max_count, filter ) request = ringbuffer_read_many_codec.encode_request( self.name, start_sequence, min_count, max_count, filter_data ) def handler(message): response = ringbuffer_read_many_codec.decode_response(message) read_count = response["read_count"] next_seq = response["next_seq"] items = response["items"] item_seqs = response["item_seqs"] return ReadResult(read_count, next_seq, items, item_seqs, self._to_object) def continuation(future): # Since the first call to capacity # is cached on the client-side, doing # a capacity check each time should not # be a problem capacity = future.result() check_true( max_count <= capacity, "max count: %d should be smaller or equal to capacity: %d" % (max_count, capacity), ) return self._invoke(request, handler) return self.capacity().continue_with(continuation)
def acquire(self, permits=1): check_true(permits > 0, "Permits must be positive") current_thread_id = thread_id() invocation_uuid = uuid.uuid4() return self._do_acquire(current_thread_id, invocation_uuid, permits)