Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hazelcast/protocol/codec/map_message_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@
MAP_VALUESWITHPAGINGPREDICATE = 0x0139
MAP_ENTRIESWITHPAGINGPREDICATE = 0x013a
MAP_CLEARNEARCACHE = 0x013b
MAP_SETTTL = 0x0149
40 changes: 40 additions & 0 deletions hazelcast/protocol/codec/map_set_ttl_codec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from hazelcast.serialization.bits import *
from hazelcast.protocol.client_message import ClientMessage
from hazelcast.protocol.custom_codec import *
from hazelcast.util import ImmutableLazyDataList
from hazelcast.protocol.codec.map_message_type import *

REQUEST_TYPE = MAP_SETTTL
RESPONSE_TYPE = 101
RETRYABLE = False


def calculate_size(name, key, ttl):
""" Calculates the request payload size"""
data_size = 0
data_size += calculate_size_str(name)
data_size += calculate_size_data(key)
data_size += LONG_SIZE_IN_BYTES
return data_size


def encode_request(name, key, ttl):
""" Encode request into client_message"""
client_message = ClientMessage(payload_size=calculate_size(name, key, ttl))
client_message.set_message_type(REQUEST_TYPE)
client_message.set_retryable(RETRYABLE)
client_message.append_str(name)
client_message.append_data(key)
client_message.append_long(ttl)
client_message.update_frame_length()
return client_message


def decode_response(client_message, to_object=None):
""" Decode response from client message"""
parameters = dict(response=None)
parameters['response'] = client_message.read_bool()
return parameters



30 changes: 26 additions & 4 deletions hazelcast/proxy/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
map_is_locked_codec, map_key_set_codec, map_key_set_with_predicate_codec, map_load_all_codec, \
map_load_given_keys_codec, map_lock_codec, map_put_codec, map_put_all_codec, map_put_if_absent_codec, \
map_put_transient_codec, map_size_codec, map_remove_codec, map_remove_if_same_codec, \
map_remove_entry_listener_codec, map_replace_codec, map_replace_if_same_codec, map_set_codec, map_try_lock_codec, \
map_try_put_codec, map_try_remove_codec, map_unlock_codec, map_values_codec, map_values_with_predicate_codec, \
map_add_interceptor_codec, map_execute_on_all_keys_codec, map_execute_on_key_codec, map_execute_on_keys_codec, \
map_execute_with_predicate_codec, map_add_near_cache_entry_listener_codec
map_remove_entry_listener_codec, map_replace_codec, map_replace_if_same_codec, map_set_codec, map_set_ttl_codec, \
map_try_lock_codec, map_try_put_codec, map_try_remove_codec, map_unlock_codec, map_values_codec, \
map_values_with_predicate_codec, map_add_interceptor_codec, map_execute_on_all_keys_codec, map_execute_on_key_codec, \
map_execute_on_keys_codec, map_execute_with_predicate_codec, map_add_near_cache_entry_listener_codec
from hazelcast.proxy.base import Proxy, EntryEvent, EntryEventType, get_entry_listener_flags, MAX_SIZE
from hazelcast.util import check_not_none, thread_id, to_millis
from hazelcast import six
Expand Down Expand Up @@ -725,6 +725,21 @@ def set(self, key, value, ttl=-1):
value_data = self._to_data(value)
return self._set_internal(key_data, value_data, ttl)

def set_ttl(self, key, ttl):
"""
Updates the TTL (time to live) value of the entry specified by the given key with a new TTL value. New TTL
value is valid starting from the time this operation is invoked, not since the time the entry was created.
If the entry does not exist or is already expired, this call has no effect.

:param key: (object), the key of the map entry.
:param ttl: (int), maximum time for this entry to stay in the map (0 means infinite,
negative means map config default)
"""
check_not_none(key, "key can't be None")
check_not_none(ttl, "ttl can't be None")
key_data = self._to_data(key)
return self._set_ttl_internal(key_data, ttl)

def size(self):
"""
Returns the number of entries in this map.
Expand Down Expand Up @@ -861,6 +876,9 @@ def _set_internal(self, key_data, value_data, ttl):
return self._encode_invoke_on_key(map_set_codec, key_data, key=key_data, value=value_data, thread_id=thread_id(),
ttl=to_millis(ttl))

def _set_ttl_internal(self, key_data, ttl):
return self._encode_invoke_on_key(map_set_ttl_codec, key_data, key=key_data, ttl=to_millis(ttl))

def _try_remove_internal(self, key_data, timeout):
return self._encode_invoke_on_key(map_try_remove_codec, key_data, key=key_data, thread_id=thread_id(),
timeout=to_millis(timeout))
Expand Down Expand Up @@ -1007,6 +1025,10 @@ def _set_internal(self, key_data, value_data, ttl):
self._invalidate_cache(key_data)
return super(MapFeatNearCache, self)._set_internal(key_data, value_data, ttl)

def _set_ttl_internal(self, key_data, ttl):
self._invalidate_cache(key_data)
return super(MapFeatNearCache, self)._set_ttl_internal(key_data, ttl)

def _replace_internal(self, key_data, value_data):
self._invalidate_cache(key_data)
return super(MapFeatNearCache, self)._replace_internal(key_data, value_data)
Expand Down
9 changes: 9 additions & 0 deletions tests/proxy/map_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,15 @@ def test_set(self):
self.map.set("key", "value")

self.assertEqual(self.map.get("key"), "value")

def test_set_ttl(self):
self.map.put("key", "value")
self.map.set_ttl("key", 0.1)

def evicted():
self.assertFalse(self.map.contains_key("key"))

self.assertTrueEventually(evicted, 1)

def test_size(self):
self._fill_map()
Expand Down