Skip to content

Instantly share code, notes, and snippets.

@arduinka55055
Created November 4, 2021 09:43
Show Gist options
  • Save arduinka55055/4f5c625ed3fd5e6a4b8da66d04395670 to your computer and use it in GitHub Desktop.
Save arduinka55055/4f5c625ed3fd5e6a4b8da66d04395670 to your computer and use it in GitHub Desktop.
"""
Finally you can transfer asgi with sockets and do some kind of microservices
This code smells horribly. it needs thread safety and other improvements
But anyways, it is more like proof of concept. will be updated later for better performance and stability
"""
from starlette.responses import HTMLResponse
from asyncio.streams import StreamWriter
from typing import Any
from starlette.types import Receive, Scope
import socket,asyncio
import pickle
async def app(scope, receive, send):
"""
get data from uvicorn and send to socket
then get reply and send it
"""
assert scope['type'] == 'http'
reader, writer = await asyncio.open_unix_connection('/tmp/asgi_sock')
while True:
aaa=await receive()
writer.write(pickle.dumps([scope,aaa]))
await writer.drain()
while True:
request = bytearray()
#while True:
# request += await reader.read(1024)
# reader.feed_eof()
# if reader.at_eof():
# break
request = await reader.readuntil(b"SYNC")
read_result = pickle.loads(request[:-4])
print(read_result)
await send(read_result)
async def remoteapp(scope, receive, send):
"""
our app to serve
"""
assert scope['type'] == 'http'
a=HTMLResponse(content="foo", status_code=200)
await a(scope,receive,send)
def receivefabric(text):
async def receivee():
return text
return receivee
#dodgy ways to send data
def sendfabric(writer:StreamWriter):
async def sendd(data):
writer.write(pickle.dumps(data))
writer.write(b"SYNC")
await writer.drain()
return sendd
#UNIX socket client
async def handle_client(reader:asyncio.StreamReader, writer:asyncio.StreamWriter):
request = bytearray()
while True:
request += await reader.read(1024)
reader.feed_eof()
if reader.at_eof():
break
scope,read_result = pickle.loads(request)
await remoteapp(scope,receivefabric(read_result),sendfabric(writer))
writer.close()
#UNIX socket server
async def run_server():
server = await asyncio.start_unix_server(handle_client, '/tmp/asgi_sock')
async with server:
await server.serve_forever()
try:
loop = asyncio.get_running_loop()
except RuntimeError: # 'RuntimeError: There is no current event loop...'
loop = None
if loop and loop.is_running():
print('Async event loop already running. Adding coroutine to the event loop.')
tsk = loop.create_task(run_server())
else:
print('Starting new event loop')
asyncio.run(run_server())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment