Jump to content

You're browsing the 2004-2023 VATSIM Forums archive. All content is preserved in a read-only fashion.
For the latest forum posts, please visit https://forum.vatsim.net.

Need to find something? Use the Google search below.

Plug-in works on debug compile, but not on release compile.


Dimitri Molenaars 1186170
 Share

Recommended Posts

Dimitri Molenaars 1186170
Posted
Posted

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

David Zhong
Posted
Posted

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

Dimitri Molenaars 1186170
Posted
Posted
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

David Zhong
Posted
Posted

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

Pierre Ferran
Posted
Posted

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.

Link to comment
Share on other sites

Dimitri Molenaars 1186170
Posted
Posted
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

David Zhong
Posted
Posted
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

 Share