Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a54d7c8

Browse files
davegarthsimpsonAlberto Iannaccone
and
Alberto Iannaccone
authored
#1032 failing upload flag for monitor mgr (#1040)
* 1032 failing upload flag for monitor mgr * move upload failure fix logic to frontend * misc corrections * avoid starting monitor when upload is in progress * avoid starting monitor when upload is in progress * prevent monitor side effects on upload (WIP) * send upload req after notifying mgr * dispose instead of pause on upld (code not final) * Revert "dispose instead of pause on upld (code not final)" This reverts commit 2d5dff2. * force wait before upload (test) * always start queued services after uplaod finishes * test cli with monitor close delay * clean up unnecessary await(s) * remove unused dependency * revert CLI to 0.23 * use master cli for testing, await in upload finish * remove upload port from pending monitor requests * fix startQueuedServices * refinements queued monitors * clean up monitor mgr state * fix typo from prev cleanup * avoid dupl queued monitor services * variable name changes * reference latest cli commit in package.json Co-authored-by: Alberto Iannaccone <a.iannaccone@arduino.cc>
1 parent 84109e4 commit a54d7c8

File tree

6 files changed

+163
-38
lines changed

6 files changed

+163
-38
lines changed

‎arduino-ide-extension/package.json‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,11 @@
156156
],
157157
"arduino": {
158158
"cli": {
159-
"version": "0.23.0"
159+
"version": {
160+
"owner": "arduino",
161+
"repo": "arduino-cli",
162+
"commitish": "c1b10f562f1e1a112e215a69b84e2f2b69e3af2d"
163+
}
160164
},
161165
"fwuploader": {
162166
"version": "2.2.0"

‎arduino-ide-extension/src/node/arduino-firmware-uploader-impl.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
9090
} catch (e) {
9191
throw e;
9292
} finally {
93-
this.monitorManager.notifyUploadFinished(board, port);
93+
awaitthis.monitorManager.notifyUploadFinished(board, port);
9494
return output;
9595
}
9696
}

‎arduino-ide-extension/src/node/core-service-impl.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
119119
return request;
120120
}
121121

