1

I have an event loop with coroutine method using asyncio.

I enthusiast to looking for an equivalent of the following example using uvloop instead.

Here's a simple asyncio event loop example:

import asyncio

async def read(**kwargs):
    oid = kwargs.get('oid', '0.0.0.0.0.0')
    time = kwargs.get('time', 1)
    try:
        print('start: ' + oid)
    except Exception as exc:
        print(exc)
    finally:
        await asyncio.sleep(time)
        print('terminate: ' + oid)


def event_loop(configs):
    loop = asyncio.get_event_loop()

    for conf in configs:
        asyncio.ensure_future(read(oid=conf['oid'], time=conf['time']))

    return loop

if __name__ == '__main__':
    snmp_configurations = [
        {'time': 5, 'oid': '1.3.6.3.2.4'},
        {'time': 6, 'oid': '1.3.6.3.5.8'},
    ]  # TODO :: DUMMY
    loop = event_loop(snmp_configurations)
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        print("Closing Loop")
        loop.close()

Question:

  • How to reform the above snippet code by using uvloop?

  • Is the following change correct for using uvloop with more performance?

    import uvloop
    
    def event_loop(configs):
        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())  # TODO  :: uvloop.
        loop = asyncio.get_event_loop()
    
     `   for conf in configs:
            asyncio.ensure_future(read(oid=conf['oid'], time=conf['time']))
    
        return loop
    

[NOTE]:

  • uvloop claims that makes asyncio 2-4x faster.
Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150

1 Answers1

6

Just set event loop policy before you call asyncio.get_event_loop().

import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

async def read(**kwargs):
    oid = kwargs.get('oid', '0.0.0.0.0.0')
    time = kwargs.get('time', 1)
    try:
        print('start: ' + oid)
    except Exception as exc:
        print(exc)
    finally:
        await asyncio.sleep(time)
        print('terminate: ' + oid)


def event_loop(configs):
    loop = asyncio.get_event_loop()

    for conf in configs:
        asyncio.ensure_future(read(oid=conf['oid'], time=conf['time']))

    return loop

if __name__ == '__main__':
    snmp_configurations = [
        {'time': 5, 'oid': '1.3.6.3.2.4'},
        {'time': 6, 'oid': '1.3.6.3.5.8'},
    ]  # TODO :: DUMMY
    loop = event_loop(snmp_configurations)
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        print("Closing Loop")
        loop.close()

Yes, this code is correct. You can set event loop policy after imports.

import uvloop
import asyncio
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())  # TODO  :: uvloop.

def event_loop(configs):

    loop = asyncio.get_event_loop()

    for conf in configs:
        asyncio.ensure_future(read(oid=conf['oid'], time=conf['time']))

    return loop
Rezvanov Maxim
  • 346
  • 1
  • 7
  • Thank for answer, but will it really have an effect on its performance enhancement? – Benyamin Jafari Nov 03 '18 at 10:18
  • 1
    @BenyaminJafari i never used `uvloop` in production. [This](https://github.com/MagicStack/uvloop/issues/47#issuecomment-239841622) can be helpful. – Rezvanov Maxim Nov 03 '18 at 10:24
  • [uvloop](https://github.com/MagicStack/uvloop) claims that its speed is 2-4x faster than the `asyncio`. So I will get the profiling with `uvloop` and pure `asyncio`. +1 – Benyamin Jafari Nov 03 '18 at 10:31
  • @BenyaminJafari these benckmarks never tells you, how faster your application will working. Just test it. – Rezvanov Maxim Nov 03 '18 at 10:38
  • @BenyaminJafari because your app have specific purposes, but benchmarks code just tests performance between frameworks. – Rezvanov Maxim Nov 03 '18 at 10:46
  • 1
    No, I mean was that get a benchmark in my actual code with the real data by using pure `asyncio` and `uvloop` and choose between them. – Benyamin Jafari Nov 03 '18 at 11:45