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 0a02d77

Browse files
author
Akos Kitta
committed
Various library/platform index update fixes
- IDE2 can start if the package index download fails. Closes #1084 - Split the lib and platform index update. Closes #1156 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent da22f1e commit 0a02d77

File tree

18 files changed

+1410
-338
lines changed

18 files changed

+1410
-338
lines changed

‎arduino-ide-extension/package.json‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@
158158
],
159159
"arduino": {
160160
"cli": {
161-
"version": "0.27.1"
161+
"version": {
162+
"owner": "cmaglie",
163+
"repo": "arduino-cli",
164+
"commitish": "download_progress_refactor"
165+
}
162166
},
163167
"fwuploader": {
164168
"version": "2.2.0"

‎arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ import { OutputEditorFactory } from './theia/output/output-editor-factory';
332332
import { StartupTaskProvider } from '../electron-common/startup-task';
333333
import { DeleteSketch } from './contributions/delete-sketch';
334334
import { UserFields } from './contributions/user-fields';
335+
import { UpdateIndexes } from './contributions/update-indexes';
335336

336337
const registerArduinoThemes = () => {
337338
const themes: MonacoThemeJson[] = [
@@ -744,6 +745,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
744745
Contribution.configure(bind, CheckForUpdates);
745746
Contribution.configure(bind, UserFields);
746747
Contribution.configure(bind, DeleteSketch);
748+
Contribution.configure(bind, UpdateIndexes);
747749

748750
bindContributionProvider(bind, StartupTaskProvider);
749751
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window

‎arduino-ide-extension/src/browser/boards/boards-config.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export class BoardsConfig extends React.Component<
132132
this.props.notificationCenter.onPlatformDidUninstall(() =>
133133
this.updateBoards(this.state.query)
134134
),
135-
this.props.notificationCenter.onIndexDidUpdate(() =>
135+
this.props.notificationCenter.onIndexUpdateDidComplete(() =>
136136
this.updateBoards(this.state.query)
137137
),
138138
this.props.notificationCenter.onDaemonDidStart(() =>

‎arduino-ide-extension/src/browser/contributions/indexes-update-progress.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ export class IndexesUpdateProgress extends Contribution {
1616
| undefined;
1717

1818
override onStart(): void {
19-
this.notificationCenter.onIndexWillUpdate((progressId) =>
19+
this.notificationCenter.onIndexUpdateWillStart(({progressId}) =>
2020
this.getOrCreateProgress(progressId)
2121
);
2222
this.notificationCenter.onIndexUpdateDidProgress((progress) => {
2323
this.getOrCreateProgress(progress).then((delegate) =>
2424
delegate.report(progress)
2525
);
2626
});
27-
this.notificationCenter.onIndexDidUpdate((progressId) => {
27+
this.notificationCenter.onIndexUpdateDidComplete(({progressId}) => {
2828
this.cancelProgress(progressId);
2929
});
3030
this.notificationCenter.onIndexUpdateDidFail(({ progressId, message }) => {
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
2+
import { nls } from '@theia/core/lib/common/nls';
3+
import { inject, injectable } from '@theia/core/shared/inversify';
4+
import { CoreService, IndexType } from '../../common/protocol';
5+
import { NotificationCenter } from '../notification-center';
6+
import { WindowServiceExt } from '../theia/core/window-service-ext';
7+
import { Command, CommandRegistry, Contribution } from './contribution';
8+
9+
@injectable()
10+
export class UpdateIndexes extends Contribution {
11+
@inject(WindowServiceExt)
12+
private readonly windowService: WindowServiceExt;
13+
@inject(LocalStorageService)
14+
private readonly localStorage: LocalStorageService;
15+
@inject(CoreService)
16+
private readonly coreService: CoreService;
17+
@inject(NotificationCenter)
18+
private readonly notificationCenter: NotificationCenter;
19+
20+
protected override init(): void {
21+
super.init();
22+
this.notificationCenter.onIndexUpdateDidComplete(({ summary }) =>
23+
Promise.all(
24+
Object.entries(summary).map(([type, updatedAt]) =>
25+
this.setLastUpdateDateTime(type as IndexType, updatedAt)
26+
)
27+
)
28+
);
29+
}
30+
31+
override onReady(): void {
32+
this.checkForUpdates();
33+
}
34+
35+
override registerCommands(registry: CommandRegistry): void {
36+
registry.registerCommand(UpdateIndexes.Commands.UPDATE_INDEXES, {
37+
execute: () => this.updateIndexes(IndexType.All, true),
38+
});
39+
registry.registerCommand(UpdateIndexes.Commands.UPDATE_PLATFORM_INDEX, {
40+
execute: () => this.updateIndexes(['platform'], true),
41+
});
42+
registry.registerCommand(UpdateIndexes.Commands.UPDATE_LIBRARY_INDEX, {
43+
execute: () => this.updateIndexes(['library'], true),
44+
});
45+
}
46+
47+
private async checkForUpdates(): Promise<void> {
48+
const checkForUpdates = this.preferences['arduino.checkForUpdates'];
49+
if (!checkForUpdates) {
50+
console.debug(
51+
'[update-indexes]: `arduino.checkForUpdates` is `false`. Skipping updating the indexes.'
52+
);
53+
return;
54+
}
55+
56+
if (await this.windowService.isFirstWindow()) {
57+
const summary = await this.coreService.indexUpdateSummaryBeforeInit();
58+
if (summary.message) {
59+
this.messageService.error(summary.message);
60+
}
61+
const typesToCheck = IndexType.All.filter((type) => !(type in summary));
62+
if (Object.keys(summary).length) {
63+
console.debug(
64+
`[update-indexes]: Detected an index update summary before the core gRPC client initialization. Updating local storage with ${JSON.stringify(
65+
summary
66+
)}`
67+
);
68+
} else {
69+
console.debug(
70+
'[update-indexes]: No index update summary was available before the core gRPC client initialization. Checking the status of the all the index types.'
71+
);
72+
}
73+
await Promise.allSettled([
74+
...Object.entries(summary).map(([type, updatedAt]) =>
75+
this.setLastUpdateDateTime(type as IndexType, updatedAt)
76+
),
77+
this.updateIndexes(typesToCheck),
78+
]);
79+
}
80+
}
81+
82+
private async updateIndexes(
83+
types: IndexType[],
84+
force = false
85+
): Promise<void> {
86+
const updatedAt = new Date().toISOString();
87+
return Promise.all(
88+
types.map((type) => this.needsIndexUpdate(type, updatedAt, force))
89+
).then((needsIndexUpdateResults) => {
90+
const typesToUpdate = needsIndexUpdateResults.filter(IndexType.is);
91+
if (typesToUpdate.length) {
92+
console.debug(
93+
`[update-indexes]: Requesting the index update of type: ${JSON.stringify(
94+
typesToUpdate
95+
)} with date time: ${updatedAt}.`
96+
);
97+
return this.coreService.updateIndex({ types: typesToUpdate });
98+
}
99+
});
100+
}
101+
102+
private async needsIndexUpdate(
103+
type: IndexType,
104+
now: string,
105+
force = false
106+
): Promise<IndexType | false> {
107+
if (force) {
108+
console.debug(
109+
`[update-indexes]: Update for index type: '${type}' was forcefully requested.`
110+
);
111+
return type;
112+
}
113+
const lastUpdateIsoDateTime = await this.getLastUpdateDateTime(type);
114+
if (!lastUpdateIsoDateTime) {
115+
console.debug(
116+
`[update-indexes]: No last update date time was persisted for index type: '${type}'. Index update is required.`
117+
);
118+
return type;
119+
}
120+
const lastUpdateDateTime = Date.parse(lastUpdateIsoDateTime);
121+
if (Number.isNaN(lastUpdateDateTime)) {
122+
console.debug(
123+
`[update-indexes]: Invalid last update date time was persisted for index type: '${type}'. Last update date time was: ${lastUpdateDateTime}. Index update is required.`
124+
);
125+
return type;
126+
}
127+
const diff = new Date(now).getTime() - lastUpdateDateTime;
128+
const needsIndexUpdate = diff >= this.threshold;
129+
console.debug(
130+
`[update-indexes]: Update for index type '${type}' is ${
131+
needsIndexUpdate ? '' : 'not '
132+
}required. Now: ${now}, Last index update date time: ${new Date(
133+
lastUpdateDateTime
134+
).toISOString()}, diff: ${diff} ms, threshold: ${this.threshold} ms.`
135+
);
136+
return needsIndexUpdate ? type : false;
137+
}
138+
139+
private async getLastUpdateDateTime(
140+
type: IndexType
141+
): Promise<string | undefined> {
142+
const key = this.storageKeyOf(type);
143+
return this.localStorage.getData<string>(key);
144+
}
145+
146+
private async setLastUpdateDateTime(
147+
type: IndexType,
148+
updatedAt: string
149+
): Promise<void> {
150+
const key = this.storageKeyOf(type);
151+
return this.localStorage.setData<string>(key, updatedAt).finally(() => {
152+
console.debug(
153+
`[update-indexes]: Updated the last index update date time of '${type}' to ${updatedAt}.`
154+
);
155+
});
156+
}
157+
158+
private storageKeyOf(type: IndexType): string {
159+
return `index-last-update-time--${type}`;
160+
}
161+
162+
private get threshold(): number {
163+
return 4 * 60 * 60 * 1_000; // four hours in millis
164+
}
165+
}
166+
export namespace UpdateIndexes {
167+
export namespace Commands {
168+
export const UPDATE_INDEXES: Command & { label: string } = {
169+
id: 'arduino-update-indexes',
170+
label: nls.localize(
171+
'arduino/updateIndexes/updateIndexes',
172+
'Update Indexes'
173+
),
174+
category: 'Arduino',
175+
};
176+
export const UPDATE_PLATFORM_INDEX: Command & { label: string } = {
177+
id: 'arduino-update-package-index',
178+
label: nls.localize(
179+
'arduino/updateIndexes/updatePackageIndex',
180+
'Update Package Index'
181+
),
182+
category: 'Arduino',
183+
};
184+
export const UPDATE_LIBRARY_INDEX: Command & { label: string } = {
185+
id: 'arduino-update-library-index',
186+
label: nls.localize(
187+
'arduino/updateIndexes/updateLibraryIndex',
188+
'Update Library Index'
189+
),
190+
category: 'Arduino',
191+
};
192+
}
193+
}

‎arduino-ide-extension/src/browser/notification-center.ts‎

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
88
import { DisposableCollection } from '@theia/core/lib/common/disposable';
99
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
1010
import {
11+
IndexUpdateDidCompleteParams,
12+
IndexUpdateDidFailParams,
13+
IndexUpdateWillStartParams,
1114
NotificationServiceClient,
1215
NotificationServiceServer,
1316
} from '../common/protocol/notification-service';
@@ -29,48 +32,48 @@ export class NotificationCenter
2932
implements NotificationServiceClient, FrontendApplicationContribution
3033
{
3134
@inject(NotificationServiceServer)
32-
protected readonly server: JsonRpcProxy<NotificationServiceServer>;
35+
private readonly server: JsonRpcProxy<NotificationServiceServer>;
3336

3437
@inject(FrontendApplicationStateService)
3538
private readonly appStateService: FrontendApplicationStateService;
3639

37-
protected readonly indexDidUpdateEmitter = new Emitter<string>();
38-
protected readonly indexWillUpdateEmitter = new Emitter<string>();
39-
protected readonly indexUpdateDidProgressEmitter =
40+
private readonly indexUpdateDidCompleteEmitter =
41+
new Emitter<IndexUpdateDidCompleteParams>();
42+
private readonly indexUpdateWillStartEmitter =
43+
new Emitter<IndexUpdateWillStartParams>();
44+
private readonly indexUpdateDidProgressEmitter =
4045
new Emitter<ProgressMessage>();
41-
protected readonly indexUpdateDidFailEmitter = new Emitter<{
42-
progressId: string;
43-
message: string;
44-
}>();
45-
protected readonly daemonDidStartEmitter = new Emitter<string>();
46-
protected readonly daemonDidStopEmitter = new Emitter<void>();
47-
protected readonly configDidChangeEmitter = new Emitter<{
46+
private readonly indexUpdateDidFailEmitter =
47+
new Emitter<IndexUpdateDidFailParams>();
48+
private readonly daemonDidStartEmitter = new Emitter<string>();
49+
private readonly daemonDidStopEmitter = new Emitter<void>();
50+
private readonly configDidChangeEmitter = new Emitter<{
4851
config: Config | undefined;
4952
}>();
50-
protected readonly platformDidInstallEmitter = new Emitter<{
53+
private readonly platformDidInstallEmitter = new Emitter<{
5154
item: BoardsPackage;
5255
}>();
53-
protected readonly platformDidUninstallEmitter = new Emitter<{
56+
private readonly platformDidUninstallEmitter = new Emitter<{
5457
item: BoardsPackage;
5558
}>();
56-
protected readonly libraryDidInstallEmitter = new Emitter<{
59+
private readonly libraryDidInstallEmitter = new Emitter<{
5760
item: LibraryPackage;
5861
}>();
59-
protected readonly libraryDidUninstallEmitter = new Emitter<{
62+
private readonly libraryDidUninstallEmitter = new Emitter<{
6063
item: LibraryPackage;
6164
}>();
62-
protected readonly attachedBoardsDidChangeEmitter =
65+
private readonly attachedBoardsDidChangeEmitter =
6366
new Emitter<AttachedBoardsChangeEvent>();
64-
protected readonly recentSketchesChangedEmitter = new Emitter<{
67+
private readonly recentSketchesChangedEmitter = new Emitter<{
6568
sketches: Sketch[];
6669
}>();
6770
private readonly onAppStateDidChangeEmitter =
6871
new Emitter<FrontendApplicationState>();
6972

70-
protected readonly toDispose = new DisposableCollection(
71-
this.indexWillUpdateEmitter,
73+
private readonly toDispose = new DisposableCollection(
74+
this.indexUpdateWillStartEmitter,
7275
this.indexUpdateDidProgressEmitter,
73-
this.indexDidUpdateEmitter,
76+
this.indexUpdateDidCompleteEmitter,
7477
this.indexUpdateDidFailEmitter,
7578
this.daemonDidStartEmitter,
7679
this.daemonDidStopEmitter,
@@ -82,8 +85,8 @@ export class NotificationCenter
8285
this.attachedBoardsDidChangeEmitter
8386
);
8487

85-
readonly onIndexDidUpdate = this.indexDidUpdateEmitter.event;
86-
readonly onIndexWillUpdate = this.indexDidUpdateEmitter.event;
88+
readonly onIndexUpdateDidComplete = this.indexUpdateDidCompleteEmitter.event;
89+
readonly onIndexUpdateWillStart = this.indexUpdateWillStartEmitter.event;
8790
readonly onIndexUpdateDidProgress = this.indexUpdateDidProgressEmitter.event;
8891
readonly onIndexUpdateDidFail = this.indexUpdateDidFailEmitter.event;
8992
readonly onDaemonDidStart = this.daemonDidStartEmitter.event;
@@ -112,26 +115,20 @@ export class NotificationCenter
112115
this.toDispose.dispose();
113116
}
114117

115-
notifyIndexWillUpdate(progressId: string): void {
116-
this.indexWillUpdateEmitter.fire(progressId);
118+
notifyIndexUpdateWillStart(params: IndexUpdateWillStartParams): void {
119+
this.indexUpdateWillStartEmitter.fire(params);
117120
}
118121

119122
notifyIndexUpdateDidProgress(progressMessage: ProgressMessage): void {
120123
this.indexUpdateDidProgressEmitter.fire(progressMessage);
121124
}
122125

123-
notifyIndexDidUpdate(progressId: string): void {
124-
this.indexDidUpdateEmitter.fire(progressId);
126+
notifyIndexUpdateDidComplete(params: IndexUpdateDidCompleteParams): void {
127+
this.indexUpdateDidCompleteEmitter.fire(params);
125128
}
126129

127-
notifyIndexUpdateDidFail({
128-
progressId,
129-
message,
130-
}: {
131-
progressId: string;
132-
message: string;
133-
}): void {
134-
this.indexUpdateDidFailEmitter.fire({ progressId, message });
130+
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void {
131+
this.indexUpdateDidFailEmitter.fire(params);
135132
}
136133

137134
notifyDaemonDidStart(port: string): void {

‎arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export abstract class ListWidget<
6868
@postConstruct()
6969
protected init(): void {
7070
this.toDispose.pushAll([
71-
this.notificationCenter.onIndexDidUpdate(() => this.refresh(undefined)),
71+
this.notificationCenter.onIndexUpdateDidComplete(() => this.refresh(undefined)),
7272
this.notificationCenter.onDaemonDidStart(() => this.refresh(undefined)),
7373
this.notificationCenter.onDaemonDidStop(() => this.refresh(undefined)),
7474
]);

0 commit comments

Comments
(0)

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