122-
asyncupload(options: CoreService.Upload.Options): Promise<void> {
122+
upload(options: CoreService.Upload.Options): Promise<void> {
123123
return this.doUpload(
124124
options,
125125
() => new UploadRequest(),

‎arduino-ide-extension/src/node/monitor-manager-proxy-impl.ts‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,14 @@ export class MonitorManagerProxyImpl implements MonitorManagerProxy {
4040
if (settings) {
4141
await this.changeMonitorSettings(board, port, settings);
4242
}
43-
const status = await this.manager.startMonitor(board, port);
44-
if (status === Status.ALREADY_CONNECTED || status === Status.OK) {
45-
// Monitor started correctly, connect it with the frontend
46-
this.client.connect(this.manager.getWebsocketAddressPort(board, port));
47-
}
43+
44+
const connectToClient = (status: Status) => {
45+
if (status === Status.ALREADY_CONNECTED || status === Status.OK) {
46+
// Monitor started correctly, connect it with the frontend
47+
this.client.connect(this.manager.getWebsocketAddressPort(board, port));
48+
}
49+
};
50+
return this.manager.startMonitor(board, port, connectToClient);
4851
}
4952

5053
/**

‎arduino-ide-extension/src/node/monitor-manager.ts‎

Lines changed: 148 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ILogger } from '@theia/core';
22
import { inject, injectable, named } from '@theia/core/shared/inversify';
3-
import { Board, Port, Status } from '../common/protocol';
3+
import { Board, BoardsService,Port, Status } from '../common/protocol';
44
import { CoreClientAware } from './core-client-provider';
55
import { MonitorService } from './monitor-service';
66
import { MonitorServiceFactory } from './monitor-service-factory';
@@ -11,16 +11,34 @@ import {
1111

1212
type MonitorID = string;
1313

14+
type UploadState = 'uploadInProgress' | 'pausedForUpload' | 'disposedForUpload';
15+
type MonitorIDsByUploadState = Record<UploadState, MonitorID[]>;
16+
1417
export const MonitorManagerName = 'monitor-manager';
1518

1619
@injectable()
1720
export class MonitorManager extends CoreClientAware {
21+
@inject(BoardsService)
22+
protected boardsService: BoardsService;
23+
1824
// Map of monitor services that manage the running pluggable monitors.
1925
// Each service handles the lifetime of one, and only one, monitor.
2026
// If either the board or port managed changes, a new service must
2127
// be started.
2228
private monitorServices = new Map<MonitorID, MonitorService>();
2329

30+
private monitorIDsByUploadState: MonitorIDsByUploadState = {
31+
uploadInProgress: [],
32+
pausedForUpload: [],
33+
disposedForUpload: [],
34+
};
35+
36+
private monitorServiceStartQueue: {
37+
monitorID: string;
38+
serviceStartParams: [Board, Port];
39+
connectToClient: (status: Status) => void;
40+
}[] = [];
41+
2442
@inject(MonitorServiceFactory)
2543
private monitorServiceFactory: MonitorServiceFactory;
2644

@@ -48,6 +66,33 @@ export class MonitorManager extends CoreClientAware {
4866
return false;
4967
}
5068

69+
private uploadIsInProgress(): boolean {
70+
return this.monitorIDsByUploadState.uploadInProgress.length > 0;
71+
}
72+
73+
private addToMonitorIDsByUploadState(
74+
state: UploadState,
75+
monitorID: string
76+
): void {
77+
this.monitorIDsByUploadState[state].push(monitorID);
78+
}
79+
80+
private removeFromMonitorIDsByUploadState(
81+
state: UploadState,
82+
monitorID: string
83+
): void {
84+
this.monitorIDsByUploadState[state] = this.monitorIDsByUploadState[
85+
state
86+
].filter((id) => id !== monitorID);
87+
}
88+
89+
private monitorIDIsInUploadState(
90+
state: UploadState,
91+
monitorID: string
92+
): boolean {
93+
return this.monitorIDsByUploadState[state].includes(monitorID);
94+
}
95+
5196
/**
5297
* Start a pluggable monitor that receives and sends messages
5398
* to the specified board and port combination.
@@ -56,13 +101,34 @@ export class MonitorManager extends CoreClientAware {
56101
* @returns a Status object to know if the process has been
57102
* started or if there have been errors.
58103
*/
59-
async startMonitor(board: Board, port: Port): Promise<Status> {
104+
async startMonitor(
105+
board: Board,
106+
port: Port,
107+
connectToClient: (status: Status) => void
108+
): Promise<void> {
60109
const monitorID = this.monitorID(board, port);
110+
61111
let monitor = this.monitorServices.get(monitorID);
62112
if (!monitor) {
63113
monitor = this.createMonitor(board, port);
64114
}
65-
return await monitor.start();
115+
116+
if (this.uploadIsInProgress()) {
117+
this.monitorServiceStartQueue = this.monitorServiceStartQueue.filter(
118+
(request) => request.monitorID !== monitorID
119+
);
120+
121+
this.monitorServiceStartQueue.push({
122+
monitorID,
123+
serviceStartParams: [board, port],
124+
connectToClient,
125+
});
126+
127+
return;
128+
}
129+
130+
const result = await monitor.start();
131+
connectToClient(result);
66132
}
67133

68134
/**
@@ -111,14 +177,18 @@ export class MonitorManager extends CoreClientAware {
111177
// to retrieve if we don't have this information.
112178
return;
113179
}
180+
114181
const monitorID = this.monitorID(board, port);
182+
this.addToMonitorIDsByUploadState('uploadInProgress', monitorID);
183+
115184
const monitor = this.monitorServices.get(monitorID);
116185
if (!monitor) {
117186
// There's no monitor running there, bail
118187
return;
119188
}
120-
monitor.setUploadInProgress(true);
121-
return await monitor.pause();
189+
190+
this.addToMonitorIDsByUploadState('pausedForUpload', monitorID);
191+
return monitor.pause();
122192
}
123193

124194
/**
@@ -130,19 +200,69 @@ export class MonitorManager extends CoreClientAware {
130200
* started or if there have been errors.
131201
*/
132202
async notifyUploadFinished(board?: Board, port?: Port): Promise<Status> {
133-
if (!board || !port) {
134-
// We have no way of knowing which monitor
135-
// to retrieve if we don't have this information.
136-
return Status.NOT_CONNECTED;
203+
let status: Status = Status.NOT_CONNECTED;
204+
let portDidChangeOnUpload = false;
205+
206+
// We have no way of knowing which monitor
207+
// to retrieve if we don't have this information.
208+
if (board && port) {
209+
const monitorID = this.monitorID(board, port);
210+
this.removeFromMonitorIDsByUploadState('uploadInProgress', monitorID);
211+
212+
const monitor = this.monitorServices.get(monitorID);
213+
if (monitor) {
214+
status = await monitor.start();
215+
}
216+
217+
// this monitorID will only be present in "disposedForUpload"
218+
// if the upload changed the board port
219+
portDidChangeOnUpload = this.monitorIDIsInUploadState(
220+
'disposedForUpload',
221+
monitorID
222+
);
223+
if (portDidChangeOnUpload) {
224+
this.removeFromMonitorIDsByUploadState('disposedForUpload', monitorID);
225+
}
226+
227+
// in case a service was paused but not disposed
228+
this.removeFromMonitorIDsByUploadState('pausedForUpload', monitorID);
137229
}
138-
const monitorID = this.monitorID(board, port);
139-
const monitor = this.monitorServices.get(monitorID);
140-
if (!monitor) {
141-
// There's no monitor running there, bail
142-
return Status.NOT_CONNECTED;
230+
231+
await this.startQueuedServices(portDidChangeOnUpload);
232+
return status;
233+
}
234+
235+
async startQueuedServices(portDidChangeOnUpload: boolean): Promise<void> {
236+
// if the port changed during upload with the monitor open, "startMonitorPendingRequests"
237+
// will include a request for our "upload port', most likely at index 0.
238+
// We remove it, as this port was to be used exclusively for the upload
239+
const queued = portDidChangeOnUpload
240+
? this.monitorServiceStartQueue.slice(1)
241+
: this.monitorServiceStartQueue;
242+
this.monitorServiceStartQueue = [];
243+
244+
for (const {
245+
monitorID,
246+
serviceStartParams: [_, port],
247+
connectToClient,
248+
} of queued) {
249+
const boardsState = await this.boardsService.getState();
250+
const boardIsStillOnPort = Object.keys(boardsState)
251+
.map((connection: string) => {
252+
const portAddress = connection.split('|')[0];
253+
return portAddress;
254+
})
255+
.some((portAddress: string) => port.address === portAddress);
256+
257+
if (boardIsStillOnPort) {
258+
const monitorService = this.monitorServices.get(monitorID);
259+
260+
if (monitorService) {
261+
const result = await monitorService.start();
262+
connectToClient(result);
263+
}
264+
}
143265
}
144-
monitor.setUploadInProgress(false);
145-
return await monitor.start();
146266
}
147267

148268
/**
@@ -202,6 +322,18 @@ export class MonitorManager extends CoreClientAware {
202322
this.monitorServices.set(monitorID, monitor);
203323
monitor.onDispose(
204324
(() => {
325+
// if a service is disposed during upload and
326+
// we paused it beforehand we know it was disposed
327+
// of because the upload changed the board port
328+
if (
329+
this.uploadIsInProgress() &&
330+
this.monitorIDIsInUploadState('pausedForUpload', monitorID)
331+
) {
332+
this.removeFromMonitorIDsByUploadState('pausedForUpload', monitorID);
333+
334+
this.addToMonitorIDsByUploadState('disposedForUpload', monitorID);
335+
}
336+
205337
this.monitorServices.delete(monitorID);
206338
}).bind(this)
207339
);

‎arduino-ide-extension/src/node/monitor-service.ts‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export class MonitorService extends CoreClientAware implements Disposable {
6060
protected readonly onDisposeEmitter = new Emitter<void>();
6161
readonly onDispose = this.onDisposeEmitter.event;
6262

63-
protected uploadInProgress = false;
6463
protected _initialized = new Deferred<void>();
6564
protected creating: Deferred<Status>;
6665

@@ -114,10 +113,6 @@ export class MonitorService extends CoreClientAware implements Disposable {
114113
return this._initialized.promise;
115114
}
116115

117-
setUploadInProgress(status: boolean): void {
118-
this.uploadInProgress = status;
119-
}
120-
121116
getWebsocketAddressPort(): number {
122117
return this.webSocketProvider.getAddress().port;
123118
}
@@ -161,15 +156,6 @@ export class MonitorService extends CoreClientAware implements Disposable {
161156
return this.creating.promise;
162157
}
163158

164-
if (this.uploadInProgress) {
165-
this.updateClientsSettings({
166-
monitorUISettings: { connected: false, serialPort: this.port.address },
167-
});
168-
169-
this.creating.resolve(Status.UPLOAD_IN_PROGRESS);
170-
return this.creating.promise;
171-
}
172-
173159
this.logger.info('starting monitor');
174160

175161
// get default monitor settings from the CLI

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /