Is Http async?

I have a function to make http request:

def fn (url)
  req = Sketchup::Http::Request.new(url, Sketchup::Http::POST)
  req.start do |request, response|
    # do something
    return 'Done'
  end
end

The intention of the function is to return ‘Done’ after HTTP result. But it always returns before getting response. How can I prevent the function from returning until Http gets response?

If it was not async, this could have a much simplier API, like

response = req.start()

But instead it is designed that you pass a code block as callback function. Whatever return you use in the callback function will not return from the outer fn function, but only once the inner function is called.

Look into passing a callback function to fn that works on the value you were trying to return, or look into Promises that you can directly return from fn. There is a SketchUp-compatible Promise library.

1 Like

YES.

You cannot. A Ruby method returns when it’s last statement has finished being evaluated and always returns that last value evaluated or nil otherwise.

But … any references local to the method go out of scope when the method returns.
So your req reference will go out of scope and get garbage collected. It is better in practice to use a @var so other methods could access the request object if needed. (Notice how in the documentation persistent @request references are shown?)

We are assuming that your @req reference and method fn are properly wrapped within a custom module.


P.S.: Do not insert spaces between method names and their argument lists. Ruby does not like this and may output warnings to the console. Users may see these warnings and become concerned.

The Ruby Net::Http module is synchronous. But note that it might not work properly in older SU versions. Also, any HTTP request could for unexpected reasons out of your control take a significant time due to network issues - they are much better done as async for the sake of user experience. From the point of a developer it takes some readjustments, but generally the better approach.

2 Likes

This is insane.
We can’t use Net::HTTP because a bug reported in 2017 (SSL on Mac) has still not been addressed.
And we can’t use Sketchup::Http because apparently y’all don’t understand programming.
Consider a simple routine, that uses read_default for settings. And it’s decided to upgrade that to storing in the cloud instead. Well, that’s impossible, without completely rewriting the tool, to now send the request to query the settings from the cloud, and then just wait for that async process to fire the rest of the command.
Or, I don’t know, how about License Validation. Surely your own license validation is synchronous???

Some things are synchronous, to blanket claim there is never a need for that is, I’m sorry, just woefully ignorant.

We’re up against a wall here, and realistically our only viable solution is just to drop support for Mac SketchUp, as clearly there is no desire to make it a functional product. No modal dialog boxes, no ability to use Net::HTTP, different behavior with load_from_url, all with not only no fix in sight, but utter nonsense spewed by those in charge.

1 Like

Does this issue have a report listed in the official bug tracker ? If so can you post a link please?

I believe this is it:
https://github.com/SketchUp/api-issue-tracker/issues/110

There’s also this incredibly unhelpful note on this page:

“The Http module provides interfaces to create asynchronous HTTP requests. This is an alternative to the Net::Http module that comes with Ruby StdLib - which is known to have issues within SketchUp.”

I didn’t write that. If I did, I would have linked “issues” to the known issues.

Okay, yes I participated in the linked issue thread. As I understand it we mainly discussed problems with Ruby’s OpenSSL library (mainly on Windows platform) which has since had quite a few updates, which were rolled into the version SketchUp is using for it’s API through the SU2019, SU2021 and SU2022 releases.

