Results 1 to 10 of 10

Thread: Asynchronous server msg vs synchronous functions

  1. #1
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Asynchronous server msg vs synchronous functions

    Hi.
    First 'n in advance, sorry for my poor English, I'm french

    the context : I'm developping some kind of network layer in order to use IRC servers for doing point to multipoint communication between clients without the need of a dedicated server.

    Here is my problem :

    I would like to create a class IRCConnexion that holds a QSocket and manages every message sent to /received by the server.
    This class will have functions like this one :
    QDict<Channel>* getChannelList();

    This function would do 3 things :
    - emitting a request message for the channel list.
    - getting each server's response and putting them into the QPtrList
    - returning the QDict.

    This function could be called in a function inside the main window like this :

    ptr = getChannelList();
    if ( ptr.find(a_channel_name) ) { do_something; }

    But, as this kind of request takes a while, I would like to let the main window having a chance to process other things while the list is downloaded from the server (like repainting, processing events...)

    As far as I know, we can't instanciate QSocket in another thread than the main one.

    How can I do that kind of thing ?

    Many thanks in advance if you take a little time to give me ways to explore

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    You don't have to use multithreading, instead you can use signals & slots mechanism. Just make your application fully event-driven and don't block the event loop.

    Note that in Qt3 you can't use QSocket in a non-GUI thread, because it requires an event loop. So if you want to have multiple threads, you will have to use QSocketDevice instead.

  3. #3
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Thumbs up Re: Asynchronous server msg vs synchronous functions

    Quote Originally Posted by jacek
    Just make your application fully event-driven and don't block the event loop.
    Do you mean I should write a getChannelList() like this :
    QPtrList<Channel> getChannelList() {
    while (!get_list_finished) {
    do some job...
    (QApplication::eventLoop())->processEvent();
    }
    return(the_QPtrList);
    }

    If it's what you said, what will be the limitations of that kind of code ? I mean, will QSocket continue to react on new incoming data while the channel list retieving ? Will the user be able to interact with the interface ?
    And if the user can still interact with the interface, what would happen if we call simultaneously two times the function ?

    Anyway, many thanks for this tips

    PS: sorry for those newbie questions, but i'm new in qt development even if I'm coding in c++ since a while.

  4. #4
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    I've made a test : it works fine :-)

    The only thing I would like to know is if there some limitations, especially with multiple simultaneous calls on the same function.

    Anyway, many, many thanks :-)

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    Quote Originally Posted by nouknouk
    Do you mean I should write a getChannelList() like this :
    Qt Code:
    1. QPtrList<Channel> getChannelList() {
    2. while (!get_list_finished) {
    3. do some job...
    4. (QApplication::eventLoop())->processEvent();
    5. }
    6. return(the_QPtrList);
    7. }
    To copy to clipboard, switch view to plain text mode 
    Well, I thought about something more like:
    Qt Code:
    1. void SomeClass::channelReceived( SomeType whatever ) // slot
    2. {
    3. add channel to the list
    4. if ( list complete ) emit channelListReady( channelList );
    5. }
    6.  
    7. void SomeClass::channelListReady( SomeList channelList ) // slot
    8. {
    9. do something with that list;
    10. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    The solution with signals and slots is the one I already have coded

    But, for me, it's not a good one, because for some type of request it would be too complex to handle :
    Maybe my first example wasn't relevant enough. Here is another one : a function like isUserConnected(QString nickName) : that function could be called in several different contexts and having 'to cable' signals and slots each time I need to know if a user exists is (to my mind) too complex and would result in totally unreadable code.

    That's why I think that the solution with processEvents() is a good one. Due to this technology, I think that I can't start more than one request at a time (*). So I've to write some kind of 'request queue'.
    What do you think of that ?

    --------------------------------------------------------------------------
    (*) because if there is two imbriqued requests, the first called can be finished as long as the second one has been finished before. Here is an exemple (is it correct ?) of what should be the call stack of my app if a user make two requests a the same time : a getChannelList() and before its end, a isUserConnected() :

    onRefreshList() slot called when the user click a "refresh channel list" buttton
    -->getChannelList() (#1)
    ---->while (!finished) processEvents() (#2)
    ------>onSearchUser() slot called when the user clicks a "search user" button
    -------->isUserConnected() (#3)
    ---------->while (!finished2) processEvents() (#4)

    At this time. If the channel list request is finished, the program wont iterate the (#2) until isUserConnected (#3) has returned. Am I right ?
    --------------------------------------------------------------------------
    Last edited by nouknouk; 2nd February 2006 at 08:54.

  7. #7
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    Well, It works almost fine, but there's still a (little) issue :

    First : here is a sample code of my getChannelListNOW() function:

    Qt Code:
    1. IRCChannelDict& IRCServer::getChannelListNOW() {
    2. _channelListUpdateOk = false;
    3. sendLineThruSocket("LIST");
    4. while(!_channelListUpdateOk) {
    5. QApplication::eventLoop()->processEvents(QEventLoop::AllEvents);
    6. }
    7. return _channelDict;
    8. }
    9. // _channelListUpdateOk is set to true by the socket message parser
    10. // when it detects the end of the channel's list transmission.
    To copy to clipboard, switch view to plain text mode 

    Another similar function is getTimeOfServerNOW().

    In my interface, i've got two buttons connected to two main window's slots in order to make a call of those functions.

    I tried to click very fast on getTimeOfServer and immediatly after on getChannelList.
    As the getTimeOfServerNOW is much quicker (less than 500ms), It should respond BEFORE getChannelListNOW() (2 or 3 seconds).
    But it don't : in this test, I get the opposite : TimeOfServer respond AFTER ChannelList.

    I think it's due to the call stack (see below), the first while statement can't be reached until getChannelListNOW() has ended.

    Qt Code:
    1. onGetTimeOfServer() // slot called by the appropriate button.
    2. getTimeOfServer() (#1)
    3. while (!finished) processEvents() // inside getTimeOfServer() func
    4. onGetChannelList() slot called inside 'processEvent'
    5. getChannelListNOW() (#3)
    6. while (!finished2) processEvents() (#4)
    To copy to clipboard, switch view to plain text mode 

    In other words, if more than one such request is called at a time, all the request will return only when the longest one has finished. This is not really a big problem for me, but do you have an idea on how to bypass this problem ?

    Anyway, many thanks for your 'event' tip

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    Since you are using a single socket you could create an object that mimics IRC server.
    Qt Code:
    1. class IRCServer : public QObject
    2. {
    3. Q_OBJECT
    4. public:
    5. // ...
    6.  
    7. public slots:
    8. void listChannels();
    9. // other IRC commands
    10.  
    11. signals:
    12. void channelFound( IRCChannel & ); // or channelsFound( IRCChannelList& )
    13. // ...
    14. };
    To copy to clipboard, switch view to plain text mode 
    Methods like listChannels() would send commands to the server and when server sends a response you will would have to parse it and emit a proper signal. This should eliminate the need for qApp->processEvents().

  9. #9
    Join Date
    Feb 2006
    Posts
    26
    Thanked 2 Times in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    That's what I already have coded.
    But for some functions I need somethings that look like an immediate response.

    Indeed, for example a function isUserConnected(QString nickname).

    isUserConnected would be called in a lot of different contexts (for different functions)

    If I write those :
    void checkUserConnected(QString nick); (equivalent to listChannels in your example)
    userConnectedResponse(bool); (the signal, equivalent to channelFound)

    I will have, for each function that would use checkUserConnected, to implement two functions.
    1/ The first part of the code (before I need to check the user) in the first function
    2/ The second part of the code (after checking) in a second function (ie, a slot).

    That don't look really 'beautiful'. I will quickly get enormous interfaces for my classes.
    Moreover, if I want to use the checkUser func again, in another part of the code , I will have to connect / disconnect signals and slots at each call :-/

    That don't look really nice for me. Even more if you know that this 'framework' has to be easy reusable...

    Don't you think so ?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Asynchronous server msg vs synchronous functions

    Quote Originally Posted by nouknouk
    I will have, for each function that would use checkUserConnected, to implement two functions.
    1/ The first part of the code (before I need to check the user) in the first function
    2/ The second part of the code (after checking) in a second function (ie, a slot).
    Maybe you could cache this information and add a QTimer to update the cache from time to time?

    That don't look really nice for me. Even more if you know that this 'framework' has to be easy reusable...

    Don't you think so ?
    I guess it all depends on the logic you want to implement. Event-driven approach doesn't work well with all kinds of programs.

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.