redis-allocator 0.3.3__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- __version__ = '0.3.3'
1
+ __version__ = '0.4.0'
@@ -175,21 +175,42 @@ class RedisAllocatorObject(Generic[U]):
175
175
  return self.obj.is_healthy()
176
176
  return True
177
177
 
178
- def set_unhealthy(self, duration: int = 3600):
178
+ def set_healthy(self, duration: Timeout = 3600):
179
+ """Set the object as healthy."""
180
+ if self.obj is not None and self.obj.name is not None:
181
+ self.allocator.update_soft_bind(self.obj.name, self.key, duration)
182
+ if self.allocator.shared:
183
+ self.allocator.unlock(self.key)
184
+
185
+ def set_unhealthy(self, duration: Timeout = 3600):
179
186
  """Set the object as unhealthy."""
180
187
  if self.obj is not None and self.obj.name is not None:
181
188
  self.allocator.unbind_soft_bind(self.obj.name)
182
189
  self.allocator.update(self.key, timeout=duration)
183
190
 
184
- def refresh(self, timeout: Timeout = 120):
191
+ def refresh(self, timeout: Timeout = 120, cache_timeout: Timeout = 3600):
185
192
  """Refresh the object."""
186
193
  self.close()
187
194
  new_obj = self.allocator.policy.malloc(self.allocator, timeout=timeout,
188
- obj=self.obj, params=self.params)
195
+ obj=self.obj, params=self.params,
196
+ cache_timeout=cache_timeout)
189
197
  if new_obj is not None:
190
198
  self.obj = new_obj.obj
191
199
  self.key = new_obj.key
192
200
  self.params = new_obj.params
201
+ self.open()
202
+
203
+ def refresh_until_healthy(self, timeout: Timeout = 120, max_attempts: int = 10, lock_duration: Timeout = 3600, cache_timeout: Timeout = 3600):
204
+ """Refresh the object until it is healthy."""
205
+ for _ in range(max_attempts):
206
+ try:
207
+ if self.is_healthy():
208
+ return
209
+ except Exception as e:
210
+ logger.error(f"Error checking health of {self.key}: {e}")
211
+ self.set_unhealthy(lock_duration)
212
+ self.refresh(timeout, cache_timeout)
213
+ raise RuntimeError("the objects is still unhealthy after %d attempts", max_attempts)
193
214
 
194
215
  @property
195
216
  def unique_id(self) -> str:
@@ -311,6 +332,7 @@ class RedisAllocatorPolicy(ABC):
311
332
  A tuple containing the number of healthy and unhealthy items in the allocator
312
333
  """
313
334
  with ThreadPoolExecutor(max_workers=max_threads) as executor:
335
+ inputs = []
314
336
  for key in allocator.keys():
315
337
  if params_fn is not None:
316
338
  params = params_fn(key)
@@ -320,9 +342,11 @@ class RedisAllocatorPolicy(ABC):
320
342
  obj = obj_fn(key)
321
343
  else:
322
344
  obj = None
323
- alloc_obj = RedisAllocatorObject(allocator, key, obj, params)
324
- executor.submit(self.check_health_once, alloc_obj, lock_duration)
325
- executor.shutdown(wait=True)
345
+ inputs.append(RedisAllocatorObject(allocator, key, obj, params))
346
+ results = list(executor.map(self.check_health_once, inputs, timeout=max_threads * lock_duration / (len(inputs) + 1)))
347
+ healthy = sum(results)
348
+ unhealthy = len(results) - healthy
349
+ return healthy, unhealthy
326
350
 
327
351
 
328
352
  class DefaultRedisAllocatorPolicy(RedisAllocatorPolicy):
@@ -349,7 +373,8 @@ class DefaultRedisAllocatorPolicy(RedisAllocatorPolicy):
349
373
  """
350
374
 
351
375
  def __init__(self, gc_count: int = 5, update_interval: int = 300,
352
- expiry_duration: int = -1, updater: Optional[RedisAllocatorUpdater] = None):
376
+ expiry_duration: int = -1, updater: Optional[RedisAllocatorUpdater] = None,
377
+ auto_close: bool = False):
353
378
  """Initialize the default allocation policy.
354
379
 
355
380
  Args:
@@ -357,6 +382,7 @@ class DefaultRedisAllocatorPolicy(RedisAllocatorPolicy):
357
382
  update_interval: Interval in seconds between pool updates
358
383
  expiry_duration: Default timeout for pool items (-1 means no timeout)
359
384
  updater: Optional updater for refreshing the pool's keys
385
+ auto_close: If True, the allocator will automatically close the object when it is not unique
360
386
  """
361
387
  self.gc_count = gc_count
362
388
  self.update_interval: float = update_interval
@@ -365,6 +391,7 @@ class DefaultRedisAllocatorPolicy(RedisAllocatorPolicy):
365
391
  self._allocator: Optional[weakref.ReferenceType['RedisAllocator']] = None
366
392
  self._update_lock_key: Optional[str] = None
367
393
  self.objects: weakref.WeakValueDictionary[str, RedisAllocatorObject] = weakref.WeakValueDictionary()
394
+ self.auto_close = auto_close
368
395
 
369
396
  def initialize(self, allocator: 'RedisAllocator'):
