1212from dataclasses import dataclass
1313from datetime import datetime
1414from socket import gethostname
15- from threading import Thread
15+ from threading import Event , Lock , Thread
1616from time import time
1717
1818from aiohttp import ClientSession
@@ -62,6 +62,11 @@ def __post_init__(
6262 if self .timeout is None :
6363 self .timeout = ClientTimeout (10 )
6464 self .session = None
65+ self .loop = asyncio .new_event_loop ()
66+ self .thread = Thread (target = self .worker , daemon = True )
67+ self .thread .start ()
68+ self .event = Event ()
69+ self .lock = Lock ()
6570
6671 def __call__ (self , xp : int = 1 ) -> None :
6772 """Add xp.
@@ -72,36 +77,53 @@ def __call__(self, xp: int = 1) -> None:
7277 :type xp: int
7378 :rtype: None
7479 """
75- self .data ["xps" ][0 ]["xp" ] += xp
76- if (
77- time () - self .datetime .timestamp () > self .interval
78- and self .data ["xps" ][0 ]["xp" ] > 0
79- ):
80- co = self .send_xp ()
81- Thread (target = asyncio .run , args = (co ,)).run ()
80+ with self .lock :
81+ self .data ["xps" ][0 ]["xp" ] += xp
82+ if time () - self .datetime .timestamp () > self .interval :
83+ self .event .set ()
84+
85+ def worker (self ) -> None :
86+ """Worker.
87+
88+ :param self:
89+ :rtype: None
90+ """
91+ asyncio .set_event_loop (self .loop )
92+ while True :
93+ self .event .wait ()
94+ self .loop .run_until_complete (self .send_xp ())
95+ self .event .clear ()
96+
97+ def __del__ (self ) -> None :
98+ if self .session :
99+ self .loop .run_until_complete (self .session .close ())
100+ self .loop .close ()
82101
83102 async def send_xp (self ) -> str :
84103 """Send xp.
85104
86105 :rtype: str
87106 """
88- self .datetime = datetime .now ().astimezone ()
89- self .data ["coded_at" ] = self .datetime .isoformat ()
90- data = json .dumps (self .data ).encode ("utf-8" )
91- text = ""
92107 if self .session is None :
93108 self .session = ClientSession (
94109 base_url = self .url ,
95110 headers = self .headers ,
96111 timeout = self .timeout ,
97112 )
113+ self .datetime = datetime .now ().astimezone ()
114+ self .data ["coded_at" ] = self .datetime .isoformat ()
115+ text = ""
116+ with self .lock :
117+ data = json .dumps (self .data ).encode ("utf-8" )
118+ xp = self .data ["xps" ][0 ]["xp" ]
98119 try :
99120 async with self .session .post (
100121 "/" ,
101122 data = data ,
102123 ) as resp :
103124 text = await resp .text ()
104- self .data ["xps" ][0 ]["xp" ] = 0
125+ with self .lock :
126+ self .data ["xps" ][0 ]["xp" ] -= xp
105127 except TimeoutError as error :
106128 logger .error (error )
107129 return text
0 commit comments