njh/node-owfs

Listing all devices and properties

Closed this issue · 2 comments

njh commented

Hello,

I am trying to create a complete list of devices and the properties for each device. However I am having problems with second call to dirall throwing EADDRNOTAVAIL.

Here is my code:

var owfs = require("owfs");
var async = require("async");

var client = new owfs.Client('localhost');
client.dirall("/",function(error, directories){
    if (!error) {
        console.log("Top no error");
        async.mapSeries(directories, client.dirall,
            function(error, results) {
                console.log("Inner Error: "+error);
                console.log("Inner Results: "+results);
            }
        );
    } else {
        console.log("Top error: "+error);
    }
});

This is the output:

Top no error
error:  code=EADDRNOTAVAIL, errno=EADDRNOTAVAIL, syscall=connect
Inner Error: Error: connect EADDRNOTAVAIL
Inner Results: 

I am using async.mapSeries in an attempt to make a sequence of calls to owserver and avoid making a large number of calls in parallel.

My theory is the while each call to dirall should be creating its own socket and connection to owserver. By the time the second socket is created, the first socket is only half-closed and node.js tries to re-use the same local port and then fails.

Can you suggest a solution to this problem?

Thanks,

nick.

Ok the error message is very missleading...

I debugged the code and found out that async is calling apply on the iterator function with null as first argument. According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply this means, that this inside the iterator function (in your case client.dirall) will be the global object.

Inside dirall I am calling an internal function on the this object. This fails in your case because this is not the client instance.

Wrapping the second dirall inside a function, like this, works as expected:

client.dirall("/",function(error, directories){
    if (!error) {
        console.log("Top no error");
        async.mapSeries(directories, function(directory,cb){
                client.dirall(directory,cb);
            },
            function(error, results) {
                console.log("Inner Error: "+error);
                console.log("Inner Results: "+results);
            }
        );
    } else {
        console.log("Top error: "+error);
    }
});

I will try to detect the error and provide a better error message.

njh commented

Thank you so much for looking into this. Working for me too.