Sketchup::Http::Request are silently dropped

I was trying to fetch several images from the internet with Sketchup::Http and noticed that requests were being dropped without any error. Here is a sample code that demonstrates the issue. The code downloads and saves an image file 100 times:

requests_finished = []
url = "https://freetestdata.com/wp-content/uploads/2021/09/png-5mb-1.png"
100.times do |i| 
  request = Sketchup::Http::Request.new(url, Sketchup::Http::GET)
  request.start do |req, res|
    filename = File.join(ENV['temp'], "test_image_#{i}.png")
    File.open(filename, 'wb') do |file|
      file.write(res.body)
    end
    puts "Request #{i} finished"
    requests_finished << i
  end
end

When I run this code, only few of the requests actually finish (the number varies and it’s around 10). All other request are silently discarded. This is the output I get

Request 0 finished
Request 1 finished
Request 2 finished
Request 5 finished
Request 6 finished
Request 3 finished
Request 7 finished
Request 8 finished
Request 4 finished
Request 10 finished
Request 9 finished
Request 30 finished
Request 31 finished
Request 99 finished

I’ve noticed that the last request is always 99. It seems that when the last request is run, all remaining requests are discarded.

I’ve observed another interesting behavior. If I save the request objects into an array, than all of the requests finish.

Here is a revised script that saves the Sketchup::Http::Request objects to an array.

requests_finished = []
url = "https://freetestdata.com/wp-content/uploads/2021/09/png-5mb-1.png"
requests = 100.times.collect { |i| Sketchup::Http::Request.new(url, Sketchup::Http::GET) }

requests.each_with_index do |request, i|
  request.start do |req, res|
    filename = File.join(ENV['temp'], "test_image_#{i}.png")
    File.open(filename, 'wb') do |file|
      file.write(res.body)
    end
    puts "Request #{i} finished"
    requests_finished << i
  end
end

Is it possible that the garbage collector clears the request objects after the last one finishes?

Because (in the 1st example) you are not keeping persistent references to the objects and Ruby’s garbage collection is destroying the objects.

Because (in the 2nd example) you are storing references in the array.

Notice in the API documentation that the example snippets assign the request object reference to a persistent instance variable, … ie: @request.


This need to keep references to objects to prevent garbage collection is basic Ruby 101.

When you no longer need an object, assign it’s reference to nil and garbage collection will clean it up on it’s next sweep.

If the reference is a local reference inside a method, then this reference will automatically “go out of scope” when the method ends, and any object so referenced will become unreferenced and subsequently garbage collected.

1 Like

That explains it. Thanks!

1 Like

This is the most idiotic thing I’ve seen in the whole SketchUp API. And I don’t care if you or others will defend this behavior. It’s just completely wrong.

WHAT is the most idiotic thing?

What the OP did incorrectly or how the RUBY LANGUAGE (not the SketchUp API) works ?

If you want to get “snotty” and start “talking out your rear orifice” then I’ll just mute you and be done with such nonsense.

In fact, it is done. I have no patience for this kind of BS and will no longer waste my time with you.

I hope this kind of language is not going to be allowed by the moderators team. In fact, I’m going to report you right away. Adios!