Python non blocking multi-client service

dima.olkhov at cell-buddy.com dima.olkhov at cell-buddy.com
Tue Aug 23 09:39:56 EDT 2016


On Tuesday, August 23, 2016 at 4:09:07 PM UTC+3, dimao wrote:
> I am trying to implement multi-client service. The service must be able to:
> 
> connect to the server;
> send/receive messages;
> wait until a new message will be received
> *** Per each client and non blocking
> 
> My current code takes almost 99% CPU usage. Here is the main part of my code :
> 
> 
> PORT    = 33123
> HOST    = '127.0.0.1'
> 
> 
> import asyncio
> import os
> 
> @asyncio.coroutine
> def tcp_echo_client(offset):
> 
>   def send(offset):
>       MSG = """{"ClientId":"%s", % (str(offset))"}"""
> 
>       print("> " + MSG)
>       writer.write((MSG).encode("utf-8"))
> 
> 
>   def recv():
>        msgback = (yield from reader.readline()).decode("utf-8").rstrip()
>        print("< " + msgback)
>        return msgback
> 
>        reader, writer = yield from asyncio.open_connection(HOST, port=PORT)
> 
> 
>        print(reader)
>        print('Waiting 3 sec for response...')
> 
>        while True:
>           response = yield from asyncio.wait_for(reader.readline(), timeout=5.0)
>           print(response)
>           send(offset)
> 
>           yield from asyncio.sleep(0.5)
> 
> @asyncio.coroutine
> def do_work(task_name, work_queue):
>         while not work_queue.empty():
>             queue_item = yield from work_queue.get()
>             print('{0} grabbed item: {1}'.format(task_name, queue_item))
>             asyncio.Task(tcp_echo_client(offset=queue_item))
>             yield from asyncio.sleep(0.1)
> 
> 
> if __name__ == "__main__":
>     q = asyncio.Queue()
> 
>     for x in range(100):
>         q.put_nowait(x)
> 
>     print(q)
> 
>     loop = asyncio.get_event_loop()
> 
>     tasks = [
>         asyncio.async(do_work('task1', q)),
>         asyncio.async(do_work('task2', q)),
>         asyncio.async(do_work('task3', q)),
>         asyncio.async(do_work('task4', q)),
>         asyncio.async(do_work('task5', q)),
>         asyncio.async(do_work('task6', q))
>     ]
> 
>     loop.run_until_complete(asyncio.wait(tasks))
>     loop.run_forever()
>     loop.close()

UPDATED :
PORT    = 33123
HOST    = '127.0.0.1'
LASTLINE = '#'

import asyncio
import os


@asyncio.coroutine
def tcp_echo_client(offset):

    def send(offset):

        MSG = '{'+"ClientId"+':'+"%s" % (str(offset))+'}'

        print("> " + MSG)
        writer.write((MSG ).encode("utf-8"))
        yield from writer.drain()

    def recv():
        msgback = (yield from reader.readline()).decode("utf-8").rstrip()
        print("< " + msgback)
        return msgback

    reader, writer = yield from asyncio.open_connection(HOST, port=PORT)


    print(reader)
    print('Waiting 3 sec for response...')

    while True:
        try:
            response = yield from asyncio.wait_for(reader.readline(), timeout=100000.0)
            print(response)

            if str(response).find('GetClientInfo') > 0:
                send(int(offset))

            yield from asyncio.sleep(0.5)
        except:
            print ('Error')

@asyncio.coroutine
def do_work(task_name, work_queue):
     while not work_queue.empty():
            queue_item = yield from work_queue.get()
            print('{0} grabbed item: {1}'.format(task_name, queue_item))
            asyncio.Task(tcp_echo_client(offset=queue_item))
            yield from asyncio.sleep(0.1)



if __name__ == "__main__":
    q = asyncio.Queue()

    for x in range(1):
        q.put_nowait(x)

    print(q)

    loop = asyncio.get_event_loop()

    tasks = [
        asyncio.async(do_work('task1', q)),
        asyncio.async(do_work('task2', q)),
        asyncio.async(do_work('task3', q)),
        asyncio.async(do_work('task4', q)),
        asyncio.async(do_work('task5', q)),
        asyncio.async(do_work('task6', q))
    ]

    loop.run_until_complete(asyncio.wait(tasks))
    loop.run_forever()
    loop.close()

Thanks



More information about the Python-list mailing list