Skip to content

Commit 03b9f1d

Browse files
authored
Go over the default time values (#260)
- Validated the default time values with the Java client. We were sending -1 second for unset values, however the server was expecting -1 millisecond. - Updated some parameter names or docstrings to make them more clear. - Implemented support for max idle in map `put`, `put_transient`, `put_if_absent` and `set`. Also added some basic tests. - Made queue `add` to return `IllegalStateError` to make it more consistent with other clients.
1 parent ce5ec71 commit 03b9f1d

File tree

7 files changed

+212
-71
lines changed

7 files changed

+212
-71
lines changed

hazelcast/proxy/map.py

Lines changed: 92 additions & 48 deletions
Large diffs are not rendered by default.

hazelcast/proxy/multi_map.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def handler(message):
211211
request = multi_map_key_set_codec.encode_request(self.name)
212212
return self._invoke(request, handler)
213213

214-
def lock(self, key, lease_time=-1):
214+
def lock(self, key, lease_time=None):
215215
"""Acquires the lock for the specified key infinitely or for the specified lease time if provided.
216216
217217
If the lock is not available, the current thread becomes disabled for thread scheduling purposes and lies
@@ -365,19 +365,19 @@ def handler(message):
365365
request = multi_map_values_codec.encode_request(self.name)
366366
return self._invoke(request, handler)
367367

368-
def try_lock(self, key, lease_time=-1, timeout=-1):
368+
def try_lock(self, key, lease_time=None, timeout=0):
369369
"""Tries to acquire the lock for the specified key.
370370
371371
When the lock is not available:
372372
373-
- If timeout is not provided, the current thread doesn't wait and returns ``false`` immediately.
374-
- If a timeout is provided, the current thread becomes disabled for thread scheduling purposes and lies
373+
- If the timeout is not provided, the current thread doesn't wait and returns ``False`` immediately.
374+
- If the timeout is provided, the current thread becomes disabled for thread scheduling purposes and lies
375375
dormant until one of the followings happens:
376376
377-
- the lock is acquired by the current thread, or
378-
- the specified waiting time elapses.
377+
- The lock is acquired by the current thread, or
378+
- The specified waiting time elapses.
379379
380-
If lease_time is provided, lock will be released after this time elapses.
380+
If the lease time is provided, lock will be released after this time elapses.
381381
382382
Args:
383383
key: Key to lock in this map.

hazelcast/proxy/queue.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from hazelcast.errors import IllegalStateError
12
from hazelcast.protocol.codec import \
23
queue_add_all_codec, \
34
queue_add_listener_codec, \
@@ -22,14 +23,6 @@
2223
from hazelcast.util import check_not_none, to_millis, ImmutableLazyDataList
2324

2425

25-
class Empty(Exception):
26-
pass
27-
28-
29-
class Full(Exception):
30-
pass
31-
32-
3326
class Queue(PartitionSpecificProxy):
3427
"""Concurrent, blocking, distributed, observable queue.
3528
@@ -48,7 +41,7 @@ def add(self, item):
4841
def result_fnc(f):
4942
if f.result():
5043
return True
51-
raise Full("Queue is full!")
44+
raise IllegalStateError("Queue is full!")
5245

5346
return self.offer(item).continue_with(result_fnc)
5447

@@ -192,8 +185,8 @@ def offer(self, item, timeout=0):
192185
193186
If there is no space currently available:
194187
195-
- If a timeout is provided, it waits until this timeout elapses and returns the result.
196-
- If a timeout is not provided, returns ``False`` immediately.
188+
- If the timeout is provided, it waits until this timeout elapses and returns the result.
189+
- If the timeout is not provided, returns ``False`` immediately.
197190
198191
Args:
199192
item: The item to be added.
@@ -224,8 +217,8 @@ def poll(self, timeout=0):
224217
225218
If this queue is empty:
226219
227-
- If a timeout is provided, it waits until this timeout elapses and returns the result.
228-
- If a timeout is not provided, returns ``None``.
220+
- If the timeout is provided, it waits until this timeout elapses and returns the result.
221+
- If the timeout is not provided, returns ``None``.
229222
230223
Args:
231224
timeout (int): Maximum time in seconds to wait for addition.

hazelcast/proxy/transactional_map.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def is_empty(self):
8787
request = transactional_map_is_empty_codec.encode_request(self.name, self.transaction.id, thread_id())
8888
return self._invoke(request, transactional_map_is_empty_codec.decode_response)
8989

90-
def put(self, key, value, ttl=-1):
90+
def put(self, key, value, ttl=None):
9191
"""Transactional implementation of :func:`Map.put(key, value, ttl) <hazelcast.proxy.map.Map.put>`
9292
9393
The object to be put will be accessible only in the current transaction context till the transaction is

hazelcast/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ def thread_id():
5555

5656

5757
def to_millis(seconds):
58+
if seconds is None:
59+
return -1
5860
return int(seconds * MILLISECONDS_IN_SECONDS)
5961

6062

tests/proxy/map_test.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,105 @@ def assert_event():
591591
self.assertEntryEvent(event, key='key', value='value', event_type=EntryEventType.LOADED)
592592

593593
self.assertTrueEventually(assert_event, 10)
594+
595+
596+
class MapTTLTest(SingleMemberTestCase):
597+
@classmethod
598+
def configure_client(cls, config):
599+
config["cluster_name"] = cls.cluster.id
600+
return config
601+
602+
def setUp(self):
603+
self.map = self.client.get_map(random_string()).blocking()
604+
605+
def tearDown(self):
606+
self.map.destroy()
607+
608+
def test_put_default_ttl(self):
609+
self.map.put("key", "value")
610+
time.sleep(1.0)
611+
self.assertTrue(self.map.contains_key("key"))
612+
613+
def test_put(self):
614+
self.map.put("key", "value", 0.1)
615+
self.assertTrueEventually(lambda: self.assertFalse(self.map.contains_key("key")))
616+
617+
def test_put_transient_default_ttl(self):
618+
self.map.put_transient("key", "value")
619+
time.sleep(1.0)
620+
self.assertTrue(self.map.contains_key("key"))
621+
622+
def test_put_transient(self):
623+
self.map.put_transient("key", "value", 0.1)
624+
self.assertTrueEventually(lambda: self.assertFalse(self.map.contains_key("key")))
625+
626+
def test_put_if_absent_ttl(self):
627+
self.map.put_if_absent("key", "value")
628+
time.sleep(1.0)
629+
self.assertTrue(self.map.contains_key("key"))
630+
631+
def test_put_if_absent(self):
632+
self.map.put_if_absent("key", "value", 0.1)
633+
self.assertTrueEventually(lambda: self.assertFalse(self.map.contains_key("key")))
634+
635+
def test_set_default_ttl(self):
636+
self.map.set("key", "value")
637+
time.sleep(1.0)
638+
self.assertTrue(self.map.contains_key("key"))
639+
640+
def test_set(self):
641+
self.map.set("key", "value", 0.1)
642+
self.assertTrueEventually(lambda: self.assertFalse(self.map.contains_key("key")))
643+
644+
645+
class MapMaxIdleTest(SingleMemberTestCase):
646+
@classmethod
647+
def configure_client(cls, config):
648+
config["cluster_name"] = cls.cluster.id
649+
return config
650+
651+
def setUp(self):
652+
self.map = self.client.get_map(random_string()).blocking()
653+
654+
def tearDown(self):
655+
self.map.destroy()
656+
657+
def test_put_default_max_idle(self):
658+
self.map.put("key", "value")
659+
time.sleep(1.0)
660+
self.assertTrue(self.map.contains_key("key"))
661+
662+
def test_put(self):
663+
self.map.put("key", "value", max_idle=0.1)
664+
time.sleep(1.0)
665+
self.assertFalse(self.map.contains_key("key"))
666+
667+
def test_put_transient_default_max_idle(self):
668+
self.map.put_transient("key", "value")
669+
time.sleep(1.0)
670+
self.assertTrue(self.map.contains_key("key"))
671+
672+
def test_put_transient(self):
673+
self.map.put_transient("key", "value", max_idle=0.1)
674+
time.sleep(1.0)
675+
self.assertFalse(self.map.contains_key("key"))
676+
677+
def test_put_if_absent_max_idle(self):
678+
self.map.put_if_absent("key", "value")
679+
time.sleep(1.0)
680+
self.assertTrue(self.map.contains_key("key"))
681+
682+
def test_put_if_absent(self):
683+
self.map.put_if_absent("key", "value", max_idle=0.1)
684+
time.sleep(1.0)
685+
self.assertFalse(self.map.contains_key("key"))
686+
687+
def test_set_default_ttl(self):
688+
self.map.set("key", "value")
689+
time.sleep(1.0)
690+
self.assertTrue(self.map.contains_key("key"))
691+
692+
def test_set(self):
693+
self.map.set("key", "value", max_idle=0.1)
694+
time.sleep(1.0)
695+
self.assertFalse(self.map.contains_key("key"))

tests/proxy/queue_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22

3+
from hazelcast.errors import IllegalStateError
34
from hazelcast.proxy.base import ItemEventType
4-
from hazelcast.proxy.queue import Full
55
from tests.base import SingleMemberTestCase
66
from tests.util import random_string, event_collector
77
from hazelcast import six
@@ -97,7 +97,7 @@ def test_add(self):
9797
def test_add_full(self):
9898
_all = ["1", "2", "3", "4", "5", "6"]
9999
self.queue.add_all(_all)
100-
with self.assertRaises(Full):
100+
with self.assertRaises(IllegalStateError):
101101
self.queue.add("cannot add this one")
102102

103103
def test_add_null_element(self):

0 commit comments

Comments
 (0)