Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very slow response #18

Open
MyraBaba opened this issue Nov 30, 2020 · 30 comments
Open

Very slow response #18

MyraBaba opened this issue Nov 30, 2020 · 30 comments
Assignees

Comments

@MyraBaba
Copy link

MyraBaba commented Nov 30, 2020

Hi,

I am testing example/form_server both my Mac Pro and also raspi4 . its super slower than the python (fastapi) ? almost 10 times slower

Why is this ? am I missed something ?

Best

@MyraBaba
Copy link
Author

MyraBaba commented Dec 2, 2020

Any idea @sprinfall

@sprinfall
Copy link
Owner

Any idea @sprinfall

Because the file data is all cached in the memory. What is the size of your test file?

@MyraBaba
Copy link
Author

MyraBaba commented Dec 4, 2020

its 10K image file . almost 1 second for each post very slow. There should be something that missed . Test yourself please

@MyraBaba
Copy link
Author

MyraBaba commented Dec 4, 2020

I am posting with curl for test :

curl -X POST "http://127.0.0.1:8000/predict/image" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "name=mmm" -F "file=@/Users/xxx/Charles_Bronson/Charles_Bronson_0003.jpg;type=image/jpg"

@MyraBaba
Copy link
Author

MyraBaba commented Dec 4, 2020

@sprinfall
if you advise I would love to use your solution in our small non profit org. production.

Best

@sprinfall
Copy link
Owner

@MyraBaba Please feel free to use.
I just pushed the code with a small improvement for the parsing of form data. I'm still investigating the performance issue.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 7, 2020

Ok I will test the new code . But you wll see the slowness of the response.. Something stalling / delaying.

Best

@sprinfall
Copy link
Owner

Ok I will test the new code . But you wll see the slowness of the response.. Something stalling / delaying.

Best

Hi, I use Python Requests library to post a JPG file, the 1s delay disappears. Just for your information.

BTW, if you want to post large files, please consider to NOT use multipart form data. Please use a normal post with streaming instead.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 8, 2020

Hi @sprinfall

My files mostly around 10K to 30K so small ones. What is the curl post and python post differences. ?
Would you mind to share your python / Post code?

Best

@sprinfall
Copy link
Owner

@MyraBaba

import requests

url = 'http://127.0.0.1:8000/upload'
files = {'file': open('path/to/jpg', 'rb')}

r = requests.post(url, files=files)
print(r.text)

@MyraBaba
Copy link
Author

MyraBaba commented Dec 8, 2020

@sprinfall can you test in aloop ?

for i in range(100):
r = requests.post(url, files=files)
print(i , " " ,r.text)

gives error

@sprinfall
Copy link
Owner

@MyraBaba Sorry, that issue was introduced by my last small optimization. I have reverted the change.
I will keep you informed when I find a better solution to optimize the performance of form data parsing.

@sprinfall sprinfall self-assigned this Dec 10, 2020
@MyraBaba
Copy link
Author

@sprinfall any perf fix?

@sprinfall
Copy link
Owner

sprinfall commented Dec 21, 2020

@sprinfall any perf fix?

I have two suggestions:

  1. Use a larger buffer to read the requests. I tested using 10240, it did improve the speed. Please see new added method of Server: set_buffer_size().
  2. Set log level to USER to avoid logging VERB and INFO logs.

@MyraBaba
Copy link
Author

I will test right today and let you know.
Best

@MyraBaba
Copy link
Author

Hi @sprinfall

I tested with :

import requests
from time import sleep
url = 'http://127.0.0.1:8000/upload'
files = {'file': open('/Users/tulpar/Projects/build-drogon-Desktop_Qt_5_13_2_clang_64bit-Debug/Charles_Bronson_0003.jpg', 'rb') , 'name':"ALALU"}
i= 99

for i in range(100):
    r = requests.post(url, files=files)
    print(i , "    " ,r.text)

Got errors:

