Skip to content

[fga] retry write relationships #18683

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

Merged
merged 1 commit into from
Sep 8, 2023
Merged
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
49 changes: 33 additions & 16 deletions components/server/src/authorization/spicedb-authorizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,40 @@ export class SpiceDBAuthorizer {
}

async writeRelationships(...updates: v1.RelationshipUpdate[]): Promise<v1.WriteRelationshipsResponse | undefined> {
const timer = spicedbClientLatency.startTimer();
let error: Error | undefined;
try {
const response = await this.client.writeRelationships(
v1.WriteRelationshipsRequest.create({
updates,
}),
this.callOptions,
);
log.info("[spicedb] Successfully wrote relationships.", { response, updates });
let tries = 0;
// we do sometimes see INTERNAL errors from SpiceDB, so we retry a few times
// last time we checked it was 15 times per day (check logs)
while (tries++ < 3) {
const timer = spicedbClientLatency.startTimer();
let error: Error | undefined;
try {
const response = await this.client.writeRelationships(
v1.WriteRelationshipsRequest.create({
updates,
}),
this.callOptions,
);
log.info("[spicedb] Successfully wrote relationships.", { response, updates, tries });

return response;
} catch (err) {
error = err;
log.error("[spicedb] Failed to write relationships.", err, { updates: new TrustedValue(updates) });
} finally {
observeSpicedbClientLatency("write", error, timer());
return response;
} catch (err) {
error = err;
if (err.code === grpc.status.INTERNAL && tries < 3) {
log.warn("[spicedb] Failed to write relationships.", err, {
updates: new TrustedValue(updates),
tries,
});
} else {
log.error("[spicedb] Failed to write relationships.", err, {
updates: new TrustedValue(updates),
tries,
});
// we don't try again on other errors
return;
}
} finally {
observeSpicedbClientLatency("write", error, timer());
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions components/server/src/orgs/usage-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { inject, injectable } from "inversify";
import { Authorizer } from "../authorization/authorizer";
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
import { CostCenterJSON, ListUsageRequest, ListUsageResponse } from "@gitpod/gitpod-protocol/lib/usage";
import { TrustedValue } from "@gitpod/gitpod-protocol/lib/util/scrubbing";

@injectable()
export class UsageService {
Expand Down Expand Up @@ -149,19 +150,19 @@ export class UsageService {
const currentInvoiceCredits = creditBalance.usedCredits;
const usageLimit = creditBalance.usageLimit;
if (currentInvoiceCredits >= usageLimit) {
log.info({ userId }, "Usage limit reached", {
log.info({ userId, organizationId }, "Usage limit reached", {
attributionId,
currentInvoiceCredits,
currentInvoiceCredits: new TrustedValue(currentInvoiceCredits),
usageLimit,
});
return {
reached: true,
attributionId,
};
} else if (currentInvoiceCredits > usageLimit * 0.8) {
log.info({ userId }, "Usage limit almost reached", {
log.info({ userId, organizationId }, "Usage limit almost reached", {
attributionId,
currentInvoiceCredits,
currentInvoiceCredits: new TrustedValue(currentInvoiceCredits),
usageLimit,
});
return {
Expand Down