Are you saying that these updates did not solve issues on the Mac platform in the latest release (ie OpenSSL v 1.1.1l ?

  • If so, I would encourage you to open a separate tracking report for this Mac platform issue.

You do realize that Trimble has a policy to not fix or patch older releases?

Depending on how far back your mac support needs to be you might be able to use Net::Http. It’s just some older versions had bugs in Ruby itself due to various issues on both platforms.

What are you referring to here? UI::WebDialog didn’t have true modal on Mac, but UI::HtmlDialog have true modal on both platforms.

1 Like

Regarding version, I’m only concerned with 2022, particularly as it seems 2021 has a lot of UI::HtmlDialog issues.

Because of which, I did not realize that UI::HtmlDialog did allow modal on Mac! When it crashed SU I guess I assumed that was it. So it must have been the other fun curve ball that UI::HtmlDialog has thrown us – can’t call definitions.load_from_url from an action_callback, have to wrap it in a UI.start_timer (The HtmlDialog bug! - #2 by john_drivenupthewall).

In addition, I already have my other list of programming exceptions:

  • can’t use exit
  • definitions.load_from_url on Mac names the component differently than on PC
  • and our topic of note here, can’t have a synchronous Http call.

I spend more time in PHP than in Ruby, so that could be where some of my frustration comes from. I can’t imagine telling a PHP programmer they can’t use die() or curl.

But, to bring this back around to the issue of this thread - not having a synchronous Http call is a huge handicap. Particularly with these other issues. Being able to finally have a modal dialog is helpful in some regards, but not if that dialog needs to tell Ruby to download a resource, in which case we’re right back to where we started, up against a wall with no viable solution.

So the end result is that a dialog that needs to download resources is going to have to be modeless, spinning off all these async download calls, and god forbid something fails catastrophically because we can’t call exit.

So, again, sorry I’m a bit frustrated, but I’m really struggling here on what should have been a very simple port from WebDialog to HtmlDialog.

–J

Are you referring to Ruby’s Kernel#exit global method ?

If so, there is no point in causing the Ruby subprocess to exit as it is controlled and embedded by the SketchUp application process. It was made a no-op because it caused the application to crash which is a bad way to unload the application and may cause unnecessary BugSplat! reports.

The API added the Sketchup::quit module method so that the application can be shut down gracefully.

I don’t want to exit the application, I want to abort all Ruby evaluation.

When I read about Ruby exit, you know, I don’t see anyone saying it’s a bad thing. To suggest one has to avoid it completely, when literally all it does is to raise a SystemExit exception, it sure sounds like the problem is not the exit method but something on the SketchUp side.
But more to the point of this thread, it’s just stacking up, this wildly unique permutation of Ruby.
I’ve been able to easily code around no ability to fire exit, I just fire a raise StandardError, which, from my perspective, is functionally identical to exit, which just raises a SystemExit. So, easy enough, I can code around that. It’s annoying, but whatever.

Meanwhile, the lack of a synchronous Http call is is a huge hindrance, especially given that I can’t call definitions.load_from_url from a dialog, OR use Net::HTTP.

–J

Back in the SU2013 days, Dana Woodman attempted to wrap the libcurl library into a SketchUp Ruby utility. He soon got a new job and had no more time to play with SketchUp, so he abandoned his SketchUp projects.


There are also some Ruby gems that wrap curl …

Perhaps one of these might be ported to use within SketchUp.

… OR ideas from them might be leveraged using Ruby Fiddle library to make libcurl calls.

Interesting, thanks Dan, those are good thoughts for workarounds.

However, it sure would suck to spend all that effort porting something like that, only to fall victim to the same OpenSSL issue plaguing Net::HTTP. I’d much rather that bug just get addressed. Alternately, I’d really like a synchronous version of Sketchup::Http.
And I’d also like the bug of definitions.load_from_url when called from UI::HtmlDialog to be fixed.
And overall, with all the above there seems to be little to no appreciation for the necessity of these, with repeated offhand comments that these can just be done async without any issue. These are serious issues, and they need to be addressed.

–J

Please open a specific feature request issue for this in the GitHub tracker.

Again, please add your concerns to the open issue #633 in the tracker.

Well, the way that the API team has been working seems that issues that have workarounds get lower priority than those that do not. (Just sayin’)

Generally, blocking (synchronous) tasks during SketchUp’s startup cycle are discouraged.
An extension can be written to initialize with a set of default options, then get overwritten with the user’s last saved options.

Meanwhile let an asynchronous routine update the options hash from “the cloud” after all extensions have loaded. In most cases the user will not immediately be using extensions before these update tasks are completed.

An extension can have a Boolean variable to know whether it’s options hash has been sync’d with the cloud. If the user tries to use one of the extension’s commands before the cloud update is complete, the code can display a warning or a messagebox asking if they wish to continue using local copy of the options.

Dan,
Alright, will post there. But just to wrap up this thought here.
Yes, there are some workarounds to some aspects of it, such as loading options as you describe.
But even that requires a fair amount of re-engineering. And in some cases, even given your exact example, that is hardly a drop-in replacement. In that example, the options hash cannot be freshened inline, and cannot be called from a modal dialog.

So to repeat, there is NO viable workaround to Net::HTTP, nor is there any ability to call definitions.load_from_url from a modal dialog. I would not call rewriting everything to modeless and asynchronous a workaround. Some ability to wrap Sketchup::Http in a loop to appear synchronous, that would be a valid workaround, but is not possible.

But I’ll go and shout into the wind in those other threads.

Cheers,

–J

You can use return if you want to stop the execution of the current method.

Can you please log this in our issue tracker? It helps getting it prioritized and corrected.

I haven’t worked much with HTTP requests myself, but I thought Ruby’s own HTTP module had been improved over time and allows synchronous calls, while SketchUp’s module can be used for async requests.

Finally someone who understands the problem of Sketchup::Http. It’s absolutely useless for license verification purposes.

In my case I can’t even rely on Net::HTTP due to OpenSSL bugs in SketchUp 2017 on Windows. That said, the same version on macOS works if one supplies a more up-to-date CA certificate.

As @hokinberry said:
> just wait for that async process to fire the rest of the command.

Seems simple enough. Same type of problem as updating UI::HtmlDialog’s when providing feedback to a user. Or, one’s code issues an execute_script to the dialog, then has to wait for an add_action_callback to continue.

Re Net::HTTP, I believe the cert file for SU 2017 on Windows is dated 03-Sept-2014. The OpenSSL version is OpenSSL 1.0.1l 15 Jan 2015. That does support TLSv1.2, but it and 1.0.2 have been EOL for a number of years. I can verify a connection to at least a few servers, but it certainly may have problems given the cert file age.

Also, re Windows, SU 2017 uses Ruby 2.2, which was built with MSYS, which ceased to exist years ago. Windows Rubies 2.4 and later are all built with MSYS2, which exists today and has good support. The most recent versions of SU (Ruby 2.7 and later?) use ‘mswin’ Ruby builds, not MSYS2.

Expecting OpenSSL 1.0.1 and Ruby 2.2 to work well today is asking for something that isn’t possible.

Also, as I recall @tt_su identified a bug in older OpenSSL versions that affected the ‘first connection’ time, which could be very slow.

Taking a break, I found some old code benching Net::HTTP vs Sketchup::Http.

Using SU 2017 and Net::HTTP, it verifies an SSL connection to github.com and successfully downloads a file.

What issues were you having with OpenSSL?