Skip to content
This repository has been archived by the owner on Jun 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #334 from superfaceai/fix/polling-errors
Browse files Browse the repository at this point in the history
Fix/polling errors
  • Loading branch information
Jakub-Vacek authored Jul 17, 2023
2 parents 9387766 + 58b19cd commit 94c91fd
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 40 deletions.
4 changes: 1 addition & 3 deletions src/common/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ describe('Format utils', () => {
});

it('formats path to app root from Superface directory', () => {
expect(formatPath(APP_PATH, SUPERFACE_DIR_PATH)).toEqual(
'..'
);
expect(formatPath(APP_PATH, SUPERFACE_DIR_PATH)).toEqual('..');
});
});
});
50 changes: 34 additions & 16 deletions src/common/polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { UserError } from './error';
import type { UX } from './ux';

export const DEFAULT_POLLING_TIMEOUT_SECONDS = 300;
export const DEFAULT_POLLING_INTERVAL_SECONDS = 1;
export const DEFAULT_POLLING_INTERVAL_SECONDS = 2;

enum PollStatus {
Success = 'Success',
Expand Down Expand Up @@ -94,12 +94,10 @@ export async function pollUrl(
};
},
{
// logger,
client,
userError,
ux,
}: {
// logger: ILogger;
client: ServiceClient;
userError: UserError;
ux: UX;
Expand All @@ -111,13 +109,17 @@ export async function pollUrl(
const pollingIntervalMilliseconds =
(options?.pollingIntervalSeconds ?? DEFAULT_POLLING_INTERVAL_SECONDS) *
1000;

let lastEvenetDescription = '';
while (
new Date().getTime() - startPollingTimeStamp.getTime() <
timeoutMilliseconds
) {
const result = await pollFetch(url, { client, userError });

if (result.status === PollStatus.Success) {
ux.succeed(`Successfully finished operation`);

return result.result_url;
} else if (result.status === PollStatus.Failed) {
throw userError(
Expand All @@ -133,19 +135,23 @@ export async function pollUrl(
)}: Operation has been cancelled.`,
1
);
} else if (result.status === PollStatus.Pending) {
// get events from response and present them to user
if (result.events.length > 0 && options?.quiet !== true) {
const currentEvent = result.events[result.events.length - 1];

if (currentEvent.description !== lastEvenetDescription) {
// console.log(`${currentEvent.type} - ${currentEvent.description}`);
ux.info(`${currentEvent.type} - ${currentEvent.description}`);
}

lastEvenetDescription = currentEvent.description;

await new Promise(resolve =>
setTimeout(resolve, pollingIntervalMilliseconds)
);
}
}

// get events from response and present them to user
if (result.events.length > 0 && options?.quiet !== true) {
const lastEvent = result.events[result.events.length - 1];

ux.info(`${lastEvent.type} - ${lastEvent.description}`);
// logger.info('pollingEvent', lastEvent.type, lastEvent.description);
}

await new Promise(resolve =>
setTimeout(resolve, pollingIntervalMilliseconds)
);
}

throw userError(
Expand Down Expand Up @@ -179,7 +185,19 @@ async function pollFetch(
},
});
if (result.status === 200) {
const data = (await result.json()) as unknown;
let data: unknown;
try {
data = (await result.json()) as unknown;
} catch (error) {
throw userError(
`Unexpected response from server: ${JSON.stringify(
await result.text(),
null,
2
)}`,
1
);
}

if (isPollResponse(data)) {
return data;
Expand Down
10 changes: 8 additions & 2 deletions src/common/ux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class UX {
private lastText = '';

private constructor() {
this.spinner = createSpinner(undefined, { color: 'cyan', interval: 25 });
this.spinner = createSpinner(undefined, { color: 'cyan', interval: 50 });
UX.instance = this;
}

Expand All @@ -32,7 +32,8 @@ export class UX {
}

public info(text: string): void {
if (text !== this.lastText) {
if (text.trim() !== this.lastText.trim()) {
this.spinner.clear();
this.spinner.update({ text });
}

Expand All @@ -46,6 +47,10 @@ export class UX {
});
}

public stop(): void {
this.spinner.stop();
}

public static create(): UX {
if (UX.instance === undefined) {
UX.instance = new UX();
Expand All @@ -55,6 +60,7 @@ export class UX {
}

public static clear(): void {
UX.instance?.spinner.clear();
UX.instance?.spinner.stop();
}
}
6 changes: 4 additions & 2 deletions src/logic/application-code/dotenv/onesdk-token.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const ONESDK_TOKEN_ENV = 'SUPERFACE_ONESDK_TOKEN';
export const ONESDK_TOKEN_COMMENT = 'The token for monitoring your Comlinks at https://superface.ai'
export const ONESDK_TOKEN_UNAVAILABLE_COMMENT = 'Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai'
export const ONESDK_TOKEN_COMMENT =
'The token for monitoring your Comlinks at https://superface.ai';
export const ONESDK_TOKEN_UNAVAILABLE_COMMENT =
'Set your OneSDK token to monitor your usage out-of-the-box. Get yours at https://superface.ai';
15 changes: 10 additions & 5 deletions src/logic/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export type MapPreparationResponse = {
};

function assertMapResponse(
input: unknown
input: unknown,
{ userError }: { userError: UserError }
): asserts input is MapPreparationResponse {
if (typeof input === 'object' && input !== null && 'source' in input) {
const tmp = input as { source: string };
Expand All @@ -21,7 +22,7 @@ function assertMapResponse(
}
}

throw Error(`Unexpected response received`);
throw userError(`Unexpected response received`, 1);
}

export async function mapProviderToProfile(
Expand Down Expand Up @@ -58,6 +59,7 @@ export async function mapProviderToProfile(
return (
await finishMapPreparation(resultUrl, {
client,
userError,
})
).source;
}
Expand Down Expand Up @@ -127,7 +129,7 @@ async function startMapPreparation(

async function finishMapPreparation(
resultUrl: string,
{ client }: { client: ServiceClient }
{ client, userError }: { client: ServiceClient; userError: UserError }
): Promise<MapPreparationResponse> {
const resultResponse = await client.fetch(resultUrl, {
method: 'GET',
Expand All @@ -139,12 +141,15 @@ async function finishMapPreparation(
});

if (resultResponse.status !== 200) {
throw Error(`Unexpected status code ${resultResponse.status} received`);
throw userError(
`Unexpected status code ${resultResponse.status} received`,
1
);
}

const body = (await resultResponse.json()) as unknown;

assertMapResponse(body);
assertMapResponse(body, { userError });

return body;
}
25 changes: 16 additions & 9 deletions src/logic/new.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ProviderJson } from '@superfaceai/ast';
import { parseDocumentId, parseProfile, Source } from '@superfaceai/parser';
import { parseDocumentId, parseProfile,Source } from '@superfaceai/parser';
import type { ServiceClient } from '@superfaceai/service-client';

import type { UserError } from '../common/error';
Expand All @@ -17,7 +17,8 @@ export type ProfilePreparationResponse = {
};

function assertProfileResponse(
input: unknown
input: unknown,
{ userError }: { userError: UserError }
): asserts input is ProfilePreparationResponse {
if (
typeof input === 'object' &&
Expand All @@ -28,24 +29,26 @@ function assertProfileResponse(
const tmp = input as { id: string; profile: { source?: string } };

if (typeof tmp.profile.source !== 'string') {
throw Error(
throw userError(
`Unexpected response received - missing profile source: ${JSON.stringify(
tmp,
null,
2
)}`
)}`,
1
);
}

try {
parseProfile(new Source(tmp.profile.source));
} catch (e) {
throw Error(
throw userError(
`Unexpected response received - unable to parse profile source: ${JSON.stringify(
e,
null,
2
)}`
)}`,
1
);
}

Expand Down Expand Up @@ -84,6 +87,7 @@ export async function newProfile(

const profileResponse = await finishProfilePreparation(resultUrl, {
client,
userError,
});

// Supports both . and / in profile id
Expand Down Expand Up @@ -146,7 +150,7 @@ async function startProfilePreparation(

async function finishProfilePreparation(
resultUrl: string,
{ client }: { client: ServiceClient }
{ client, userError }: { client: ServiceClient; userError: UserError }
): Promise<ProfilePreparationResponse> {
const resultResponse = await client.fetch(resultUrl, {
method: 'GET',
Expand All @@ -158,12 +162,15 @@ async function finishProfilePreparation(
});

if (resultResponse.status !== 200) {
throw Error(`Unexpected status code ${resultResponse.status} received`);
throw userError(
`Unexpected status code ${resultResponse.status} received`,
1
);
}

const body = (await resultResponse.json()) as unknown;

assertProfileResponse(body);
assertProfileResponse(body, { userError });

return body;
}
7 changes: 4 additions & 3 deletions src/logic/prepare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export type ProviderPreparationResponse = {
};

function assertProviderResponse(
input: unknown
input: unknown,
{ userError }: { userError: UserError }
): asserts input is ProviderPreparationResponse {
if (
typeof input === 'object' &&
Expand All @@ -39,7 +40,7 @@ function assertProviderResponse(
}
}

throw Error(`Unexpected response received`);
throw userError(`Unexpected response received`, 1);
}

export async function prepareProviderJson(
Expand Down Expand Up @@ -141,7 +142,7 @@ async function finishProviderPreparation(

const body = (await resultResponse.json()) as unknown;

assertProviderResponse(body);
assertProviderResponse(body, { userError });

return body;
}

0 comments on commit 94c91fd

Please sign in to comment.