Re: How to interact with the MainLoop ?



Thanks Philip,
  meanwhile I've solved the problem so now async operations such `require("fs").readFile("./test.js", (err, data) => console.log(data.toString()))` will never exit the program until the asynchronous file read is completed.

How? Basically explicitly defining when an async operation should call `mainloop.wait();` before executing:
https://github.com/WebReflection/jsgtk/blob/master/jsgtk_modules/jsgtk/mainloop.js

Works for `fs.stat` so far, as example, but it works for other cases too:
https://github.com/WebReflection/jsgtk/blob/master/jsgtk_modules/fs.js#L175-L187

Best Regards

On Sat, Apr 9, 2016 at 10:18 PM, <philip chimento gmail com> wrote:
On Thu, Mar 31, 2016 at 11:10 AM Andrea Giammarchi <andrea giammarchi gmail com> wrote:
I'm trying to figure out if there's a way to avoid GJS exiting when there are operations going on, like a watch on a file, or folder, without bothering the main Gtk loop or `imports.mainloop.run()`

Not sure I understand the question entirely, but I don't think you are supposed to be able to get access to main loop objects that you didn't create yourself. Even the GTK main loop will let you start or quit it, but it won't give you access to the main loop object itself.

What I'd really like to do, is to understand if any other part of the code started already a loop but I cannot find a way to reach `g_main_loop_is_running()` via GJS and using `null` to receive the context, when I should also pass the value `isRunning` makes little sense to me ... 'cause I don't know upfront if I want the default context flagged as running or not.

That is indeed a silly API, I don't know why that parameter is there.

Depending on what you are trying to do, you _may_ be able to use GLib.MainContext.default().pending() to see if there are any events pending in the default context.

But I think you are better off explicitly starting a main loop and explicitly exiting it when all your operations are done.

The `Gtk.main_level()` gives me 0 even if `imports.mainloop.run()` has never been called, and it gives me 1 or more even if a `Gtk.main_quit()` has been invoked after.

Registering a callback in the mainloop also doesn't prevent GJS from exiting before it's triggered.

I've tried to use `Gio.Application` with a dummy listener and using `app.hold()` but the moment I follow that command by `app.run([])` nothing after happens, so I can't set this thing up as it unless I do it after another event has been scheduled.

This makes sense because `hold` and `release` are explicit in their intent, but I feel like there's no way to do what I'm trying to do.

Let's say this is my `gjs-info` program

```gjs
#!/usr/bin/env gjs
const Gio = imports.gi.Gio;
let fd = Gio.File.new_for_path(ARGV[0]);
fd.query_info_async('*', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null, null, (source, result) => {
  let info = source.query_info_finish(result);
  print(info);
});

// if I write this, it will hang
// if I don't, it will exit
// imports.mainloop.run();
```

considering this is an example and what I'm trying to do has many nested asynchronous operations and not just one, how could I prevent GJS from exiting the program before I have results?

Thanks for any sort of hint/outcome.

In this example, I would simply run the operation synchronously. But you say that you have many async operations. Are they run serially or in parallel? If serial, then I would still switch to sync.

If parallel, you could very easily implement something like hold/release:

let pendingOperations = 0;
let allOperationsStarted = false;
myInputs.forEach(input => {
  pendingOperations++;
  input.my_operation_async((obj, res) => {
    pendingOperations--;
    obj.my_operation_finish(res);
    if (pendingOperations === 0 && allOperationsStarted)
      Mainloop.quit();
  });
});
allOperationsStarted = true;
Mainloop.run();

This is kind of the continuation-passing equivalent of Promise.all().

Best regards,
Philip



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