Results 1 to 6 of 6

Thread: Synchronous Http (Good reason)

  1. #1
    Join Date
    Apr 2008
    Posts
    3
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Wink Synchronous Http (Good reason)

    Hello,

    First, I understand that asynchronous QHttp API is usually the right way to go. However, I have a problem that is very sequential in nature, which makes any async. solution ugly.

    Briefly, the problem is as following:

    Fetch document R1, parse R1, depending on what's found fetch some document R2, parse R2, depending on what's found there, fetch and parse some document R3, etc.

    There are two asynchronous approaches (using QHttp) I can come up with:

    (1) Create one giant state machine (keep the current state in some member variable(s) and have bunch of switch statements) - UGLY.

    (2) Create a separate class for every type of document R1, R2, R3, etc. - UGLY.

    A much cleaner solution would be to create a sync. way of fetching documents via Http. Then, I would not need to further complicate already complicated logic. I could also place all sync code in a separate thread to keep the QT even loop running.

    QUESTION: What is the best way to implement synchronous Http functionality? Al I can think of is something along the lines of:

    requestId_ = qHttp_->get("http://google.com");
    while(qHttp_->hasPendingRequests()) {
    qApp->processEvents();
    }

    plus have a slot connected to the QHttp requestFinished() signal to copy whatever data is there when the requestId_ is finished...

    Any better ideas?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Synchronous Http (Good reason)

    I'd emulate a blocking call using non blocking calls. You can even spin your own QEventLoop there if you want.

  3. The following user says thank you to wysota for this useful post:

    umbrella (4th April 2008)

  4. #3
    Join Date
    Apr 2008
    Posts
    3
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Synchronous Http (Good reason)

    Yes, this is what I thought... First, I tried creating and exec()-ing QEventLoop. It worked, but I did not like it, partially because I was not sure how exactly it worked and how expensive it was... The QT docs for QEventLoop are not very good I am afraid

    I think that the solution I have right now is slightly better (it does not interfere with the main even loop), but I may be wrong. Here it is (maybe someone else will find it helpful, the timeout parameter is currently ignored):

    //
    // fetches the file data over http and writes it to the device; returns true if succeeds and false if an error is encountered or the http request is timed-out.
    //
    bool HttpFileFetcher::FetchFile(const QString* url, QIODevice* device, UINT32 timeout) {
    bool rval = IS_TRUE(url != NULL && device != NULL);
    if (rval) {
    QUrl qUrl(*url);

    rval = IS_TRUE(qUrl.isValid());
    if (rval) {
    setHost(qUrl.host());
    requestId_ = get(*url, device);

    while(currentId() != 0) {
    qApp->processEvents();
    }

    rval = !error_;
    }
    }

    return rval;
    }

    //
    // called when the http request is done.
    //
    void HttpFileFetcher::RequestFinishedSlot(int requestId, bool error) {
    if (requestId_ == requestId) {
    if (error) {
    error_ = error;
    Log(MessageFilter::ALERT1) << L"failed to fetch an http resource: " << errorString().toAscii().data() << Log::endl;
    }
    }
    }

    //
    // fetches the file data over http and writes it to the device; returns true if succeeds and false if an error is encountered or the http request is timed-out.
    //
    bool HttpFileFetcher::Fetch(const QString* url, QIODevice* device, UINT32 timeout) {
    HttpFileFetcher fileFetcher;
    return fileFetcher.FetchFile(url, device, timeout);
    }

    //
    // fetches the file data over http and writes it to the buffer; returns true if succeeds and false if an error is encountered or the http request is timed-out.
    //
    bool HttpFileFetcher::Fetch(const QString* url, QByteArray* buffer, UINT32 timeout) {
    bool rval = IS_TRUE(url != NULL && buffer != NULL);
    if (rval) {
    QBuffer device(buffer);
    device.open(QIODevice::WriteOnly);

    rval = IS_TRUE(device.isOpen());
    if (rval) {
    HttpFileFetcher fileFetcher;
    rval = fileFetcher.FetchFile(url, &device, timeout);
    }
    }

    return rval;
    }

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Synchronous Http (Good reason)

    Quote Originally Posted by umbrella View Post
    Yes, this is what I thought... First, I tried creating and exec()-ing QEventLoop. It worked, but I did not like it, partially because I was not sure how exactly it worked and how expensive it was...
    It's the same loop Qt uses for its application loop. I mean similar, not the same instance.

    The QT docs for QEventLoop are not very good I am afraid
    Because it is very rarely used, so there is no point in documenting it too much.

    I think that the solution I have right now is slightly better (it does not interfere with the main even loop), but I may be wrong. Here it is (maybe someone else will find it helpful, the timeout parameter is currently ignored):
    It's not better. It's almost the same, just that any optimizations to the loop performed by QEventLoop (if there are any) are not used by your code.

  6. #5
    Join Date
    Apr 2008
    Posts
    3
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Synchronous Http (Good reason)

    It's not better. It's almost the same, just that any optimizations to the loop performed by QEventLoop (if there are any) are not used by your code.[/QUOTE]

    So how exactly does this work, doesn't another executing QEventLoop block the main QT event loop? Or QT manages to jump from executing one loop to another?

    Thanks.

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Synchronous Http (Good reason)

    Quote Originally Posted by umbrella View Post
    So how exactly does this work, doesn't another executing QEventLoop block the main QT event loop?
    It does. That's the whole point.

    Or QT manages to jump from executing one loop to another?
    Look at how modal dialogs (ones triggered using QDialog::exec()) work - they use the same mechanism, they have an internal event loop.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.