Skip to content

Commit 940f171

Browse files
committed
100% more observables hell
1 parent b6fc04f commit 940f171

File tree

2 files changed

+28
-59
lines changed

2 files changed

+28
-59
lines changed

src/socket-daemon.js

Lines changed: 27 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ import { detect } from 'detect-browser';
3434
import {
3535
Subject,
3636
BehaviorSubject,
37-
interval
37+
interval,
38+
timer
3839
} from 'rxjs';
40+
import { filter, startWith, takeUntil } from 'rxjs/operators';
3941
import ReaderWriter from './reader-writer';
4042

4143
// Required agent version
@@ -52,6 +54,8 @@ const LOOPBACK_HOSTNAME = 'localhost';
5254
const LOOKUP_PORT_START = 8991;
5355
const LOOKUP_PORT_END = 9000;
5456

57+
const POLLING_INTERVAL = 1000;
58+
5559
const CANT_FIND_AGENT_MESSAGE = 'Arduino Create Agent cannot be found';
5660
let updateAttempts = 0;
5761

@@ -65,64 +69,53 @@ export default class SocketDaemon {
6569
constructor() {
6670
this.selectedProtocol = PROTOCOL.HTTP;
6771
this.agentInfo = {};
68-
6972
this.agentFound = new BehaviorSubject(false);
7073
this.wsConnected = new BehaviorSubject(false);
71-
this.wsError = new Subject();
72-
74+
this.error = new Subject();
7375
this.readerWriter = new ReaderWriter();
76+
7477
this.wsConnected
75-
.subscribe(status => {
76-
if (status) {
78+
.subscribe(wsConnected => {
79+
if (wsConnected) {
7780
this.readerWriter.initSocket(this.socket);
81+
interval(POLLING_INTERVAL)
82+
.pipe(startWith(0))
83+
.pipe(takeUntil(this.wsConnected.pipe(filter(status => !status))))
84+
.subscribe(() => this.socket.emit('command', 'list'));
7885
}
7986
else {
80-
this.findAgent();
87+
this.agentFound.next(false);
8188
}
8289
});
8390

8491
this.agentFound
85-
.subscribe(status => {
86-
if (status) {
87-
this.wsConnect();
92+
.subscribe(agentFound => {
93+
if (agentFound) {
94+
this._wsConnect();
8895
}
8996
else {
90-
this.agentInfo = {};
97+
this.findAgent();
9198
}
9299
});
93100
}
94101

95102
/**
96103
* Look for the agent endpoint.
97104
* First search in http://LOOPBACK_ADDRESS, after in https://LOOPBACK_HOSTNAME if in Chrome or Firefox, otherwise vice versa.
98-
* @return {object} The found agent info values.
99105
*/
100106
findAgent() {
101-
const find = () => this.tryAllPorts()
102-
.catch(err => {
103-
this.agentFound.next(false);
104-
return err;
105-
})
106-
.finally(() => {
107-
if (!this.isConnected()) {
108-
setTimeout(find, 3000);
109-
}
110-
});
111-
return find();
112-
}
113-
114-
tryAllPorts() {
115-
return this.tryPorts(orderedPluginAddresses[0])
116-
.catch(() => this.tryPorts(orderedPluginAddresses[1])
117-
.catch(err => Promise.reject(err)));
107+
this._tryPorts(orderedPluginAddresses[0])
108+
.catch(() => this._tryPorts(orderedPluginAddresses[1]))
109+
.then(() => this.agentFound.next(true))
110+
.catch(() => timer(POLLING_INTERVAL).subscribe(() => this.findAgent()));
118111
}
119112

120113
/**
121114
* Try ports for the selected hostname. From LOOKUP_PORT_START to LOOKUP_PORT_END
122115
* @param {string} hostname - The hostname value (LOOPBACK_ADDRESS or LOOPBACK_HOSTNAME).
123-
* @return {object} info - The agent info values.
116+
* @return {Promise} info - A promise resolving with the agent info values.
124117
*/
125-
tryPorts(hostname) {
118+
_tryPorts(hostname) {
126119
const pluginLookups = [];
127120

128121
for (let port = LOOKUP_PORT_START; port < LOOKUP_PORT_END; port += 1) {
@@ -146,7 +139,6 @@ export default class SocketDaemon {
146139
this.agentInfo[this.selectedProtocol] = this.agentInfo[this.selectedProtocol].replace('localhost', '127.0.0.1');
147140
}
148141
this.readerWriter.initPluginUrl(this.agentInfo[this.selectedProtocol]);
149-
this.agentFound.next(true);
150142
return true;
151143
}
152144
return false;
@@ -170,14 +162,8 @@ export default class SocketDaemon {
170162

171163
/**
172164
* Uses the websocket protocol to connect to the agent
173-
*
174-
* @return {Promise}
175165
*/
176-
wsConnect() {
177-
if (this.isConnected()) {
178-
return;
179-
}
180-
166+
_wsConnect() {
181167
const wsProtocol = this.selectedProtocol === PROTOCOL.HTTPS ? 'ws' : 'wss';
182168
const address = this.agentInfo[wsProtocol];
183169
this.socket = io(address, { reconnection: false, forceNew: true });
@@ -188,20 +174,11 @@ export default class SocketDaemon {
188174
this.socket.emit('command', 'downloadtool bossac 1.7.0 arduino keep');
189175

190176
this.wsConnected.next(true);
191-
192-
// Periodically asks for the ports
193-
if (!this.portsPollingSubscription) {
194-
this.portsPollingSubscription = interval(1500).subscribe(() => this.socket.emit('command', 'list'));
195-
}
196177
});
197178

198-
this.socket.on('error', error => this.wsError.next(error));
179+
this.socket.on('error', error => this.error.next(error));
199180

200-
// Reconnect on disconnect
201181
this.socket.on('disconnect', () => {
202-
if (this.portsPollingSubscription) {
203-
this.portsPollingSubscription.unsubscribe();
204-
}
205182
this.wsConnected.next(false);
206183
});
207184
}
@@ -225,20 +202,12 @@ export default class SocketDaemon {
225202
* @param {function} createDeviceCb used to create the device associated to the user
226203
*/
227204
configureBoard(compiledSketch, board, createDeviceCb) {
228-
if (!this.isConnected()) {
205+
if (!this.wsConnect.getValue()) {
229206
return Promise.reject(new Error('We were not able to generate the CSR.'));
230207
}
231208
return this.configure(compiledSketch, board, createDeviceCb);
232209
}
233210

234-
/**
235-
* Check if socket connected.
236-
* @return {boolean} The connection status flag.
237-
*/
238-
isConnected() {
239-
return this.socket && this.socket.connected;
240-
}
241-
242211
/**
243212
* Pauses the plugin
244213
* @return {Promise}

test/app.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class App extends React.Component {
3636
this.setState({ wsStatus: status });
3737
});
3838

39-
this.daemon.wsError.subscribe(this.showError);
39+
this.daemon.error.subscribe(this.showError);
4040

4141
this.daemon.readerWriter.messageSubject.subscribe(() => {
4242
this.setState({

0 commit comments

Comments
 (0)