2

I have a ANPR (automated number plate reading) system. Essentially a few cameras configured. These make HTTP POSTs to locations we configure. Our cocktail of problems are such:

  • Our script needs to send this data onto multiple, occasionally slow places.
  • The camera locks up while it's POSTing.

So if my script takes 15 seconds to complete —it can— we might miss a read.

Here's the cut down version of my script at the moment. Apologies for the 3.4 syntax, we've got some old machines on site.

@asyncio.coroutine
def handle_plate_read(request):
    post_data = yield from request.post()
    print(post_data)

    # slow stuff!

    return web.Response()

app = web.Application()
app.router.add_post('/', handle_plate_read)
web.run_app(app, port=LISTEN_PORT)

This is functional but can I push back the 200 to the camera early (and disconnect it) and carry on processing the data, or otherwise easily defer that step until after the camera connection is handled?

Oli
  • 235,628
  • 64
  • 220
  • 299

1 Answers1

3

If I understood your question correctly, you can of course carry on processing the data right after response or deffer it to process even later.

Here's how simple solution can look like:

  1. Instead of doing slow stuff before response, add data needed to do it to some Queue with unlimited size and return response imideately.

  2. Run some Task in background to process slow job that would grab data from queue. Task itself runs parallely with other coroutines and doesn't block them. (more info)

  3. Since "slow stuff" is probably something CPU-related, you would need to use run_in_executor with ProcessPoolExecutor to do slow stuff in other process(es). (more info)

This should work in basic case.

But you should also think over how will it work under heavy load. For example if you grab data for slow stuff quicky, but process it much slower your queue will grow and you'll run out of RAM.

In that case it makes sense to store your data in DB other then in queue (you would probably need to create separate task to store your data in DB without blocking response). asyncio has drivers for many DB, for example.

Mikhail Gerasimov
  • 36,989
  • 16
  • 116
  • 159