You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tasks_loop.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. import asyncio
  2. import time
  3. import redis
  4. import os
  5. import copy
  6. import json
  7. import traceback
  8. import inspect
  9. import sys
  10. import atexit
  11. from asgiref.sync import async_to_sync,sync_to_async
  12. # hot_reload_build = False
  13. hot_reload_build = True
  14. print("QWERTYU")
  15. p=print
  16. async def anop(*a,**kw):pass
  17. def nop(*a,**kw):pass
  18. class Edict(dict):pass
  19. class Eobj():pass
  20. def connect_redis1():
  21. return redis.Redis(host='localhost', port=6379, db=1,charset="utf-8", decode_responses=True, encoding_errors="backslashreplace")
  22. def connect_redis():
  23. return redis.Redis(host='localhost', port=6379, db=0,charset="utf-8", decode_responses=True, encoding_errors="backslashreplace")
  24. def eclass_factory(n):
  25. ret = []
  26. for k in range(n):
  27. class nx:pass
  28. # _rcls_name
  29. ret.append(nx)
  30. return ret
  31. def callable_helper(fn):
  32. ret = {
  33. "is_callable":0,
  34. "is_coroutine":0,
  35. }
  36. ret["is_callable"]= callable(fn)
  37. ret["is_coroutine"]= inspect.iscoroutinefunction(fn)
  38. # if (ca)
  39. return ret
  40. # verbose = print
  41. verbose=nop
  42. class DbgMixin:
  43. async def ws_rec(self,text_data,*a,**kw):
  44. # if "dbg" in
  45. text_data_json = json.loads(text_data)
  46. if not 'dbg' in text_data_json:
  47. return
  48. p("DBG!")
  49. exec(text_data_json["dbg"])
  50. class AconMixin(DbgMixin):
  51. # class AconMixin:
  52. async def connect(self):
  53. p(end="",flush=True)
  54. await self.accept()
  55. verbose("<MRO")
  56. verbose(type(self))
  57. await self.call_all_mro("ws_conn0")
  58. await self.call_all_mro("ws_conn")
  59. await self.call_all_mro("ws_conn2")
  60. verbose("/MRO>")
  61. await self.ws_conn_once()
  62. async def ws_conn_once(self, *a,**kw):pass
  63. async def ws_disconn_once(self, *a,**kw):pass
  64. async def ws_rec_once(self, *a,**kw):pass
  65. async def receive(self, *a,**kw):
  66. await self.call_all_mro("ws_rec",*a,**kw)
  67. await self.ws_rec_once(*a,**kw)
  68. print("",end="",flush=True)
  69. async def call_all_mro(self,mthd_name,*args,**kwargs):
  70. called = set([None])
  71. for cls_obj in self.__class__.__mro__:
  72. mthd = getattr(cls_obj,mthd_name,None)
  73. if not mthd in called:
  74. called.add(mthd)
  75. await mthd(self,*args,**kwargs)
  76. async def disconnect(self, close_code):
  77. await self.call_all_mro("ws_disconn",close_code)
  78. await self.ws_disconn_once(close_code)
  79. class AclTaskMixin:
  80. async def ws_disconn(self,*a,**kw):
  81. pass
  82. async def ws_conn0(self):
  83. self.groups_set = set()
  84. if glob_cl.has_cl:
  85. return
  86. glob_cl.has_cl = True
  87. glob_cl.run_persistent_loop(self)
  88. glob_cl.acl = self.channel_layer
  89. class DevMixin(*eclass_factory(10)):pass
  90. class DevMroMixin(*eclass_factory(10)):pass
  91. class WSStoMixin(*eclass_factory(10)):pass
  92. class GCLMixin(*eclass_factory(10)):pass
  93. class RldManMixin(*eclass_factory(10)):pass
  94. class LoneMixinA():pass
  95. class LoneMixinB():pass
  96. Mixins = Eobj()
  97. Mixins.DevMixin = DevMixin
  98. Mixins.DevMroMixin = DevMroMixin
  99. Mixins.WSStoMixin = WSStoMixin
  100. Mixins.GCLMixin = GCLMixin
  101. Mixins.RldManMixin = RldManMixin
  102. Mixins.LoneMixinA = LoneMixinA
  103. Mixins.LoneMixinB = LoneMixinB
  104. Mixins.DbgMixin = DbgMixin
  105. Mixins.AconMixin = AconMixin
  106. Mixins.AclTaskMixin = AclTaskMixin
  107. class globCL(GCLMixin):
  108. def __init__(self,*a,**kw):
  109. print("IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII")
  110. # for now we are not going to do any weird class stuff
  111. self.acl = None
  112. self.has_cl = False
  113. r'''
  114. self.rconn1 = connect_redis1()
  115. self.rconn = connect_redis()
  116. # '''
  117. self.rman = RldMan()
  118. self.cbs_once = []
  119. self.cbs_asap2 = []
  120. self.cbs_asap = []
  121. self.cbs_once_set = set()
  122. if (hot_reload_build):
  123. self.cbs = {"fn1":fn1,"fn2x":nop}
  124. else:
  125. self.cbs = {}
  126. self.timeout = 1
  127. self.fast_timeout = .1
  128. pass
  129. async def persistent_fast_cb_loop_min_timeout(self,*a,**kw):
  130. print("persistent_fast_cb_loop_min_timeout")
  131. c=0
  132. while 1:
  133. p("",c++)
  134. if len(self.cbs_asap2):
  135. cbs_once = [*self.cbs_asap2]
  136. self.cbs_asap2=[]
  137. k=0
  138. for v in cbs_once:
  139. try:
  140. call_info = callable_helper(v)
  141. if (call_info["is_callable"]):
  142. if call_info["is_coroutine"]:
  143. pass
  144. await v({k,self})
  145. else:
  146. v({k,self})
  147. else:
  148. pass
  149. except Exception as e:
  150. p("persistent_fast_cb_loop Exception cbs_once:",e)
  151. p(flush=True)
  152. else:
  153. pass
  154. finally:
  155. pass
  156. k += 1
  157. if len(self.cbs_asap):
  158. self.cbs_asap2 = self.cbs_asap
  159. self.cbs_asap=[]
  160. await asyncio.sleep(self.fast_timeout)
  161. async def persistent_fast_cb_loop(self,*a,**kw):
  162. while 1:
  163. if len(self.cbs_asap):
  164. cbs_once = [*self.cbs_asap]
  165. self.cbs_asap=[]
  166. k=0
  167. for v in cbs_once:
  168. try:
  169. call_info = callable_helper(v)
  170. if (call_info["is_callable"]):
  171. if call_info["is_coroutine"]:
  172. pass
  173. await v({k,self})
  174. else:
  175. v({k,self})
  176. else:
  177. pass
  178. except Exception as e:
  179. p("persistent_fast_cb_loop Exception cbs_once:",e)
  180. p(flush=True)
  181. else:
  182. pass
  183. finally:
  184. pass
  185. k += 1
  186. await asyncio.sleep(self.fast_timeout)
  187. async def persistent_loop(self,*a,**kw):
  188. print("persistent_loop")
  189. while 1:
  190. for k,v in [*self.cbs.items()]:
  191. try:
  192. call_info = callable_helper(v)
  193. if (call_info["is_callable"]):
  194. if call_info["is_coroutine"]:
  195. await v({k,self})
  196. else:
  197. v({k,self})
  198. else:
  199. pass
  200. pass
  201. except Exception as e:
  202. p("persistent_loop Exception",e)
  203. p(flush=True)
  204. else:
  205. pass
  206. finally:
  207. pass
  208. cbs_once = [*self.cbs_once,*self.cbs_once_set]
  209. self.cbs_once = []
  210. self.cbs_once_set = set()
  211. k=0
  212. for v in cbs_once:
  213. try:
  214. call_info = callable_helper(v)
  215. if (call_info["is_callable"]):
  216. if call_info["is_coroutine"]:
  217. pass
  218. await v({k,self})
  219. else:
  220. v({k,self})
  221. else:
  222. pass
  223. except Exception as e:
  224. p("persistent_loop Exception cbs_once:",e)
  225. p(flush=True)
  226. else:
  227. pass
  228. finally:
  229. pass
  230. k += 1
  231. await asyncio.sleep(self.timeout)
  232. async def _run_persistent_loop2(self,*a,**kw):
  233. p("_run_persistent_loop2:",self,a,kw)
  234. self.run_persistent_loop2 = nop
  235. self.rman.persistent_loop_cb()
  236. # loop = asyncio.get_event_loop()
  237. # loop.create_task(self.persistent_fast_cb_loop())
  238. asyncio.ensure_future(self.persistent_loop())
  239. asyncio.ensure_future(self.persistent_fast_cb_loop_min_timeout())
  240. # self.loop = loop
  241. async def _run_persistent_loop3(self,*a,**kw):
  242. p("_run_persistent_loop3:",self,a,kw)
  243. loop = asyncio.new_event_loop()
  244. self.run_persistent_loop = nop
  245. self.rman.persistent_loop_cb()
  246. loop.create_task(self.persistent_loop())
  247. # loop.create_task(self.persistent_fast_cb_loop())
  248. self.loop = loop
  249. loop.run_until_complete(self.persistent_fast_cb_loop_min_timeout())
  250. # loop.run_forever()
  251. async def _run_persistent_loop(self,*a,**kw):
  252. p("_run_persistent_loop:",self,a,kw)
  253. loop = asyncio.get_event_loop()
  254. self.run_persistent_loop = nop
  255. self.rman.persistent_loop_cb()
  256. loop.create_task(self.persistent_loop())
  257. # loop.create_task(self.persistent_fast_cb_loop())
  258. loop.create_task(self.persistent_fast_cb_loop_min_timeout())
  259. self.loop = loop
  260. run_persistent_loop = _run_persistent_loop
  261. run_persistent_loop2 = _run_persistent_loop2
  262. run_persistent_loop3 = _run_persistent_loop3
  263. def sync_dev_group_discard(self,*a,**kw):
  264. glob_cl.cbs_once.append(self.sync_dev_group_discard(*a,**kw))
  265. async def dev_group_discard(self,group_name,consumer):
  266. channel_layer = glob_cl.acl
  267. if consumer.channel_name in consumer.groups:
  268. consumer.groups.remove(group_name)
  269. await channel_layer.group_discard(group_name,consumer.channel_name)
  270. def sync_dev_group_add(self,*a,**kw):
  271. glob_cl.cbs_once.append(self.group_add(*a,**kw))
  272. async def dev_group_add(self,group_name,consumer):
  273. channel_layer = glob_cl.acl
  274. # if not consumer.channel_name in consumer.groups_set:
  275. # consumer.groups_set.add(groups)
  276. if not consumer.channel_name in consumer.groups:
  277. consumer.groups.append(group_name)
  278. await channel_layer.group_add(group_name,consumer.channel_name)
  279. # RldManMixin
  280. class RldMan(RldManMixin):
  281. def __init__(self,*a,**kw):
  282. self.files = {}
  283. z="ABC"
  284. self.scopes = {
  285. "dflt_scope":{"globals":globals(),"locals":locals()},
  286. "dflt_scope_zloc":{"globals":globals(),"locals":{}},
  287. "dflt_scope_gscope":{"globals":globals(),"locals":{}},
  288. "dflt_scope_copy": {"globals":copy.copy(globals()),"locals":copy.copy(locals())},
  289. # "dflt_scope":{"globals":globals(),"locals":{}}
  290. }
  291. self.scopes['current_scope'] = self.scopes['dflt_scope_zloc']
  292. # self.scope_opt = ""locals
  293. self.scope_opt = "globals"
  294. self.print_tb = 0
  295. base_path = "/usr/games/repos/ign4/py_rld/djc/edan_hrld/"
  296. file_list = [
  297. base_path+"i0.py",
  298. ]
  299. self.add_files(file_list)
  300. # self.add_files(file_list,{"run"})
  301. def persistent_loop_cb(self,*a,**kw):
  302. base_path = "/usr/games/repos/ign4/py_rld/djc/edan_hrld/"
  303. file_list = [
  304. base_path+"f0.py",
  305. ]
  306. self.add_files(file_list)
  307. def add_files(self,files):
  308. for file in files:
  309. if type(file)==str:
  310. self.add_file(file)
  311. elif type(file)==list:
  312. self.add_file(*file)
  313. else:
  314. p("add files???",file)
  315. def add_file(self,file_name,fnx={}):
  316. self.files[file_name] = {"ftxt":"",**fnx}
  317. def get_scope(self,rfile_obj,file_name):
  318. return self.scopes["current_scope"]
  319. return {
  320. "scope":self.scopes["current_scope"],
  321. }
  322. # rfile_obj.get("scope")
  323. # if
  324. def rld_file(self,file_name,ret= {"errs":{},"all":{},"alle":{},},**kw):
  325. if file_name in self.files:
  326. rfile_obj = self.files[file_name]
  327. st = os.stat(file_name)
  328. st_tuple = (st.st_mtime,st.st_size)
  329. # if rfile_obj["ftxt"] == "":
  330. eflag ="nd"
  331. # rfile_obj["ftxt"] = st_tuple
  332. if rfile_obj["ftxt"] != st_tuple:
  333. # p(rfile_obj["ftxt"])
  334. rfile_obj["ftxt"] = st_tuple
  335. try:
  336. f = open(file_name,"r")
  337. ftxt = f.read()
  338. # scope_key = rfile_obj.get("scope")
  339. # p(scope_key,rfile_obj)
  340. f.close()
  341. scope_obj = self.get_scope(file_name,rfile_obj)
  342. if self.scope_opt == "locals":
  343. eflag ="locals"
  344. exec(ftxt,scope_obj["globals"],scope_obj["locals"])
  345. elif self.scope_opt == "globals":
  346. eflag ="globals"
  347. exec(ftxt,scope_obj["globals"])
  348. else:
  349. eflag ="[]"
  350. exec(ftxt)
  351. except Exception as e:
  352. p()
  353. print("file:",file_name)
  354. print("EXCEPT",eflag,e)
  355. if self.print_tb:
  356. traceback.print_tb(e.__traceback__,file=sys.stdout)
  357. else:
  358. pass
  359. finally:
  360. pass
  361. print(end="",flush=True)
  362. return ret
  363. def rld_files(self):
  364. ret = {
  365. "errs":{},
  366. "all":{},
  367. "alle":{},
  368. }
  369. for k in [*self.files]:
  370. self.rld_file(k,ret)
  371. p("",end="",flush=True)
  372. return ret
  373. def fn1(*a,**kw):
  374. glob_cl.rman.rld_files()
  375. glob_cl = globCL()
  376. # we are not flushing databases if
  377. def atexit_fn():
  378. print("atexit_fn!\n\n")
  379. # rconn = glob_cl.rconn
  380. # rconn.flushall()
  381. # rconn.flushdb()
  382. print("",end="",flush=True)
  383. if hot_reload_build:
  384. glob_cl.rman.rld_files()
  385. atexit.register(atexit_fn)
  386. else:
  387. import wsps.hot_reload_temp_staging
  388. wsps.hot_reload_temp_staging.init_class_edits(Mixins)
  389. glob_cl.dev_room_dashboard = "jfi_dash"
  390. # if not hot_reload_build:
  391. # glob_cl.rman.rld_files()
  392. # print("############################ ##############################")