move backend source to src
This commit is contained in:
1 parent
c8b86927e2
commit
0dbdb1b5ad
13 files changed
+6
-22
No files matched your search
@@ -0,0 +1,103 @@
|
||||
import asyncio
|
||||
import nest_asyncio
|
||||
|
||||
id_counter = 0
|
||||
|
||||
def run_fn (fn_obj, arg):
|
||||
if fn_obj == None:
|
||||
return
|
||||
|
||||
# https://stackoverflow.com/questions/36076619/test-if-function-or-method-is-normal-or-asynchronous
|
||||
if asyncio.iscoroutinefunction(fn_obj):
|
||||
if arg == None:
|
||||
asyncio.create_task(fn_obj())
|
||||
else:
|
||||
asyncio.create_task(fn_obj(arg))
|
||||
return
|
||||
|
||||
if arg == None:
|
||||
fn_obj()
|
||||
else:
|
||||
fn_obj(arg)
|
||||
|
||||
def make_runnable(fn_obj):
|
||||
"""
|
||||
Creates an async signal and a task that listen to the signal.
|
||||
When it is received, fn_obj is called.
|
||||
The task doesn't stop and keeps forwarding signals to the passed function.
|
||||
There can also be arguments coming along with the signal, those are passed to the function.
|
||||
"""
|
||||
signal_queue = asyncio.Queue()
|
||||
|
||||
async def signal_listener():
|
||||
while True:
|
||||
args = await signal_queue.get()
|
||||
if args is None: # Stop signal
|
||||
break
|
||||
run_fn(fn_obj, args[0] if args else None)
|
||||
|
||||
# Start the listener task in the background
|
||||
asyncio.create_task(signal_listener())
|
||||
|
||||
# Return a method to put items on the signal queue
|
||||
return lambda *args: signal_queue.put_nowait(args)
|
||||
|
||||
class Stream:
|
||||
def __init__(self, app):
|
||||
global id_counter
|
||||
|
||||
self.id = id_counter
|
||||
id_counter = id_counter + 1
|
||||
|
||||
self.open = True
|
||||
self.content = ""
|
||||
self.listeners = []
|
||||
|
||||
app.streams[self.id] = self
|
||||
|
||||
def listen (self, chunk_fn, end_fn):
|
||||
nest_asyncio.apply()
|
||||
#chunk_fn = make_runnable(chunk_fn)
|
||||
#end_fn = make_runnable(end_fn)
|
||||
|
||||
if self.open:
|
||||
self.listeners.append({
|
||||
"chunk": chunk_fn,
|
||||
"end": end_fn,
|
||||
})
|
||||
|
||||
if self.content != "":
|
||||
run_fn(chunk_fn, self.content)
|
||||
else:
|
||||
run_fn(chunk_fn, self.content)
|
||||
run_fn(end_fn, None)
|
||||
|
||||
def feed (self, chunk):
|
||||
if not self.open:
|
||||
return
|
||||
|
||||
self.content = self.content + chunk
|
||||
for listener in self.listeners:
|
||||
run_fn(listener["chunk"], chunk)
|
||||
|
||||
def close (self):
|
||||
self.open = False
|
||||
|
||||
for listener in self.listeners:
|
||||
run_fn(listener["end"], None)
|
||||
|
||||
async def content_wait (self):
|
||||
async_loop = asyncio.get_event_loop()
|
||||
event = asyncio.Event()
|
||||
|
||||
def set_event():
|
||||
event.set()
|
||||
|
||||
def noop (chunk): pass
|
||||
def end_fn ():
|
||||
async_loop.call_soon_threadsafe(set_event)
|
||||
|
||||
self.listen(chunk_fn=noop, end_fn=end_fn)
|
||||
await event.wait()
|
||||
|
||||
return self.content
|
||||
Reference in new issue
Block a user