Async / Background job in Sketchup

Hi, I want to fetch some data from a http get request on the startup of sketchup and then save it locally to JSON file.
is there any way we can do this HTTP request in background so that it will not block the Sketchup. Thanks

For this particular case you can use sketchup 's own implementation of HTTP::Request

for processing the response (to storing into the JSON file) is taking time, for that time being its blocking the sketchup. can we do something so it will run in background and store into JSON file

Are you sending the response body as a JSON string ?
Or are doing something else with the data sent ?


… should not take very long.

You could try …

UI.start_timer(0,false) { File.write(save_path,response.body) }

before saving to JSON file, actually we are doing some calculation which is taking time, so is there a way which we can do those calculation into the background so it will not block the sketchup.

Well the UI.start_timer is wrapper around a C++ timer that might be asynchronous.

Did you try it?

If it is not asynchronous, then at least you can delay the task until (hopefully) the SketchUp load cycle is complete.

@request.start do |request, response|
  body = response.body
  UI.start_timer(10.0,false) {
    json_data = process_body(body)
    File.write(@save_path, json_data)

… or whatever.

Also know that Sketchup.is_online is not asynchronous. It will block until it returns or times out. So don’t use this during the load cycle.

i don’t think UI.start_timer will work here because this will just call after 10 seconds and again sketchup will stuck in process_body method. i just wanted to run this process_body method in the background so that sketchup will not stuck. is there anything we can do with process or thread.

just wanted to setup a background runner job which will download data from HTTP request , process data and then stored into the JSON file (all this should happen in background means sketchup should not stuck or hang)

Listen, we most definitely do not want any blocking during SketchUp’s startup extensions loading cycle.

I don’t think so. But you can try.

The SketchUp API does not define such a “background” runner.

You might be able to start a separate process and pass the data to it.
Some developers in the past save data like this to a local file, then start some external utility or batch command file that will open the data file.

Ruby’s Kernel module has the backtick method (also exposed as %x executable strings.)

Dir.chdir(__dir__) do
  %[someutility.exe "data_file.txt"]

The main drawback to the above (on Windows platform) is that a command shell window will be displayed and there is no way in Ruby to prevent this window.

But, there is also the Windows Scripting Host on Windows that can be used via WIN32OLE class.

require "win32ole"
shell ="WScript.Shell")
shell.Run("someutility.exe data_file.txt", 7, false)

The 7 should minimize the new window and leave SketchUp’s window active.

The code within the block is not performed in any background thread, it’s still being executed in the main thread.

Unfortunately Ruby’s threads isn’t working properly within SketchUp. We’ve not been able to figure out the reason for this.

One alternative would be to use a Ruby C extension and use native threads. Though it’s a more advanced and complex approach. GitHub - SketchUp/ruby-c-extension-examples: Ruby C extension examples

1 Like

Hence my use of the word “might” which revealed my own skepticism. Thank you for the clarification.

If you could improve the API docstring for this method what would you like it to say ? Perhaps that it schedules the block to run within the main thread ?

@mohan.s I did some testing today and found out that any UI::start_timer defined at load time, no mater how small the interval set for it, will not execute for the first time until after all the plugins have been loaded.

So if say you set the timer’s interval to 0.25 seconds, but it took SketchUp 7.5 seconds to load all the plugins, that timer block will not run until sometime after 7.5 seconds.

Yea, a timer isn’t able to interrupt the main thread. So as long as the main thread is busy any timers will have to wait until the main thread is ready.

1 Like