11"""Async and dict-like interfaces for interacting with Replit Database."""
22
3+ import asyncio
34from collections import abc
45import json
56import threading
@@ -82,8 +83,17 @@ class AsyncDatabase:
8283 :param unbind Callable: Permit additional behavior after Database close
8384 """
8485
85- __slots__ = ("db_url" , "sess" , "client" , "_get_db_url" , "_unbind" , "_refresh_timer" )
86+ __slots__ = (
87+ "db_url" ,
88+ "sess" ,
89+ "client" ,
90+ "_get_db_url" ,
91+ "_unbind" ,
92+ "_refresh_timer" ,
93+ "_watchdog_timer" ,
94+ )
8695 _refresh_timer : Optional [threading .Timer ]
96+ _watchdog_timer : Optional [threading .Timer ]
8797
8898 def __init__ (
8999 self ,
@@ -113,6 +123,9 @@ def __init__(
113123 if self ._get_db_url :
114124 self ._refresh_timer = threading .Timer (3600 , self ._refresh_db )
115125 self ._refresh_timer .start ()
126+ watched_thread = threading .main_thread ()
127+ self ._watchdog_timer = threading .Timer (1 , self ._watchdog , args = [watched_thread ])
128+ self ._watchdog_timer .start ()
116129
117130 def _refresh_db (self ) -> None :
118131 if self ._refresh_timer :
@@ -125,6 +138,14 @@ def _refresh_db(self) -> None:
125138 self ._refresh_timer = threading .Timer (3600 , self ._refresh_db )
126139 self ._refresh_timer .start ()
127140
141+ def _watchdog (self , watched_thread : threading .Thread ) -> None :
142+ if not watched_thread .is_alive ():
143+ return asyncio .run (self .close ())
144+ if self ._watchdog_timer :
145+ self ._watchdog_timer .cancel ()
146+ self ._watchdog_timer = threading .Timer (1 , self ._watchdog , args = [watched_thread ])
147+ self ._watchdog_timer .start ()
148+
128149 def update_db_url (self , db_url : str ) -> None :
129150 """Update the database url.
130151
@@ -292,6 +313,9 @@ async def close(self) -> None:
292313 if self ._refresh_timer :
293314 self ._refresh_timer .cancel ()
294315 self ._refresh_timer = None
316+ if self ._watchdog_timer :
317+ self ._watchdog_timer .cancel ()
318+ self ._watchdog_timer = None
295319 if self ._unbind :
296320 # Permit signaling to surrounding scopes that we have closed
297321 self ._unbind ()
@@ -485,8 +509,16 @@ class Database(abc.MutableMapping):
485509 :param unbind Callable: Permit additional behavior after Database close
486510 """
487511
488- __slots__ = ("db_url" , "sess" , "_get_db_url" , "_unbind" , "_refresh_timer" )
512+ __slots__ = (
513+ "db_url" ,
514+ "sess" ,
515+ "_get_db_url" ,
516+ "_unbind" ,
517+ "_refresh_timer" ,
518+ "_watchdog_timer" ,
519+ )
489520 _refresh_timer : Optional [threading .Timer ]
521+ _watchdog_timer : Optional [threading .Timer ]
490522
491523 def __init__ (
492524 self ,
@@ -518,6 +550,9 @@ def __init__(
518550 if self ._get_db_url :
519551 self ._refresh_timer = threading .Timer (3600 , self ._refresh_db )
520552 self ._refresh_timer .start ()
553+ watched_thread = threading .main_thread ()
554+ self ._watchdog_timer = threading .Timer (1 , self ._watchdog , args = [watched_thread ])
555+ self ._watchdog_timer .start ()
521556
522557 def _refresh_db (self ) -> None :
523558 if self ._refresh_timer :
@@ -530,6 +565,14 @@ def _refresh_db(self) -> None:
530565 self ._refresh_timer = threading .Timer (3600 , self ._refresh_db )
531566 self ._refresh_timer .start ()
532567
568+ def _watchdog (self , watched_thread : threading .Thread ) -> None :
569+ if not watched_thread .is_alive ():
570+ return self .close ()
571+ if self ._watchdog_timer :
572+ self ._watchdog_timer .cancel ()
573+ self ._watchdog_timer = threading .Timer (1 , self ._watchdog , args = [watched_thread ])
574+ self ._watchdog_timer .start ()
575+
533576 def update_db_url (self , db_url : str ) -> None :
534577 """Update the database url.
535578
@@ -720,6 +763,9 @@ def close(self) -> None:
720763 if self ._refresh_timer :
721764 self ._refresh_timer .cancel ()
722765 self ._refresh_timer = None
766+ if self ._watchdog_timer :
767+ self ._watchdog_timer .cancel ()
768+ self ._watchdog_timer = None
723769 if self ._unbind :
724770 # Permit signaling to surrounding scopes that we have closed
725771 self ._unbind ()
0 commit comments