2

I use the uwsgi to start my flask server, which has 15 workers, and I want to get the call times for each api, and return the result like:

{
    "api/students": 10,
    "api/teachers": 20,
    ...
}

I add the before_request handle for app:

@app.before_request
def before_request_handler():
    # here to do statistics
    # count += 1

And I write an api to get the count value. However, I found that each time the values was not increment, because there're multi workers, each time I just got one worker's call times

So, my question is how to collect all the request call times from all the workers in Flask?

Jimmy Guo
  • 1,288
  • 1
  • 9
  • 24
  • I don't need any packages, just code solution, thanks – Jimmy Guo Sep 14 '17 at 06:31
  • There is a global variable `g` for managing shared variable all over the app. you can use a default `dict` that keeps name (url) and value (how many times the URL is invoked) in `before_request` decorated function. I am not sure about thread safety yet. But please be sure about that multiple workers do not change the value of URL dict in a same time. – Saiful Azad Sep 14 '17 at 06:38
  • 1
    no simple solution inside flask, but I guess you could just do logging api call time and do the stats on logs, which is much easier to me. – georgexsh Sep 14 '17 at 06:44

1 Answers1

0

You cannot track counters like this across workers as you'll run into problems like:

  • Assuming workers are running in separate processes, you'll need to reconcile your counters
  • Assuming workers are running in threads, you'll need to make sure your counters are thread safe.

In the comment section, it is suggested to use the g object, this won't work as g is global per request only. After each request, g gets torn down.

The correct way to implement counters is to use a 3rd party data store. A database can do the job (concurrency can be handled in transactions) but it's recommended to use a caching service like Redis or Memcached.

Ivan Choo
  • 1,997
  • 15
  • 15