DBus methods with Shouqun/node-dbus don't work. #289

Closed
Ivshti opened this Issue Dec 22, 2012 · 8 comments

Comments

Projects
None yet
2 participants
Contributor

Ivshti commented Dec 22, 2012

This code:

        var dbus = require("dbus");


        dbus.start(function()
        {
            var device = dbus.get_interface(dbus.system_bus(),"org.freedesktop.UDisks","/org/freedesktop/UDisks/devices/sda5","org.freedesktop.UDisks.Device");
            console.log(device.FilesystemMount("",[]));

        });

works perfectly fine with node.js 0.8.14, but fails to work with node-webkit 0.3.6 (node 0.8.14); The result of it's execution in Node is the device being mounted, and the mountpoint being logged. In node-webkit, "undefined" is logged, the device is not mounted, and the command gets executed much faster (I tried the same code, only async via .finished callback and with a time measure): 10-15ms vs 200ms for the working code (in Node.js).

Running udisks-daemon in the console, I can see that the proper message has not even reached it.

Also, signals work on and off in Node-webkit when using this DBus module. I tried to debug it - but I have the suspicion that something (probably the GLib loop) is not playing well with the Chromium context.

There is the option of using native-dbus by sidorares (https://github.com/sidorares/node-dbus), but it's very buggy and unfinished.
... And Dbus is vital for developing desktop apps in Linux

I thought that, as a temporary workaround, I can fork a Node.js instance from Node-webkit an use DBus from there to update a shared object. Is this possible? (EDIT: it's not; node-webkit does not start a pure node.js instance on child_process.fork)

rogerwang was assigned Dec 24, 2012

Member

rogerwang commented Dec 24, 2012

I made a try and found that the debug version of node-dbus and gcontext works well with node-webkit. btw, I tried with pidgin's dbus interface.

Member

rogerwang commented Dec 24, 2012

@Shouqun @cfsghost you might be interested in why only the debug version works here.

Member

rogerwang commented Dec 28, 2012

today I rebuild the release version again and it works... so I cannot reproduce it now.

Contributor

Ivshti commented Dec 28, 2012

Please try using the code that I supplied - you should have UDisks available if you are running Ubuntu or any popular distro. If you have UDisks2, you can still install udisks legacy through the software center/package manager.

The problem is that, sometimes DBus works for me - e.g. when getting properties:

dbus.get_interface(dbus.system_bus(),"org.freedesktop.UDisks",devicePath,"org.freedesktop.DBus.Properties").GetAll("org.freedesktop.UDisks.Device") 

(let's say device path is "/org/freedesktop/UDisks/devices/sda1" since you probably have that device).

While trying to get the interface itself and calling a function from it fails:

var device = dbus.get_interface(dbus.system_bus(),"org.freedesktop.UDisks","/org/freedesktop/UDisks/devices/sda5","org.freedesktop.UDisks.Device");
            console.log(device.FilesystemMount("",[]));

I tried asynchronous (set .finish = function() {... } and then call function) too - the callback is called, but UDisks never receives the call in the first place.

Anyway, please notify me when the new release version is uploaded so I can re-test my app. For now, I am using a simple workaround (calling udisks --mount through child.exec) but in the future, being able to interact with DBus would be a critical part of all my software.

Member

rogerwang commented Dec 28, 2012

OK. I'll try with your code and UDisk.

btw, do other D-Bus interfaces work well on your side?

Contributor

Ivshti commented Dec 28, 2012

Actually, I tried with notifications:

            var dbus = require("/tmp/node_modules/dbus");


        dbus.start(function()
        {
            var notify = dbus.get_interface(dbus.session_bus(),"org.freedesktop.Notifications","/org/freedesktop/Notifications","org.freedesktop.Notifications");
            console.log(notify.Notify("node-webkit", 0, "", "short desc", "long desc", [], {}, -1));

        });

Works fine.

And rhythmbox:

            var dbus = require("/tmp/node_modules/dbus");


        dbus.start(function()
        {
            var player = dbus.get_interface(dbus.session_bus(),"org.gnome.Rhythmbox","/org/gnome/Rhythmbox/Player","org.gnome.Rhythmbox.Player");
           player.playPause(0);
           setTimeout(function() {  player.playPause(1)  }, 5000) 

        });

Works fine (stops player and resumes it after 5 sec).

Is it possible system/session bus is the cutoff? Remember, UDisks works fine in regular Node.js.

(in case the dbus module itself was changed and that made everything work, I tested things again with UDisks; same result - OK in node.js and returns undefined in node-webkit and does not execute the command).

Edits:
Something important that I forgot to mention: EnumerateDevices() on the main UDisks object works.
UPower also works. So I am starting to think that the cutoff is related to the time it takes to execute the command.

New update:
.FilesystemUnmount also works; I remember having other functions that did not work before - but they were heavy operations; I am definitely starting to think that time is the cutoff.
I remember when I first try to debug that issue - FilesystemMount was taking ~200MS in node.js - which is extremely long for a DBus method - however expected - since mounting is a heavy operation. In node-webkit, it took a little bit over 10ms (13ms), and of course - returned undefined instead of a mountpoint and did not work.

Contributor

Ivshti commented Jan 30, 2013

Several things were wrong with the node-dbus module with node-webkit. One was that objects were made "weak" and that means the garbage collector collects them when they're no longer accessible from JS.

So, if in an isolated function, like the callback to dbus.start, I initialize a Dbus connection and I set a callback to a signal (e.g. .onemit =, .enable = true) the garbage collector will wipe out the object and that would no longer be valid. If we define that service as a global variable (var definition outside this function) it's all fine.

In node.js, something seems to make this object persist because we have attached our function to it, so the problem didn't affect it.

After all, I patched node-dbus and I will soon push the changes upstream.

The problem with udisks is not with node-dbus at all. Udisks was returning "Not authorized", which means something denies authorization to the nw process but allows it to regular node.js. Of course, ConsoleKit is in charge of permissions for Udisks, so I will investigate.

Ivshti closed this Jan 30, 2013

Member

rogerwang commented Jan 30, 2013

good to know it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment