Skip to content

Initial retries support #114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions etc/astra-db-ts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ export interface AddVectorizeOperation<Schema extends SomeRow> {

// @public
export abstract class AdminCommandEvent extends BaseClientEvent {
// Warning: (ae-forgotten-export) The symbol "DevOpsAPIRequestInfo" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "DevOpsAPIRequestMetadata" needs to be exported by the entry point index.d.ts
//
// @internal
protected constructor(name: string, requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, longRunning: boolean);
protected constructor(name: string, metadata: DevOpsAPIRequestMetadata);
// (undocumented)
getMessagePrefix(): string;
readonly invokingMethod: string;
Expand All @@ -122,7 +122,7 @@ export type AdminCommandEventMap = {
// @public
export class AdminCommandFailedEvent extends AdminCommandEvent {
// @internal
constructor(requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, longRunning: boolean, error: Error, started: number);
constructor(metadata: DevOpsAPIRequestMetadata, error: Error);
readonly duration: number;
readonly error: Error;
// (undocumented)
Expand All @@ -134,7 +134,7 @@ export class AdminCommandFailedEvent extends AdminCommandEvent {
// @public
export class AdminCommandPollingEvent extends AdminCommandEvent {
// @internal
constructor(requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, started: number, interval: number, pollCount: number);
constructor(metadata: DevOpsAPIRequestMetadata, interval: number, pollCount: number);
readonly elapsed: number;
// (undocumented)
getMessage(): string;
Expand All @@ -147,7 +147,7 @@ export class AdminCommandPollingEvent extends AdminCommandEvent {
// @public
export class AdminCommandStartedEvent extends AdminCommandEvent {
// @internal
constructor(requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, longRunning: boolean, timeout: Partial<TimeoutDescriptor>);
constructor(metadata: DevOpsAPIRequestMetadata);
// (undocumented)
getMessage(): string;
// @internal
Expand All @@ -158,7 +158,7 @@ export class AdminCommandStartedEvent extends AdminCommandEvent {
// @public
export class AdminCommandSucceededEvent extends AdminCommandEvent {
// @internal
constructor(requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, longRunning: boolean, data: Record<string, any> | undefined, started: number);
constructor(metadata: DevOpsAPIRequestMetadata, data: Record<string, any> | undefined);
readonly duration: number;
// (undocumented)
getMessage(): string;
Expand All @@ -170,7 +170,7 @@ export class AdminCommandSucceededEvent extends AdminCommandEvent {
// @public
export class AdminCommandWarningsEvent extends AdminCommandEvent {
// @internal
constructor(requestId: string, baseUrl: string, info: DevOpsAPIRequestInfo, longRunning: boolean, warnings: NonEmpty<DataAPIWarningDescriptor>);
constructor(metadata: DevOpsAPIRequestMetadata, warnings: NonEmpty<DataAPIWarningDescriptor>);
// (undocumented)
getMessage(): string;
// @internal
Expand Down Expand Up @@ -386,8 +386,10 @@ export class AWSEmbeddingHeadersProvider extends StaticHeadersProvider<'embeddin

// @public
export abstract class BaseClientEvent {
// Warning: (ae-forgotten-export) The symbol "RequestId" needs to be exported by the entry point index.d.ts
//
// @internal
protected constructor(name: string, requestId: string, extra: Record<string, unknown> | undefined);
protected constructor(name: string, requestId: RequestId, extra: Record<string, unknown> | undefined);
readonly extraLogInfo?: Record<string, any>;
format(formatter?: EventFormatter): string;
formatVerbose(): string;
Expand Down Expand Up @@ -855,10 +857,10 @@ export type CollTypeCodecOpts = TypeCodecOpts<CollectionSerCtx, CollectionDesCtx

// @public
export abstract class CommandEvent extends BaseClientEvent {
// Warning: (ae-forgotten-export) The symbol "DataAPIRequestInfo" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "DataAPIRequestMetadata" needs to be exported by the entry point index.d.ts
//
// @internal
protected constructor(name: string, requestId: string, info: DataAPIRequestInfo, extra: Record<string, unknown> | undefined);
protected constructor(name: string, metadata: DataAPIRequestMetadata);
readonly command: Record<string, any>;
get commandName(): string;
// @internal (undocumented)
Expand Down Expand Up @@ -904,7 +906,7 @@ export type CommandEventTarget = {
// @public
export class CommandFailedEvent extends CommandEvent {
// @internal
constructor(requestId: string, info: DataAPIRequestInfo, extra: Record<string, unknown> | undefined, reply: RawDataAPIResponse | undefined, error: Error, started: number);
constructor(metadata: DataAPIRequestMetadata, reply: RawDataAPIResponse | undefined, error: Error);
readonly duration: number;
readonly error: Error;
// (undocumented)
Expand All @@ -918,8 +920,14 @@ export class CommandFailedEvent extends CommandEvent {

// @public
export interface CommandOptions<Spec extends CommandOptionsSpec = Required<CommandOptionsSpec>> {
// (undocumented)
isSafelyRetryable?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you imagine users will set isSafelyRetryable on every command they want to be able to retry? Or will isSafelyRetryable be set on commands like findOne() that are read only by default?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSafelyRetryable will be an option people can use to force-set a method as either idempotent or not; otherwise, each method will have its own default idempotency.

Btw retries are still a far-fetched idea in its early experimental stage, so I wouldn't pay them too much heed for the time being 🙂 there's a very rough brain-dump-like spec in our internal "yellow doc" which you should have access to if you want more information.

// @deprecated
maxTimeMS?: 'ERROR: The `maxTimeMS` option is no longer available; the timeouts system has been overhauled, and timeouts should now be set using `timeout`';
// Warning: (ae-forgotten-export) The symbol "RetryConfig" needs to be exported by the entry point index.d.ts
//
// (undocumented)
retry?: RetryConfig;
timeout?: number | Pick<Partial<TimeoutDescriptor>, 'requestTimeoutMs' | Exclude<Spec['timeout'], undefined>>;
}

Expand All @@ -932,7 +940,7 @@ export interface CommandOptionsSpec {
// @public
export class CommandStartedEvent extends CommandEvent {
// @internal
constructor(requestId: string, info: DataAPIRequestInfo, extra: Record<string, unknown> | undefined);
constructor(metadata: DataAPIRequestMetadata);
// (undocumented)
getMessage(): string;
// @internal
Expand All @@ -943,7 +951,7 @@ export class CommandStartedEvent extends CommandEvent {
// @public
export class CommandSucceededEvent extends CommandEvent {
// @internal
constructor(requestId: string, info: DataAPIRequestInfo, extra: Record<string, unknown> | undefined, reply: RawDataAPIResponse, started: number);
constructor(metadata: DataAPIRequestMetadata, reply: RawDataAPIResponse);
readonly duration: number;
// (undocumented)
getMessage(): string;
Expand All @@ -955,7 +963,7 @@ export class CommandSucceededEvent extends CommandEvent {
// @public
export class CommandWarningsEvent extends CommandEvent {
// @internal
constructor(requestId: string, info: DataAPIRequestInfo, extra: Record<string, unknown> | undefined, warnings: NonEmpty<DataAPIWarningDescriptor>);
constructor(metadata: DataAPIRequestMetadata, warnings: NonEmpty<DataAPIWarningDescriptor>);
// (undocumented)
getMessage(): string;
// @internal
Expand Down Expand Up @@ -1327,8 +1335,6 @@ export class DataAPITimeoutError extends DataAPIError {
//
// @internal
constructor(info: HTTPRequestInfo, types: TimedOutCategories);
// @internal (undocumented)
static mk(this: void, info: HTTPRequestInfo, types: TimedOutCategories): DataAPITimeoutError;
readonly timedOutCategories: TimedOutCategories;
readonly timeout: Partial<TimeoutDescriptor>;
}
Expand Down Expand Up @@ -1523,8 +1529,6 @@ export class DevOpsAPIResponseError extends DevOpsAPIError {
export class DevOpsAPITimeoutError extends DevOpsAPIError {
// @internal
constructor(info: HTTPRequestInfo, types: TimedOutCategories);
// @internal (undocumented)
static mk(this: void, info: HTTPRequestInfo, types: TimedOutCategories): DevOpsAPITimeoutError;
readonly timedOutCategories: TimedOutCategories;
readonly timeout: Partial<TimeoutDescriptor>;
readonly url: string;
Expand Down Expand Up @@ -2228,6 +2232,11 @@ export type MaybeId<T> = NoId<T> & {
_id?: IdOf<T>;
};

// @internal (undocumented)
export type Mut<T extends object> = {
-readonly [K in keyof T]: T[K];
};

// @public
export type NoId<Doc> = Omit<Doc, '_id'>;

Expand Down
Binary file modified examples/astra-db-ts.tgz
Binary file not shown.
2 changes: 1 addition & 1 deletion examples/browser/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/cloudflare-workers/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/customize-http/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/logging/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/nextjs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/non-astra-backends/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/serdes/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/using-http2/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions scripts/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ function LibCheck(): Step {
});
} catch (_) {
Utils.printFailed('Library compilation failed');

await spinner('Rerunning tsc with captured output...', async () => {
await $({ stdio: 'inherit', nothrow: true })`npx tsc`;
});
}
} else {
Utils.printFailed('Could not set up library for lib-check phase');
Expand Down
15 changes: 9 additions & 6 deletions src/administration/astra-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { AstraDbAdmin } from '@/src/administration/astra-db-admin.js';
import { Db } from '@/src/db/db.js';
import { buildAstraDatabaseAdminInfo } from '@/src/administration/utils.js';
import { DEFAULT_DEVOPS_API_ENDPOINTS, DEFAULT_KEYSPACE, HttpMethods } from '@/src/lib/api/constants.js';
import { DevOpsAPIHttpClient } from '@/src/lib/api/clients/devops-api-http-client.js';
import { DevOpsAPIHttpClient } from '@/src/lib/api/clients/impls/devops-api-http-client.js';
import type { CommandOptions, OpaqueHttpClient } from '@/src/lib/index.js';
import { HierarchicalLogger, TokenProvider } from '@/src/lib/index.js';
import type { AstraFullDatabaseInfo } from '@/src/administration/types/admin/database-info.js';
Expand Down Expand Up @@ -283,7 +283,8 @@ export class AstraAdmin extends HierarchicalLogger<AdminCommandEventMap> {
method: HttpMethods.Get,
path: `/databases/${id}`,
methodName: 'admin.dbInfo',
}, tm);
timeoutManager: tm,
});

return buildAstraDatabaseAdminInfo(resp.data!, this.#environment);
}
Expand Down Expand Up @@ -341,7 +342,8 @@ export class AstraAdmin extends HierarchicalLogger<AdminCommandEventMap> {
path: `/databases`,
params: params,
methodName: 'admin.listDatabases',
}, tm);
timeoutManager: tm,
});

return resp.data!.map((d: SomeDoc) => buildAstraDatabaseAdminInfo(d, this.#environment));
}
Expand Down Expand Up @@ -414,12 +416,12 @@ export class AstraAdmin extends HierarchicalLogger<AdminCommandEventMap> {
path: '/databases',
data: definition,
methodName: 'admin.createDatabase',
timeoutManager: tm,
}, {
id: (resp) => resp.headers.location,
target: 'ACTIVE',
legalStates: ['INITIALIZING', 'PENDING'],
defaultPollInterval: 10000,
timeoutManager: tm,
options,
});

Expand Down Expand Up @@ -462,12 +464,12 @@ export class AstraAdmin extends HierarchicalLogger<AdminCommandEventMap> {
method: HttpMethods.Post,
path: `/databases/${id}/terminate`,
methodName: 'admin.dropDatabase',
timeoutManager: tm,
}, {
id: id,
target: 'TERMINATED',
legalStates: ['TERMINATING'],
defaultPollInterval: 10000,
timeoutManager: tm,
options,
});
}
Expand Down Expand Up @@ -524,7 +526,8 @@ export class AstraAdmin extends HierarchicalLogger<AdminCommandEventMap> {
'region-type': 'vector',
},
methodName: 'admin.findAvailableRegions',
}, tm);
timeoutManager: tm,
});

return resp.data!.map((region: any): AstraAvailableRegionInfo => ({
classification: region.classification,
Expand Down
15 changes: 8 additions & 7 deletions src/administration/astra-db-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import type { OpaqueHttpClient, CommandOptions } from '@/src/lib/index.js';
import { TokenProvider } from '@/src/lib/index.js';
import { buildAstraDatabaseAdminInfo, extractAstraEnvironment } from '@/src/administration/utils.js';
import { DEFAULT_DEVOPS_API_ENDPOINTS, HttpMethods } from '@/src/lib/api/constants.js';
import type { DevOpsAPIRequestInfo } from '@/src/lib/api/clients/devops-api-http-client.js';
import { DevOpsAPIHttpClient } from '@/src/lib/api/clients/devops-api-http-client.js';
import type { ExecuteDevOpsAPIOperationOptions } from '@/src/lib/api/clients/impls/devops-api-http-client.js';
import { DevOpsAPIHttpClient } from '@/src/lib/api/clients/impls/devops-api-http-client.js';
import type { Db } from '@/src/db/index.js';
import { $CustomInspect } from '@/src/lib/constants.js';
import type { AstraFullDatabaseInfo } from '@/src/administration/types/admin/database-info.js';
Expand Down Expand Up @@ -212,12 +212,12 @@ export class AstraDbAdmin extends DbAdmin {
method: HttpMethods.Post,
path: `/databases/${this.#db.id}/keyspaces/${keyspace}`,
methodName: 'dbAdmin.createKeyspace',
timeoutManager: tm,
}, {
id: this.#db.id,
target: 'ACTIVE',
legalStates: ['MAINTENANCE'],
defaultPollInterval: 1000,
timeoutManager: tm,
options,
});
}
Expand Down Expand Up @@ -260,12 +260,12 @@ export class AstraDbAdmin extends DbAdmin {
method: HttpMethods.Delete,
path: `/databases/${this.#db.id}/keyspaces/${keyspace}`,
methodName: 'dbAdmin.dropKeyspace',
timeoutManager: tm,
}, {
id: this.#db.id,
target: 'ACTIVE',
legalStates: ['MAINTENANCE'],
defaultPollInterval: 1000,
timeoutManager: tm,
options,
});
}
Expand Down Expand Up @@ -298,12 +298,12 @@ export class AstraDbAdmin extends DbAdmin {
method: HttpMethods.Post,
path: `/databases/${this.#db.id}/terminate`,
methodName: 'dbAdmin.drop',
timeoutManager: tm,
}, {
id: this.#db.id,
target: 'TERMINATED',
legalStates: ['TERMINATING'],
defaultPollInterval: 10000,
timeoutManager: tm,
options,
});
}
Expand All @@ -312,12 +312,13 @@ export class AstraDbAdmin extends DbAdmin {
return this.#httpClient;
}

async #info(methodName: DevOpsAPIRequestInfo['methodName'], tm: TimeoutManager): Promise<AstraFullDatabaseInfo> {
async #info(methodName: ExecuteDevOpsAPIOperationOptions['methodName'], tm: TimeoutManager): Promise<AstraFullDatabaseInfo> {
const resp = await this.#httpClient.request({
method: HttpMethods.Get,
path: `/databases/${this.#db.id}`,
timeoutManager: tm,
methodName,
}, tm);
});

return buildAstraDatabaseAdminInfo(resp.data!, this.#environment);
}
Expand Down
2 changes: 1 addition & 1 deletion src/administration/data-api-db-admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import type { CreateDataAPIKeyspaceOptions } from '@/src/administration/types/index.js';
import { DbAdmin } from '@/src/administration/db-admin.js';
import type { OpaqueHttpClient, CommandOptions } from '@/src/lib/index.js';
import type { DataAPIHttpClient } from '@/src/lib/api/clients/data-api-http-client.js';
import type { DataAPIHttpClient } from '@/src/lib/api/clients/impls/data-api-http-client.js';
import type { Db } from '@/src/db/index.js';
import { $CustomInspect } from '@/src/lib/constants.js';
import type { ParsedAdminOptions } from '@/src/client/opts-handlers/admin-opts-handler.js';
Expand Down
Loading