diff --git a/.env.example b/.env.example index ffcbba6bc0..66df73e853 100644 --- a/.env.example +++ b/.env.example @@ -482,3 +482,7 @@ DATABASE_CHUNK_SIZE= # Service Account Encryption Key for encrypting/decrypting service account keys # You can use: `openssl rand -base64 24` to generate one CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY= + +SALESFORCE_GRAPHQL_DELAY_MS=500 +SALESFORCE_GRAPHQL_MAX_DELAY_MS=2000 +SALESFORCE_GRAPHQL_MAX_RETRIES=3 diff --git a/packages/app-store/salesforce/lib/graphql/SalesforceGraphQLClient.ts b/packages/app-store/salesforce/lib/graphql/SalesforceGraphQLClient.ts index 59c4195f90..077a070d37 100644 --- a/packages/app-store/salesforce/lib/graphql/SalesforceGraphQLClient.ts +++ b/packages/app-store/salesforce/lib/graphql/SalesforceGraphQLClient.ts @@ -1,4 +1,5 @@ import { Client, cacheExchange, fetchExchange } from "@urql/core"; +import { retryExchange } from "@urql/exchange-retry"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; @@ -17,9 +18,27 @@ export class SalesforceGraphQLClient { constructor({ accessToken, instanceUrl }: { accessToken: string; instanceUrl: string }) { this.accessToken = accessToken; + + const exchanges = [cacheExchange, fetchExchange]; + + if ( + process.env.SALESFORCE_GRAPHQL_DELAY_MS && + process.env.SALESFORCE_GRAPHQL_MAX_DELAY_MS && + process.env.SALESFORCE_GRAPHQL_MAX_RETRIES + ) { + const retryOptions = { + maxRetries: 3, + initialDelayMs: Number(process.env.SALESFORCE_GRAPHQL_DELAY_MS), + maxDelayMs: Number(process.env.SALESFORCE_GRAPHQL_MAX_DELAY_MS), + randomDelay: true, + maxNumberAttempts: Number(process.env.SALESFORCE_GRAPHQL_MAX_RETRIES), + }; + exchanges.push(retryExchange(retryOptions)); + } + this.client = new Client({ url: `${instanceUrl}/services/data/${this.version}/graphql`, - exchanges: [cacheExchange, fetchExchange], + exchanges, fetchOptions: () => { return { headers: { authorization: `Bearer ${this.accessToken}` }, diff --git a/packages/app-store/salesforce/package.json b/packages/app-store/salesforce/package.json index ce11aa6cbc..c8d11df922 100644 --- a/packages/app-store/salesforce/package.json +++ b/packages/app-store/salesforce/package.json @@ -14,7 +14,8 @@ "@calcom/prisma": "workspace:*", "@jetstreamapp/soql-parser-js": "^6.1.0", "@jsforce/jsforce-node": "^3.6.3", - "@urql/core": "^5.1.1" + "@urql/core": "^5.1.1", + "@urql/exchange-retry": "^2.0.0" }, "devDependencies": { "@calcom/types": "workspace:*", diff --git a/turbo.json b/turbo.json index aa40416880..4faebfbf65 100644 --- a/turbo.json +++ b/turbo.json @@ -165,6 +165,9 @@ "RETELL_AI_TEST_CAL_API_KEY", "SALESFORCE_CONSUMER_KEY", "SALESFORCE_CONSUMER_SECRET", + "SALESFORCE_GRAPHQL_DELAY_MS", + "SALESFORCE_GRAPHQL_MAX_DELAY_MS", + "SALESFORCE_GRAPHQL_MAX_RETRIES", "SAML_ADMINS", "SAML_CLIENT_SECRET_VERIFIER", "SAML_DATABASE_URL", diff --git a/yarn.lock b/yarn.lock index c48c438a8d..feaa7c3aba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,18 @@ __metadata: version: 6 cacheKey: 8 +"@0no-co/graphql.web@npm:^1.0.13": + version: 1.2.0 + resolution: "@0no-co/graphql.web@npm:1.2.0" + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + checksum: 4d5a54b93e6024b7d476e94b991e4e4ebc4ecb97e4ce886f76889741f5e419b587bedc6a00488753069534d8ae3e4de2e901ad58506ba2f74eeb8642edccc4ca + languageName: node + linkType: hard + "@0no-co/graphql.web@npm:^1.0.5": version: 1.1.2 resolution: "@0no-co/graphql.web@npm:1.1.2" @@ -3946,6 +3958,7 @@ __metadata: "@jsforce/jsforce-node": ^3.6.3 "@parcel/watcher": ^2.5.1 "@urql/core": ^5.1.1 + "@urql/exchange-retry": ^2.0.0 graphql-config: ^5.1.3 graphql-introspection-json-to-sdl: ^1.0.3 languageName: unknown @@ -19345,6 +19358,28 @@ __metadata: languageName: node linkType: hard +"@urql/core@npm:^6.0.0": + version: 6.0.1 + resolution: "@urql/core@npm:6.0.1" + dependencies: + "@0no-co/graphql.web": ^1.0.13 + wonka: ^6.3.2 + checksum: 6cedd18dc9f386d361991c6cbde61dc45c1cac9dfa9db60274fdd9acec91185d176a5c63bb39593152490f539441e226db32bdf88cfba0af4488d90399e58482 + languageName: node + linkType: hard + +"@urql/exchange-retry@npm:^2.0.0": + version: 2.0.0 + resolution: "@urql/exchange-retry@npm:2.0.0" + dependencies: + "@urql/core": ^6.0.0 + wonka: ^6.3.2 + peerDependencies: + "@urql/core": ^6.0.0 + checksum: a75b4bfa4cdf55f202d6e35201b2a8c3219e9d5d4660b43bc29bfecc373266f1bdd6adf1efd39566a8a3e6bdf1e8e506c17a7a598b6d4205cb5ab2d79c95ab21 + languageName: node + linkType: hard + "@vercel/edge-config@npm:^0.1.1": version: 0.1.1 resolution: "@vercel/edge-config@npm:0.1.1"