form parts: 2
name: file
name: name
2020-12-21 13:38:50.697, WARN, main, connection.cc, 44, Socket shutdown error (Socket is not connected).
2020-12-21 13:38:57.077, ERRO, main, request_parser.cc, 131, Invalid part data.
2020-12-21 13:38:57.077, ERRO, main, connection.cc, 114, Failed to parse HTTP request.
2020-12-21 13:38:57.077, ERRO, main, connection.cc, 101, Socket read error (Bad file descriptor).
2020-12-21 13:38:57.077, WARN, main, connection.cc, 44, Socket shutdown error (Bad file descriptor).
2020-12-21 13:39:17.295, ERRO, main, request_parser.cc, 131, Invalid part data.
2020-12-21 13:39:17.295, ERRO, main, connection.cc, 114, Failed to parse HTTP request.
2020-12-21 13:39:17.296, ERRO, main, connection.cc, 101, Socket read error (Bad file descriptor).
2020-12-21 13:39:17.296, WARN, main, connection.cc, 44, Socket shutdown error (Bad file descriptor).
2020-12-21 13:39:36.575, ERRO, main, request_parser.cc, 131, Invalid part data.
2020-12-21 13:39:36.575, ERRO, main, connection.cc, 114, Failed to parse HTTP request.
2020-12-21 13:39:36.576, ERRO, main, connection.cc, 101, Socket read error (Bad file descriptor).
2020-12-21 13:39:36.576, WARN, main, connection.cc, 44, Socket shutdown error (Bad file descriptor).

@sprinfall
Copy link
Owner

I will look into it tonight.

@sprinfall
Copy link
Owner

@MyraBaba I found that from the second request in the loop, the file data sent was empty. Please try to move the files definition into inside of the loop. Meanwhile, I made a quickfix to handle this empty form part data. Please pull the code. But I will do more test tomorrow.

@MyraBaba
Copy link
Author

@sprinfall Hi again,

I love the webcc its fantastic work. Thanks.

Do you think that we can embed it to our Qt Project ? Do you Qt ?
It will be great if we get data as signal/slot mechanism

@MyraBaba
Copy link
Author

@sprinfall do you know Qt platform ?

@sprinfall
Copy link
Owner

sprinfall commented Jan 21, 2021

@sprinfall Hi again,

I love the webcc its fantastic work. Thanks.

Do you think that we can embed it to our Qt Project ? Do you Qt ?
It will be great if we get data as signal/slot mechanism

For signal/slot mechanism, you have to use QNetworkAccessManager: https://doc.qt.io/qt-5/qnetworkaccessmanager.html
But it only has client API. Is your Qt project a client or server?

@MyraBaba
Copy link
Author

MyraBaba commented Jan 21, 2021 via email

@MyraBaba
Copy link
Author

MyraBaba commented Jan 21, 2021 via email

@sprinfall
Copy link
Owner

@MyraBaba

  1. Run the REST server in a thread in your Qt application (see the server_states.cc example).
  2. In RestApi (the View), emit signals of some global (or Singleton) QObject after the requests have been handled (in your case, images are uploaded).
  3. In your Qt widgets, connect the signals of that global (or Singleton) object to some slots.
    I will come back to you later.

@MyraBaba
Copy link
Author

MyraBaba commented Jan 21, 2021 via email

@sprinfall
Copy link
Owner

@MyraBaba
Just added an example for Qt based on my understanding: example/qt_app_server. Hope it helps.

@MyraBaba
Copy link
Author

@sprinfall Thanks a lot. I tested.

Now I try to put same way to in my QTHREAD logic. Do you think it is also work in the QTHREAD created by the mainwindow ?

Best

@MyraBaba
Copy link
Author

@sprinfall Thanks a lot .

what is the proper way to pass below objects which I can use inside the


`webcc::ResponsePtr Handle(webcc::RequestPtr request) override {


}`

the objects :


`. bc::Landmarker *Landarker = new bc::Landmarker;
    bc::facenet *Recognizer = new bc::facenet;
    bc::Aligner *Aligner          = new bc::Aligner;
    Recognizer->Init("/home/alp2080/Projects//data/models");
    Landarker->Init("/home/alp2080/Projects//data/models");

`

how can I do this to use also inside webcc::ResponsePtr Handle(webcc::RequestPtr request) override ?

whenever I start to think I am something at c++ always hitting such a wall.

Appreciate your help.

I mentioned and advise your webcc in Qt forum.

Best

@sprinfall
Copy link
Owner

@MyraBaba You want to access Landmarker, Facenet and Aligner from the overridden Handle() method, right?
These objects look like some algorithm based on pre-trained models. So I think they are shared by all requests and related to each other. I suggest you to put them into a new class and create a single global variable (or singleton) of this class, then you can access it from everywhere. You should initialize this new global variable in your main() function.

@sprinfall
Copy link
Owner

@sprinfall Thanks a lot. I tested.

Now I try to put same way to in my QTHREAD logic. Do you think it is also work in the QTHREAD created by the mainwindow ?

Best

I suggest to use C++ std::thread to run the HTTP server. QThread is quite a different thing. It has extra event loop?
So, keep your Views (sub-classes of webcc::View) away from QObject. Do the server part in pure C++ way. Emit signals, if necessary, from some other QObject for notifying the GUI thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants