Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
taranvohra committed Jan 3, 2024
1 parent 4b212ef commit a1555f2
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 87 deletions.
89 changes: 88 additions & 1 deletion integrations/github/src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { GitBookAPI } from '@gitbook/api';
import { Logger } from '@gitbook/runtime';

import { querySpaceInstallations } from './installation';
import { triggerImport } from './sync';
import type { GithubRuntimeContext, IntegrationTask, IntegrationTaskImportSpaces } from './types';
import { handleImportDispatchForSpaces } from './webhooks';

const logger = Logger('github:tasks');

/**
* Queue a task for the integration to import spaces.
Expand Down Expand Up @@ -32,3 +38,84 @@ export async function handleIntegrationTask(
throw new Error(`Unknown integration task type: ${task}`);
}
}

/**
* This function is used to trigger an import for all the spaces that match the given config query.
* It will handle pagination by queueing itself if there are more spaces to import.
*
* `NOTE`: It is important that the total number of external network calls in this function is less
* than 50 as that is the limit imposed by Cloudflare workers.
*/
export async function handleImportDispatchForSpaces(
context: GithubRuntimeContext,
payload: IntegrationTaskImportSpaces['payload']
): Promise<number | undefined> {
const { configQuery, page, standaloneRef } = payload;

logger.debug(`handling import dispatch for spaces with payload: ${JSON.stringify(payload)}`);

const {
data: spaceInstallations,
nextPage,
total,
} = await querySpaceInstallations(context, configQuery, {
limit: 10,
page,
});

await Promise.allSettled(
spaceInstallations.map(async (spaceInstallation) => {
try {
// Obtain the installation API token needed to trigger the import
const { data: installationAPIToken } =
await context.api.integrations.createIntegrationInstallationToken(
spaceInstallation.integration,
spaceInstallation.installation
);

// Set the token in the duplicated context to be used by the API client
const installationContext: GithubRuntimeContext = {
...context,
api: new GitBookAPI({
endpoint: context.environment.apiEndpoint,
authToken: installationAPIToken.token,
}),
environment: {
...context.environment,
authToken: installationAPIToken.token,
},
};

await triggerImport(installationContext, spaceInstallation, {
standalone: standaloneRef
? {
ref: standaloneRef,
}
: undefined,
});
} catch (error) {
logger.error(
`error while triggering ${
standaloneRef ? `standalone (${standaloneRef})` : ''
} import for space ${spaceInstallation.space}`,
error
);
}
})
);

// Queue the next page if there is one
if (nextPage) {
logger.debug(`queueing next page ${nextPage} of import dispatch for spaces`);
await queueTaskForImportSpaces(context, {
type: 'import:spaces',
payload: {
page: nextPage,
configQuery,
standaloneRef,
},
});
}

return total;
}
88 changes: 2 additions & 86 deletions integrations/github/src/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import type {
} from '@octokit/webhooks-types';
import httpError from 'http-errors';

import { GitBookAPI } from '@gitbook/api';
import { Logger } from '@gitbook/runtime';

import { querySpaceInstallations } from './installation';
import { triggerImport } from './sync';
import { queueTaskForImportSpaces } from './tasks';
import { GithubRuntimeContext, IntegrationTaskImportSpaces } from './types';
import { handleImportDispatchForSpaces } from './tasks';
import { GithubRuntimeContext } from './types';
import { arrayToHex, computeConfigQueryKey, safeCompare } from './utils';

const logger = Logger('github:webhooks');
Expand Down Expand Up @@ -110,84 +107,3 @@ export async function handlePullRequestEvents(
logger.debug(`${total} space configurations are affected`);
}
}

/**
* This function is used to trigger an import for all the spaces that match the given config query.
* It will handle pagination by queueing itself if there are more spaces to import.
*
* `NOTE`: It is important that the total number of external network calls in this function is less
* than 50 as that is the limit imposed by Cloudflare workers.
*/
export async function handleImportDispatchForSpaces(
context: GithubRuntimeContext,
payload: IntegrationTaskImportSpaces['payload']
): Promise<number | undefined> {
const { configQuery, page, standaloneRef } = payload;

logger.debug(`handling import dispatch for spaces with payload: ${JSON.stringify(payload)}`);

const {
data: spaceInstallations,
nextPage,
total,
} = await querySpaceInstallations(context, configQuery, {
limit: 10,
page,
});

await Promise.allSettled(
spaceInstallations.map(async (spaceInstallation) => {
try {
// Obtain the installation API token needed to trigger the import
const { data: installationAPIToken } =
await context.api.integrations.createIntegrationInstallationToken(
spaceInstallation.integration,
spaceInstallation.installation
);

// Set the token in the duplicated context to be used by the API client
const installationContext: GithubRuntimeContext = {
...context,
api: new GitBookAPI({
endpoint: context.environment.apiEndpoint,
authToken: installationAPIToken.token,
}),
environment: {
...context.environment,
authToken: installationAPIToken.token,
},
};

await triggerImport(installationContext, spaceInstallation, {
standalone: standaloneRef
? {
ref: standaloneRef,
}
: undefined,
});
} catch (error) {
logger.error(
`error while triggering ${
standaloneRef ? `standalone (${standaloneRef})` : ''
} import for space ${spaceInstallation.space}`,
error
);
}
})
);

// Queue the next page if there is one
if (nextPage) {
logger.debug(`queueing next page ${nextPage} of import dispatch for spaces`);
await queueTaskForImportSpaces(context, {
type: 'import:spaces',
payload: {
page: nextPage,
configQuery,
standaloneRef,
},
});
}

return total;
}

0 comments on commit a1555f2

Please sign in to comment.