Dimitri Molenaars 1186170 Posted May 16, 2016 at 04:17 PM Posted May 16, 2016 at 04:17 PM I'm writing a plugin for Schiphol controllers which contacts our gateplanner webpages and displays that information inside euroscope (plugin source). When testing I noticed something curious. The gateplanner API has 2 endpoints: a testing endpoint that'll reply to callsigns in a pre-determined log file. the live endpoint that'll reply to callsigns currently on the network. Between these 4 tests, the code hasn't changed, with the exception of the GP_API_ENDPOINT definitions. Debug compile settings, test endpoint = success. Release compile settings, test endpoint = success. Debug compile settings, live endpoint = success. Release compile settings, live endpoint = fail. All the parts seem to be working, until they're put together. Anybody have any ideas as to why this would happen? Signed, Dimitri "Tyrope" Molenaars Link to comment Share on other sites More sharing options...
David Zhong Posted May 18, 2016 at 04:33 AM Posted May 18, 2016 at 04:33 AM When you say "fail", do you mean that it doesn't compile or it doesn't run correctly? David Zhong Link to comment Share on other sites More sharing options...
Dimitri Molenaars 1186170 Posted May 19, 2016 at 05:33 PM Author Posted May 19, 2016 at 05:33 PM When you say "fail", do you mean that it doesn't compile or it doesn't run correctly? I should've elaborated: When I say fail I mean it doesn't display the information in the tag item created, as if it never calls the function. Signed, Dimitri "Tyrope" Molenaars Link to comment Share on other sites More sharing options...
David Zhong Posted May 20, 2016 at 10:54 AM Posted May 20, 2016 at 10:54 AM I'm trying to follow your code. How is it that CGatePlannerPlugIn::GetAPIInfo doesn't block? From my reading of the code, it looks like that that method should cause the GUI to freeze while the socket request is under way. David Zhong Link to comment Share on other sites More sharing options...
Pierre Ferran Posted May 20, 2016 at 12:00 PM Posted May 20, 2016 at 12:00 PM I was reading the code and though the same, you'll need to thread your asio request, or switch to async asio, see an example here: https://stackoverflow.com/questions/22490193/boost-asio-async-http-client-timeout (there is one in the docs but I can't find it anymore). I would also recommend using boost Property tree to p[Mod - Happy Thoughts] Json and not your your own implementation, that might avoid parsing errors that you did not account for, and will cleanup your code, see an example here: http://stackoverflow.com/a/15207050 and the docs here http://www.boost.org/doc/libs/1_61_0/doc/html/property_tree.html If you can't figure out what's happening, I would suggest shoving a bunch of debug output in every method, to see what actually gets called or not. My instinct would point to the fact that your live environment uses a whole bunch of different callsigns/gates/data that your testing endpoint does not contain, because you can't really predict what the actual callsigns used will be on the network. vSMR Plugin for EuroScope Link to comment Share on other sites More sharing options...
Dimitri Molenaars 1186170 Posted May 20, 2016 at 03:40 PM Author Posted May 20, 2016 at 03:40 PM I'm trying to follow your code. How is it that CGatePlannerPlugIn::GetAPIInfo doesn't block? From my reading of the code, it looks like that that method should cause the GUI to freeze while the socket request is under way. I was reading the code and though the same, you'll need to thread your asio request, or switch to async asio, see an example here: https://stackoverflow.com/questions/22490193/boost-asio-async-http-client-timeout (there is one in the docs but I can't find it anymore). Hadn't thought of that, and that explains the GUI freeze upon plugin load (oddly enough, not every 30 seconds, when it should request new data for every tag in the arrival list) Top of the issues list! One question however: It appears that OnGetTagItem doesn't need a 'return' statement, you just [Mod - Happy Thoughts]ign a value to sItemString. How would this work async, since I'd still need to keep a reference to that variable? Would a p[Mod - Happy Thoughts]-by-reference work? I would also recommend using boost Property tree to p[Mod - Happy Thoughts] Json and not your your own implementation, that might avoid parsing errors that you did not account for, and will cleanup your code, see an example here: http://stackoverflow.com/a/15207050 and the docs here http://www.boost.org/doc/libs/1_61_0/doc/html/property_tree.html Thanks, will definitely have a close look at this. If you can't figure out what's happening, I would suggest shoving a bunch of debug output in every method, to see what actually gets called or not. My instinct would point to the fact that your live environment uses a whole bunch of different callsigns/gates/data that your testing endpoint does not contain, because you can't really predict what the actual callsigns used will be on the network. Short of the callsigns, all possible data that comes from the webAPI in live are on the testing endpoint. (the entire reason the test endpoint exists.) You might be right regarding the callsigns part, however. Signed, Dimitri "Tyrope" Molenaars Link to comment Share on other sites More sharing options...
David Zhong Posted May 21, 2016 at 05:42 AM Posted May 21, 2016 at 05:42 AM One question however: It appears that OnGetTagItem doesn't need a 'return' statement, you just [Mod - Happy Thoughts]ign a value to sItemString. How would this work async, since I'd still need to keep a reference to that variable? Would a p[Mod - Happy Thoughts]-by-reference work? In your async "onsuccess" callback, you should write to your local storage (i.e. m_knownFlightInfo). OnGetTagItem should only read from m_knownFlightInfo and "ask" for an API request if the data is missing. If it cannot find the required information in m_knownFlightInfo, it should simply display a generic value (e.g. "----", "NOGATE", etc.) An easy mistake to make when using asynchronous requests, is to accidentally create too many identical requests. I would [Mod - Happy Thoughts]ume that OnGetTagItem would get called very frequently (on every draw?), which would mean that a new request would be made on every draw until the first request returns and writes to the local storage. You might create a new method that takes a callsign and checks against a std::vector of current requests before making a new API request. I'm not sure how asio async works, but if it uses threads, you will also need to be careful with your data synchronisation. Otherwise you will end up with subtle bugs involving race conditions and potentially corrupted data. For that reason and the difficultly in debugging threads, I tend to avoid threads and prefer polling libraries even though they may be a bit less efficient. David Zhong Link to comment Share on other sites More sharing options...
Recommended Posts