Уведомления

Группа в Telegram: присоединиться

#1 Янв. 10, 2019 10:10:39

Pit
Зарегистрирован: 2018-12-26
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Async Await =>tornado+asyncio+aiomysql+разбиение по папкам+тесты

Если все в одном месте (исключая tornado) то все просто + есть примеры. Но когда надо разбить по папкам (создать слоистую структуру), то много вопросов:
Так например есть слои BLL(Service), DAL(Connector, Repository), WebApi(Api,Run)
Пример без слоев для DAL:

 conn = await aiomysql.connect(host=config.get('DataBase', 'host'), port=3306, user=config.get('DataBase','user'), password=config.get('DataBase', 'password'), db='testdb', loop=loop)
cur = await conn.cursor()
await cur.execute("SELECT Host,User FROM user")
r = await cur.fetchall()
await cur.close()
conn.close()

Как бы все просто, но в слоях, я так понимаю в Connector будет типа:
 class Conenction():
    def __init__(self):
        self.conn = None
    async def getConnection(self):
        if self.conn is None:
            await self.__connect()
        if not self.conn.is_connected():
            await self.__connect()
        return self.conn
    async def __connect(self):
        self.conn = await aiomysql.connect(host=config.get('DataBase', 'host'), port=3306, user=config.get('DataBase','user'), password=config.get('DataBase', 'password'), db='testdb', loop=loop)

а в репозитории я также буду писать async/await везде??!, где использую Connection, например :
 class Repository():
    def __init__(self):
        self.cn = Conenction()
    async def insert(self, item):
        try:
            self.cnn = await self.cn.getConnection()
            self.cur = await self.cnn.cursor()
            sql = InsertNewSMS
            val = (item.text, item.phoneNumber)
            await self.cur.execute(sql, val)
            await self.cnn.commit()
        except Exception as e:
            logging.critical("insertSms "+ str(e))
        finally:
            if self.cur:
                await self.cur.close()
            if self.cnn:
                await self.cnn.close()

То есть надо ли в репозитории, а затем и в сервисе в методах писать Async/await () и если где-то не написан, то код станет синхронным или он будет частично асинхронным??

И еще вопрос, в классе Conenction для подключения используется loop, если добавлю tornado, а там также loop, то надо ли будет этот loop вынести в отдельный файл и его подключить для Conenction и Run:
файл Loop
 ioloop = asyncio.get_event_loop()
и уже ioloop использовать для инициализации в Conenction для поля loop, а для торнадо тогда как получается в Run:
 application = tornado.web.Application([
    (r'/send', Send)
])
if __name__ == "__main__":
    application.listen(config.get("WebApi", "port"))
# как то надо задействовать ioloop, но как?
    tornado.ioloop.IOLoop.instance().start()#явно не так

И вот как задействовать для торнадо ioloop?

Отредактировано Pit (Янв. 10, 2019 10:12:19)

Офлайн

#2 Янв. 10, 2019 10:22:49

Pit
Зарегистрирован: 2018-12-26
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Async Await =>tornado+asyncio+aiomysql+разбиение по папкам+тесты

По идее написать
ioloop.IOLoop.instance().start()

и ioloop тот же самый как для Conenction, так и для торнадо

Офлайн

#3 Янв. 11, 2019 13:59:14

Pit
Зарегистрирован: 2018-12-26
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Async Await =>tornado+asyncio+aiomysql+разбиение по папкам+тесты

Нашел примерчик:

 class PoolHandler(web.RequestHandler):
    async def get(self):
        pool = self.application.pool
        async with pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute("SELECT * FROM users_account LIMIT 1")
                ret = await cur.fetchone()
                print(ret)
        self.finish("ok")
class App(web.Application):
    def __init__(self, pool):
        settings = {
            'debug': True
        }
        self._pool = pool
        super(App, self).__init__(
            handlers=[
                (r'/pool', PoolHandler),
            ],
            **settings)
    @property
    def pool(self):
        return self._pool
async def init_db_pool(loop):
    return await aiomysql.create_pool(host='127.0.0.1', port=3306,
                                      user='root', password='root',
                                      db='hydra', loop=loop)
def init_app(pool):
    app = App(pool)
    return app
if __name__ == '__main__':
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    tornado_asyncio.AsyncIOMainLoop().install()
    loop = asyncio.get_event_loop()
    pool = loop.run_until_complete(init_db_pool(loop=loop))
    app = init_app(pool=pool)
    server = httpserver.HTTPServer(app, xheaders=True)
    server.listen(5070)
    loop.run_forever()

Но этот пример точно не будет работать на винде, так как uvloop используется + tornado_asyncio вроде как уже старенький и в 3.6 его уже нет.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version