Re: Running function asynchronously in gjs



On Tue, Jan 12, 2016 at 10:23 PM Per <pmknutsen gmail com> wrote:
I am currently spawning a shell command from my Gnome extension synchronously with Util.spawn(). The command updates icon emblems, and may run hundreds of times consecutively inside a for() loop. The command is:

Util.spawn_async(['gvfs-set-attribute', MYPATH, '-t', 'stringv', 'metadata::emblems', EMBLEM]);

The repeating spawning, perhaps unsurprisingly, locks up the entire Gnome desktop.

Is there a way I can run a command asynchronously in Gnome _javascript_?

There is Gio.Subprocess, but it would be better to do all this without shelling out in the first place. It's not good to spawn hundreds of processes at once, synchronously or not! Here's some (untested) code that might help you:

// adjust these parameters according to your situation
let priority = GLib.PRIORITY_DEFAULT;
let cancellable = new Gio.Cancellable();
let flags = Gio.FileQueryInfoFlags.NONE;

// inside your loop:
let file = Gio.File.new_for_path(MYPATH);
file.query_info_async('metadata::emblems', flags, priority, cancellable, (file, res) => {
    let info = file.query_info_finish(res);
    info.set_attribute_stringv('metadata::emblems', [EMBLEM]);
    file.set_attributes_async(info, flags, priority, cancellable, (file, res) => {
        file.set_attributes_finish(res);
    });
});

This code still may have a problem; you'll want to avoid running hundreds of threads at the same time, all doing file I/O. To solve that, you could consider using recursion instead of a loop; start with an array of files that you want to process, pass it into a function with the above code, then in the callback to set_attributes_async(), pop the processed element off the array and do the same thing again until the array is empty. That way, the files will all be processed sequentially and asynchronously.

Regards,
Philip



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]