Skip to content

Commit

Permalink
Handle query errors and reduce rate limit
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Mäder <t.s.maeder@gmail.com>
  • Loading branch information
tsmaeder committed Jul 11, 2024
1 parent 50f73f7 commit 5b86871
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
if: runner.os == 'Linux'
shell: bash
run: |
yarn -s download:plugins
yarn -s download:plugins --rate-limit 3
- name: Build
shell: bash
Expand Down
5 changes: 3 additions & 2 deletions dev-packages/ovsx-client/src/ovsx-api-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ export class OVSXApiFilterImpl implements OVSXApiFilter {
let offset = 0;
let loop = true;
while (loop) {
const queryOptions = {
const queryOptions: VSXQueryOptions = {
...query,
offset
offset,
size: 5 // there is a great chance that the newest version will work
};
const results = await this.client.query(queryOptions);
const compatibleExtension = this.getLatestCompatibleExtension(results.extensions);
Expand Down
1 change: 0 additions & 1 deletion dev-packages/ovsx-client/src/ovsx-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export interface VSXSearchOptions {
* Should be aligned with https://github.com/eclipse/openvsx/blob/e8f64fe145fc05d2de1469735d50a7a90e400bc4/server/src/main/java/org/eclipse/openvsx/json/SearchResultJson.java
*/
export interface VSXSearchResult {
error?: string;
offset: number;
extensions: VSXSearchEntry[];
}
Expand Down
76 changes: 43 additions & 33 deletions packages/vsx-registry/src/browser/vsx-extensions-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,49 +225,59 @@ export class VSXExtensionsModel {
}
const client = await this.clientProvider();
const filter = await this.vsxApiFilter();
const result = await client.search(param);
this._searchError = result.error;
if (token.isCancellationRequested) {
return;
}
for (const data of result.extensions) {
const id = data.namespace.toLowerCase() + '.' + data.name.toLowerCase();
const allVersions = filter.getLatestCompatibleVersion(data);
if (!allVersions) {
continue;
try {
const result = await client.search(param);

if (token.isCancellationRequested) {
return;
}
if (this.preferences.get('extensions.onlyShowVerifiedExtensions')) {
this.fetchVerifiedStatus(id, client, allVersions).then(verified => {
this.doChange(() => {
this.addExtensions(data, id, allVersions, !!verified);
return Promise.resolve();
for (const data of result.extensions) {
const id = data.namespace.toLowerCase() + '.' + data.name.toLowerCase();
const allVersions = filter.getLatestCompatibleVersion(data);
if (!allVersions) {
continue;
}
if (this.preferences.get('extensions.onlyShowVerifiedExtensions')) {
this.fetchVerifiedStatus(id, client, allVersions).then(verified => {
this.doChange(() => {
this.addExtensions(data, id, allVersions, !!verified);
return Promise.resolve();
});
});
});
} else {
this.addExtensions(data, id, allVersions);
this.fetchVerifiedStatus(id, client, allVersions).then(verified => {
this.doChange(() => {
let extension = this.getExtension(id);
extension = this.setExtension(id);
extension.update(Object.assign({
verified: verified
}));
return Promise.resolve();
} else {
this.addExtensions(data, id, allVersions);
this.fetchVerifiedStatus(id, client, allVersions).then(verified => {
this.doChange(() => {
let extension = this.getExtension(id);
extension = this.setExtension(id);
extension.update(Object.assign({
verified: verified
}));
return Promise.resolve();
});
});
});
}
}
} catch (error) {
this._searchError = error;
}

}, token);
}

protected async fetchVerifiedStatus(id: string, client: OVSXClient, allVersions: VSXAllVersions): Promise<boolean | undefined> {
const res = await client.query({ extensionId: id, extensionVersion: allVersions.version, includeAllVersions: true });
const extension = res.extensions?.[0];
let verified = extension?.verified;
if (!verified && extension?.publishedBy.loginName === 'open-vsx') {
verified = true;
try {
const res = await client.query({ extensionId: id, extensionVersion: allVersions.version, includeAllVersions: true });
const extension = res.extensions?.[0];
let verified = extension?.verified;
if (!verified && extension?.publishedBy.loginName === 'open-vsx') {
verified = true;
}
return verified;
} catch (error) {
console.error(error);
return false;
}
return verified;
}

protected addExtensions(data: VSXSearchEntry, id: string, allVersions: VSXAllVersions, verified?: boolean): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,47 +42,49 @@ export class VSXLanguageQuickPickService extends LanguageQuickPickService {

protected override async getAvailableLanguages(): Promise<LanguageQuickPickItem[]> {
const client = await this.clientProvider();
const searchResult = await client.search({
category: 'Language Packs',
sortBy: 'downloadCount',
sortOrder: 'desc',
size: 20
});
if (searchResult.error) {
throw new Error('Error while loading available languages: ' + searchResult.error);
}
try {
const searchResult = await client.search({
category: 'Language Packs',
sortBy: 'downloadCount',
sortOrder: 'desc',
size: 20
});

const extensionLanguages = await Promise.all(
searchResult.extensions.map(async extension => ({
extension,
languages: await this.loadExtensionLanguages(extension)
}))
);
const extensionLanguages = await Promise.all(
searchResult.extensions.map(async extension => ({
extension,
languages: await this.loadExtensionLanguages(extension)
}))
);

const languages = new Map<string, LanguageQuickPickItem>();
const languages = new Map<string, LanguageQuickPickItem>();

for (const extension of extensionLanguages) {
for (const localizationContribution of extension.languages) {
if (!languages.has(localizationContribution.languageId)) {
languages.set(localizationContribution.languageId, {
...this.createLanguageQuickPickItem(localizationContribution),
execute: async () => {
const progress = await this.messageService.showProgress({
text: nls.localizeByDefault('Installing {0} language support...',
localizationContribution.localizedLanguageName ?? localizationContribution.languageName ?? localizationContribution.languageId),
});
try {
const extensionUri = VSCodeExtensionUri.fromId(`${extension.extension.namespace}.${extension.extension.name}`).toString();
await this.pluginServer.deploy(extensionUri);
} finally {
progress.cancel();
for (const extension of extensionLanguages) {
for (const localizationContribution of extension.languages) {
if (!languages.has(localizationContribution.languageId)) {
languages.set(localizationContribution.languageId, {
...this.createLanguageQuickPickItem(localizationContribution),
execute: async () => {
const progress = await this.messageService.showProgress({
text: nls.localizeByDefault('Installing {0} language support...',
localizationContribution.localizedLanguageName ?? localizationContribution.languageName ?? localizationContribution.languageId),
});
try {
const extensionUri = VSCodeExtensionUri.fromId(`${extension.extension.namespace}.${extension.extension.name}`).toString();
await this.pluginServer.deploy(extensionUri);
} finally {
progress.cancel();
}
}
}
});
});
}
}
}
return Array.from(languages.values());
} catch (error) {
console.error(error);
return [];
}
return Array.from(languages.values());
}

protected async loadExtensionLanguages(extension: VSXSearchEntry): Promise<LanguageInfo[]> {
Expand Down

0 comments on commit 5b86871

Please sign in to comment.