370
397
  """Initialize the policy with an allocator instance.
@@ -410,9 +437,10 @@ class DefaultRedisAllocatorPolicy(RedisAllocatorPolicy):
410
437
  key = allocator.malloc_key(timeout, obj_name,
411
438
  cache_timeout=cache_timeout)
412
439
  alloc_obj = RedisAllocatorObject(allocator, key, obj, params)
413
- old_obj = self.objects.get(alloc_obj.unique_id, None)
414
- if old_obj is not None:
415
- old_obj.close()
440
+ if self.auto_close:
441
+ old_obj = self.objects.get(alloc_obj.unique_id, None)
442
+ if old_obj is not None:
443
+ old_obj.close()
416
444
  self.objects[alloc_obj.unique_id] = alloc_obj
417
445
  return alloc_obj
418
446
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: redis-allocator
3
- Version: 0.3.3
3
+ Version: 0.4.0
4
4
  Summary: Redis-based resource allocation system.
5
5
  Home-page: https://github.com/invoker-bot/RedisAllocator-python
6
6
  Author: Invoker Bot
@@ -230,7 +230,7 @@ if allocated_obj:
230
230
 
231
231
  # Using soft binding (associates a name with a resource)
232
232
  allocator.update_soft_bind("worker-1", "resource-1")
233
- # Later...
233
+ # Unbind soft binding
234
234
  allocator.unbind_soft_bind("worker-1")
235
235
 
236
236
  # Garbage collection (reclaims unused resources)
@@ -291,9 +291,9 @@ graph TD
291
291
 
292
292
  subgraph "PoolHash Contents (Doubly-Linked Free List)"
293
293
  Key1 --> Key2["Key2: Key1||Key3||Expiry"]
294
- Key2 --> Key3["Key3: Key2||...||Expiry"]
295
- Key3 --> ...
296
- KeyN_1[...] --> KeyN
294
+ Key2 --> Key3["Key3: Key2||Key4||Expiry"]
295
+ Key3 --> Key4["Key4: Key3||Key5||Expiry"]
296
+ KeyN_1["KeyN: KeyN-1||""||Expiry"] --> KeyN
297
297
  end
298
298
 
299
299
  subgraph "Allocated Keys (Non-Shared Mode)"
@@ -1,15 +1,15 @@
1
1
  redis_allocator/__init__.py,sha256=TVjUm-8YEu_MQD_PkfeIKiVknpCJBrUY9cWN1LlaZcU,1016
2
- redis_allocator/_version.py,sha256=on4Bj4mGEjEjyUkQExxprhOoEopcv_sPapsEnNxyelE,22
3
- redis_allocator/allocator.py,sha256=oFJSRAhFJsBbeho5TibY81_3Vy07glrAuEhpIOYfeJI,47282
2
+ redis_allocator/_version.py,sha256=2eiWQI55fd-roDdkt4Hvl9WzrTJ4xQo33VzFud6D03U,22
3
+ redis_allocator/allocator.py,sha256=Bo4Ck7mqg-Z8KdQH-iqeHfdEbyhMqBD0c2g5T3E5sBU,48730
4
4
  redis_allocator/lock.py,sha256=fqf6WUWHKYenEArWopMIF6kWEnDfADC-bZvnQImsQVo,27400
5
5
  redis_allocator/task_queue.py,sha256=8DjNr2uxhzCsHatV_CHOeGh7_K9pqQZFApSbe2blRO0,14989
6
- redis_allocator-0.3.3.dist-info/licenses/LICENSE,sha256=Wt4X1rHpffQfEiyWcDUx8BMLjXxfPqaiYZ7Lgsj7L4c,1068
6
+ redis_allocator-0.4.0.dist-info/licenses/LICENSE,sha256=Wt4X1rHpffQfEiyWcDUx8BMLjXxfPqaiYZ7Lgsj7L4c,1068
7
7
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  tests/conftest.py,sha256=Ts82uylQSzP_GcaN0E02o3xcFdjw20cXNzh3RAdYKW4,3967
9
9
  tests/test_allocator.py,sha256=hFKgLe_yONtEjjm6zssUnhK0tzihG_1xZMziztHmqqA,22404
10
10
  tests/test_lock.py,sha256=MDMRNN46VhWqkHUIhYOMEDgZkFFCW_WjwRLTOjkFF-Q,46952
11
11
  tests/test_task_queue.py,sha256=Fh5naikFajfOvL6GngEy_TPfOYCYZolZfVwtR6T4dTY,31710
12
- redis_allocator-0.3.3.dist-info/METADATA,sha256=oEPcsqP1oiKP_HaZgIgfEEqIxuY6c9aoapC5ecLrP8w,21653
13
- redis_allocator-0.3.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
14
- redis_allocator-0.3.3.dist-info/top_level.txt,sha256=0hXzU7sK5FCeSolTEYxThOt3HOybnwaXv1FLRJvHVgI,22
15
- redis_allocator-0.3.3.dist-info/RECORD,,
12
+ redis_allocator-0.4.0.dist-info/METADATA,sha256=rXeA3Nsb6eie8H5G10HXLlLI8jCRs45I1C06seN-Sgs,21727
13
+ redis_allocator-0.4.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
14
+ redis_allocator-0.4.0.dist-info/top_level.txt,sha256=0hXzU7sK5FCeSolTEYxThOt3HOybnwaXv1FLRJvHVgI,22
15
+ redis_allocator-0.4.0.dist-info/RECORD,,