dycw-utilities 0.129.1__py3-none-any.whl → 0.129.3__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.
- {dycw_utilities-0.129.1.dist-info → dycw_utilities-0.129.3.dist-info}/METADATA +1 -1
- {dycw_utilities-0.129.1.dist-info → dycw_utilities-0.129.3.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/asyncio.py +53 -51
- {dycw_utilities-0.129.1.dist-info → dycw_utilities-0.129.3.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.129.1.dist-info → dycw_utilities-0.129.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=xvWWvcsivl7tOOnGKv9OKQ27M1f_gdDFBYwkYVERk-4,60
|
2
2
|
utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
|
3
|
-
utilities/asyncio.py,sha256=
|
3
|
+
utilities/asyncio.py,sha256=3n5EIcSq2xtEF1i4oR0oY2JmBq3NyugeHKFK39Mt22s,37987
|
4
4
|
utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
|
5
5
|
utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
|
6
6
|
utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
|
@@ -89,7 +89,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
89
89
|
utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
|
90
90
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
91
91
|
utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
|
92
|
-
dycw_utilities-0.129.
|
93
|
-
dycw_utilities-0.129.
|
94
|
-
dycw_utilities-0.129.
|
95
|
-
dycw_utilities-0.129.
|
92
|
+
dycw_utilities-0.129.3.dist-info/METADATA,sha256=tSQGMjW1iN-3qoQebYNCtjnI6yzQARSXvw0ThdEKy2A,12803
|
93
|
+
dycw_utilities-0.129.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
94
|
+
dycw_utilities-0.129.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
95
|
+
dycw_utilities-0.129.3.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/asyncio.py
CHANGED
@@ -353,6 +353,7 @@ class Looper(Generic[_T]):
|
|
353
353
|
_is_entered: Event = field(default_factory=Event, init=False, repr=False)
|
354
354
|
_is_initialized: Event = field(default_factory=Event, init=False, repr=False)
|
355
355
|
_is_initializing: Event = field(default_factory=Event, init=False, repr=False)
|
356
|
+
_is_pending_back_off: Event = field(default_factory=Event, init=False, repr=False)
|
356
357
|
_is_pending_restart: Event = field(default_factory=Event, init=False, repr=False)
|
357
358
|
_is_pending_stop: Event = field(default_factory=Event, init=False, repr=False)
|
358
359
|
_is_pending_stop_when_empty: Event = field(
|
@@ -439,6 +440,11 @@ class Looper(Generic[_T]):
|
|
439
440
|
def __len__(self) -> int:
|
440
441
|
return self._queue.qsize()
|
441
442
|
|
443
|
+
async def _apply_back_off(self) -> None:
|
444
|
+
"""Apply a back off period."""
|
445
|
+
await sleep(self._backoff)
|
446
|
+
self._is_pending_back_off.clear()
|
447
|
+
|
442
448
|
async def core(self) -> None:
|
443
449
|
"""Core part of running the looper."""
|
444
450
|
|
@@ -458,7 +464,9 @@ class Looper(Generic[_T]):
|
|
458
464
|
"""Remove and return an item from the end of the queue without blocking."""
|
459
465
|
return self._queue.get_right_nowait()
|
460
466
|
|
461
|
-
async def initialize(
|
467
|
+
async def initialize(
|
468
|
+
self, *, skip_sleep_if_failure: bool = False
|
469
|
+
) -> Exception | None:
|
462
470
|
"""Initialize the looper."""
|
463
471
|
match self._is_initializing.is_set():
|
464
472
|
case True:
|
@@ -476,21 +484,21 @@ class Looper(Generic[_T]):
|
|
476
484
|
async with self._lock:
|
477
485
|
self._initialization_failures += 1
|
478
486
|
ret = error
|
479
|
-
match
|
487
|
+
match skip_sleep_if_failure:
|
480
488
|
case True:
|
481
489
|
_ = self._logger.warning(
|
482
|
-
"%s: encountered %s whilst initializing
|
490
|
+
"%s: encountered %s whilst initializing",
|
483
491
|
self,
|
484
492
|
repr_error(error),
|
485
|
-
self.backoff,
|
486
493
|
)
|
487
|
-
await sleep(self._backoff)
|
488
494
|
case False:
|
489
495
|
_ = self._logger.warning(
|
490
|
-
"%s: encountered %s whilst initializing",
|
496
|
+
"%s: encountered %s whilst initializing; sleeping for %s...",
|
491
497
|
self,
|
492
498
|
repr_error(error),
|
499
|
+
self.backoff,
|
493
500
|
)
|
501
|
+
await self._apply_back_off()
|
494
502
|
case _ as never:
|
495
503
|
assert_never(never)
|
496
504
|
else:
|
@@ -547,6 +555,21 @@ class Looper(Generic[_T]):
|
|
547
555
|
**kwargs,
|
548
556
|
)
|
549
557
|
|
558
|
+
def request_back_off(self) -> None:
|
559
|
+
"""Request the looper to back off."""
|
560
|
+
match self._is_pending_back_off.is_set():
|
561
|
+
case True:
|
562
|
+
_ = self._debug and self._logger.debug(
|
563
|
+
"%s: already requested back off", self
|
564
|
+
)
|
565
|
+
case False:
|
566
|
+
_ = self._debug and self._logger.debug(
|
567
|
+
"%s: requesting back off...", self
|
568
|
+
)
|
569
|
+
self._is_pending_back_off.set()
|
570
|
+
case _ as never:
|
571
|
+
assert_never(never)
|
572
|
+
|
550
573
|
def request_restart(self) -> None:
|
551
574
|
"""Request the looper to restart."""
|
552
575
|
match self._is_pending_restart.is_set():
|
@@ -561,6 +584,7 @@ class Looper(Generic[_T]):
|
|
561
584
|
self._is_pending_restart.set()
|
562
585
|
case _ as never:
|
563
586
|
assert_never(never)
|
587
|
+
self.request_back_off()
|
564
588
|
|
565
589
|
def request_stop(self) -> None:
|
566
590
|
"""Request the looper to stop."""
|
@@ -590,20 +614,20 @@ class Looper(Generic[_T]):
|
|
590
614
|
case _ as never:
|
591
615
|
assert_never(never)
|
592
616
|
|
593
|
-
async def restart(self
|
617
|
+
async def restart(self) -> None:
|
594
618
|
"""Restart the looper."""
|
595
619
|
_ = self._debug and self._logger.debug("%s: restarting...", self)
|
596
620
|
self._is_pending_restart.clear()
|
597
621
|
async with self._lock:
|
598
622
|
self._restart_attempts += 1
|
599
|
-
tear_down = await self.tear_down(
|
600
|
-
initialization = await self.initialize(
|
601
|
-
match tear_down, initialization
|
602
|
-
case None, None
|
623
|
+
tear_down = await self.tear_down(skip_sleep_if_failure=True)
|
624
|
+
initialization = await self.initialize(skip_sleep_if_failure=True)
|
625
|
+
match tear_down, initialization:
|
626
|
+
case None, None:
|
603
627
|
_ = self._debug and self._logger.debug("%s: finished restarting", self)
|
604
628
|
async with self._lock:
|
605
629
|
self._restart_successes += 1
|
606
|
-
case Exception(), None
|
630
|
+
case Exception(), None:
|
607
631
|
async with self._lock:
|
608
632
|
self._restart_failures += 1
|
609
633
|
_ = self._logger.warning(
|
@@ -612,16 +636,8 @@ class Looper(Generic[_T]):
|
|
612
636
|
repr_error(tear_down),
|
613
637
|
self.backoff,
|
614
638
|
)
|
615
|
-
await
|
616
|
-
case Exception()
|
617
|
-
async with self._lock:
|
618
|
-
self._restart_failures += 1
|
619
|
-
_ = self._logger.warning(
|
620
|
-
"%s: encountered %s whilst restarting (tear down)",
|
621
|
-
self,
|
622
|
-
repr_error(tear_down),
|
623
|
-
)
|
624
|
-
case None, Exception(), True:
|
639
|
+
await self._apply_back_off()
|
640
|
+
case None, Exception():
|
625
641
|
async with self._lock:
|
626
642
|
self._restart_failures += 1
|
627
643
|
_ = self._logger.warning(
|
@@ -630,16 +646,8 @@ class Looper(Generic[_T]):
|
|
630
646
|
repr_error(initialization),
|
631
647
|
self.backoff,
|
632
648
|
)
|
633
|
-
await
|
634
|
-
case
|
635
|
-
async with self._lock:
|
636
|
-
self._restart_failures += 1
|
637
|
-
_ = self._logger.warning(
|
638
|
-
"%s: encountered %s whilst restarting (initialize)",
|
639
|
-
self,
|
640
|
-
repr_error(initialization),
|
641
|
-
)
|
642
|
-
case Exception(), Exception(), True:
|
649
|
+
await self._apply_back_off()
|
650
|
+
case Exception(), Exception():
|
643
651
|
async with self._lock:
|
644
652
|
self._restart_failures += 1
|
645
653
|
_ = self._logger.warning(
|
@@ -649,16 +657,7 @@ class Looper(Generic[_T]):
|
|
649
657
|
repr_error(initialization),
|
650
658
|
self.backoff,
|
651
659
|
)
|
652
|
-
await
|
653
|
-
case Exception(), Exception(), False:
|
654
|
-
async with self._lock:
|
655
|
-
self._restart_failures += 1
|
656
|
-
_ = self._logger.warning(
|
657
|
-
"%s: encountered %s (tear down) and then %s (initialization) whilst restarting",
|
658
|
-
self,
|
659
|
-
repr_error(tear_down),
|
660
|
-
repr_error(initialization),
|
661
|
-
)
|
660
|
+
await self._apply_back_off()
|
662
661
|
case _ as never:
|
663
662
|
assert_never(never)
|
664
663
|
|
@@ -674,10 +673,12 @@ class Looper(Generic[_T]):
|
|
674
673
|
self._is_pending_stop_when_empty.is_set() and self.empty()
|
675
674
|
):
|
676
675
|
await self.stop()
|
676
|
+
elif self._is_pending_back_off.is_set():
|
677
|
+
await self._apply_back_off()
|
677
678
|
elif self._is_pending_restart.is_set():
|
678
|
-
await self.restart(
|
679
|
+
await self.restart()
|
679
680
|
elif not self._is_initialized.is_set():
|
680
|
-
_ = await self.initialize(
|
681
|
+
_ = await self.initialize()
|
681
682
|
else:
|
682
683
|
_ = self._debug and self._logger.debug(
|
683
684
|
"%s: running core...", self
|
@@ -695,7 +696,6 @@ class Looper(Generic[_T]):
|
|
695
696
|
async with self._lock:
|
696
697
|
self._core_failures += 1
|
697
698
|
self.request_restart()
|
698
|
-
await sleep(self._backoff)
|
699
699
|
else:
|
700
700
|
async with self._lock:
|
701
701
|
self._core_successes += 1
|
@@ -749,7 +749,9 @@ class Looper(Generic[_T]):
|
|
749
749
|
case _ as never:
|
750
750
|
assert_never(never)
|
751
751
|
|
752
|
-
async def tear_down(
|
752
|
+
async def tear_down(
|
753
|
+
self, *, skip_sleep_if_failure: bool = False
|
754
|
+
) -> Exception | None:
|
753
755
|
"""Tear down the looper."""
|
754
756
|
match self._is_tearing_down.is_set():
|
755
757
|
case True:
|
@@ -766,21 +768,21 @@ class Looper(Generic[_T]):
|
|
766
768
|
async with self._lock:
|
767
769
|
self._tear_down_failures += 1
|
768
770
|
ret = error
|
769
|
-
match
|
771
|
+
match skip_sleep_if_failure:
|
770
772
|
case True:
|
771
773
|
_ = self._logger.warning(
|
772
|
-
"%s: encountered %s whilst tearing down
|
774
|
+
"%s: encountered %s whilst tearing down",
|
773
775
|
self,
|
774
776
|
repr_error(error),
|
775
|
-
self.backoff,
|
776
777
|
)
|
777
|
-
await sleep(self._backoff)
|
778
778
|
case False:
|
779
779
|
_ = self._logger.warning(
|
780
|
-
"%s: encountered %s whilst tearing down",
|
780
|
+
"%s: encountered %s whilst tearing down; sleeping for %s...",
|
781
781
|
self,
|
782
782
|
repr_error(error),
|
783
|
+
self.backoff,
|
783
784
|
)
|
785
|
+
await self._apply_back_off()
|
784
786
|
case _ as never:
|
785
787
|
assert_never(never)
|
786
788
|
else:
|
File without changes
|
File without changes
|