Skip to content

Commit 59531f8

Browse files
Merge pull request #61 from RethinkRobotics-opensource/spinnerAndLifecycle
Spinner and lifecycle
2 parents 631d662 + 78c71e7 commit 59531f8

15 files changed

Lines changed: 662 additions & 255 deletions

src/index.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,37 +38,28 @@ const MsgLoader = require('./utils/messageGeneration/MessageLoader.js');
3838
// will be initialized through call to initNode
3939
let log = Logging.getLogger();
4040
let rosNode = null;
41+
let pingMasterTimeout = null;
4142

4243
//------------------------------------------------------------------
4344

44-
function _checkMasterHelper(timeout=500) {
45-
let firstCheck = true;
46-
45+
function _checkMasterHelper(timeout=100) {
4746
const localHelper = (resolve) => {
48-
setTimeout(() => {
47+
pingMasterTimeout = setTimeout(() => {
4948
// also check that the slave api server is set up
5049
if (!rosNode.slaveApiSetupComplete()) {
5150
localHelper(resolve);
5251
return;
5352
}
54-
// else
55-
if (firstCheck) {
56-
// hook into master api connection errors.
57-
// api client will continue trying to connect
58-
rosNode._masterApi.getXmlrpcClient().once('ECONNREFUSED', (err) => {
59-
log.warn(`Unable to register with master node [${rosNode.getRosMasterUri()}]: master may not be running yet. Will keep trying.`);
60-
});
61-
firstCheck = false;
62-
}
63-
rosNode.getMasterUri()
53+
rosNode.getMasterUri({ maxAttempts: 1 })
6454
.then(() => {
6555
log.infoOnce(`Connected to master at ${rosNode.getRosMasterUri()}!`);
56+
pingMasterTimeout = null;
6657
resolve();
6758
})
6859
.catch((err, resp) => {
69-
log.warnThrottle(60000, 'Unable to connect to master. ' + err);
60+
log.warnThrottle(60000, `Unable to register with master node [${rosNode.getRosMasterUri()}]: master may not be running yet. Will keep trying.`);
7061
localHelper(resolve);
71-
})
62+
});
7263
}, timeout);
7364
};
7465

@@ -133,16 +124,16 @@ let Rosnodejs = {
133124

134125
// create the ros node. Return a promise that will
135126
// resolve when connection to master is established
136-
rosNode = new RosNode(nodeName, rosMasterUri);
137-
127+
const nodeOpts = options.node || {};
128+
rosNode = new RosNode(nodeName, rosMasterUri, nodeOpts);
138129

139130
return this._loadOnTheFlyMessages(options)
140131
.then(_checkMasterHelper)
141132
.then(Logging.initializeRosOptions.bind(Logging, this, options.logging))
142133
.then(Time._initializeRosTime.bind(Time, this))
143134
.then(() => { return this.getNodeHandle(); })
144135
.catch((err) => {
145-
log.error('Error: ' + err);
136+
log.error('Error during initialization: ' + err);
146137
});
147138
},
148139

@@ -151,7 +142,34 @@ let Rosnodejs = {
151142
},
152143

153144
shutdown() {
154-
return rosNode.shutdown();
145+
clearTimeout(pingMasterTimeout);
146+
if (this.ok()) {
147+
return rosNode.shutdown();
148+
}
149+
// else
150+
return Promise.resolve();
151+
},
152+
153+
ok() {
154+
return rosNode && !rosNode.isShutdown();
155+
},
156+
157+
on(evt, handler) {
158+
if (rosNode) {
159+
rosNode.on(evt, handler);
160+
}
161+
},
162+
163+
once(evt, handler) {
164+
if (rosNode) {
165+
rosNode.once(evt, handler);
166+
}
167+
},
168+
169+
removeListener(evt, handler) {
170+
if (rosNode) {
171+
rosNode.removeListener(evt, handler);
172+
}
155173
},
156174

157175
_loadOnTheFlyMessages({onTheFly}) {

src/lib/MasterApiClient.js

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ class MasterApiClient {
3636
return this._xmlrpcClient;
3737
}
3838

39-
_call(method, data, resolve, reject, options) {
39+
_call(method, data, resolve, reject, options = {}) {
4040
this._xmlrpcClient.call(method, data, resolve, reject, options);
4141
}
4242

43-
registerService(callerId, service, serviceUri, uri) {
43+
registerService(callerId, service, serviceUri, uri, options) {
4444
let data = [
4545
callerId,
4646
service,
@@ -49,72 +49,72 @@ class MasterApiClient {
4949
];
5050

5151
return new Promise((resolve, reject) => {
52-
this._call('registerService', data, resolve, reject);
52+
this._call('registerService', data, resolve, reject, options);
5353
});
5454
}
5555

56-
unregisterService(callerId, service, serviceUri) {
56+
unregisterService(callerId, service, serviceUri, options) {
5757
let data = [
5858
callerId,
5959
service,
6060
serviceUri
6161
];
6262

6363
return new Promise((resolve, reject) => {
64-
this._call('unregisterService', data, resolve, reject);
64+
this._call('unregisterService', data, resolve, reject, options);
6565
});
6666
}
6767

68-
registerSubscriber(callerId, topic, topicType, uri) {
68+
registerSubscriber(callerId, topic, topicType, uri, options) {
6969
let data = [
7070
callerId,
7171
topic,
7272
topicType,
7373
uri
7474
];
7575
return new Promise((resolve, reject) => {
76-
this._call('registerSubscriber', data, resolve, reject);
76+
this._call('registerSubscriber', data, resolve, reject, options);
7777
});
7878
}
7979

80-
unregisterSubscriber(callerId, topic, uri) {
80+
unregisterSubscriber(callerId, topic, uri, options) {
8181
let data = [
8282
callerId,
8383
topic,
8484
uri
8585
];
8686
return new Promise((resolve, reject) => {
87-
this._call('unregisterSubscriber', data, resolve, reject);
87+
this._call('unregisterSubscriber', data, resolve, reject, options);
8888
});
8989
}
9090

91-
registerPublisher(callerId, topic, topicType, uri) {
91+
registerPublisher(callerId, topic, topicType, uri, options) {
9292
let data = [
9393
callerId,
9494
topic,
9595
topicType,
9696
uri
9797
];
9898
return new Promise((resolve, reject) => {
99-
this._call('registerPublisher', data, resolve, reject);
99+
this._call('registerPublisher', data, resolve, reject, options);
100100
});
101101
}
102102

103-
unregisterPublisher(callerId, topic, uri) {
103+
unregisterPublisher(callerId, topic, uri, options) {
104104
let data = [
105105
callerId,
106106
topic,
107107
uri
108108
];
109109
return new Promise((resolve, reject) => {
110-
this._call('unregisterPublisher', data, resolve, reject);
110+
this._call('unregisterPublisher', data, resolve, reject, options);
111111
});
112112
}
113113

114-
lookupNode(callerId, nodeName) {
114+
lookupNode(callerId, nodeName, options) {
115115
let data = [callerId, nodeName];
116116
return new Promise((resolve, reject) => {
117-
this._call('lookupNode', data, resolve, reject);
117+
this._call('lookupNode', data, resolve, reject, options);
118118
});
119119
}
120120

@@ -128,34 +128,41 @@ class MasterApiClient {
128128

129129
/** return an object containing all current publishers (by topic),
130130
subscribers (by topic), and services (by name) */
131-
getSystemState(callerId) {
131+
getSystemState(callerId, options) {
132132
function toObject(memo, sublist) {
133133
memo[sublist[0]] = sublist[1];
134134
return memo;
135135
}
136+
136137
let data = [callerId];
137138
return new Promise((resolve, reject) => {
138-
this._call('getSystemState', data, function(data) {
139-
return resolve({
140-
publishers: data[2][0].reduce(toObject, {}),
141-
subscribers: data[2][1].reduce(toObject, {}),
142-
services: data[2][2].reduce(toObject, {})
143-
});
144-
}, reject);
139+
this._call(
140+
'getSystemState',
141+
data,
142+
function(data) {
143+
return resolve({
144+
publishers: data[2][0].reduce(toObject, {}),
145+
subscribers: data[2][1].reduce(toObject, {}),
146+
services: data[2][2].reduce(toObject, {})
147+
});
148+
},
149+
reject,
150+
options
151+
);
145152
});
146153
}
147154

148-
getUri(callerId) {
155+
getUri(callerId, options) {
149156
let data = [callerId];
150157
return new Promise((resolve, reject) => {
151-
this._call('getUri', data, resolve, reject);
158+
this._call('getUri', data, resolve, reject, options);
152159
});
153160
}
154161

155-
lookupService(callerId, service) {
162+
lookupService(callerId, service, options) {
156163
let data = [callerId, service];
157164
return new Promise((resolve, reject) => {
158-
this._call('lookupService', data, resolve, reject);
165+
this._call('lookupService', data, resolve, reject, options);
159166
});
160167
}
161168
};

src/lib/NodeHandle.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class NodeHandle {
3737
return this._node.getNodeName();
3838
}
3939

40+
isShutdown() {
41+
return this._node && this._node.isShutdown();
42+
}
43+
4044
//------------------------------------------------------------------
4145
// Pubs, Subs, Services
4246
//------------------------------------------------------------------

0 commit comments

Comments
 (0)