Path: blob/main/components/dashboard/src/usage/download/get-usage-records.ts
2500 views
/**1* Copyright (c) 2023 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56import { ListUsageRequest, Ordering, Usage } from "@gitpod/gitpod-protocol/lib/usage";7import { getGitpodService } from "../../service/service";89type GetAllUsageRecordsArgs = Pick<ListUsageRequest, "attributionId" | "from" | "to"> & {10signal?: AbortSignal;11onProgress?: (percentage: number) => void;12};1314export const getAllUsageRecords = async ({15attributionId,16from,17to,18signal,19onProgress,20}: GetAllUsageRecordsArgs): Promise<Usage[]> => {21let page = 1;22let totalPages: number | null = null;23let records: Usage[] = [];2425while (totalPages === null || page <= totalPages) {26if (signal?.aborted === true) {27return [];28}2930const timer = new Promise((r) => setTimeout(r, 1000));3132const resp = await getUsagePage({33attributionId,34from,35to,36page,37});38records = records.concat(resp.usageEntriesList);39totalPages = resp.pagination?.totalPages ?? 0;4041if (totalPages > 0) {42onProgress && onProgress(Math.ceil((page / totalPages) * 100));43}4445// ensure we only call once per second46// TODO: consider starting timer here to ensure 1s between call completing and next call vs. 1s between start and next call47await timer;4849page = page + 1;50}5152return records;53};5455type GetUsagePageArgs = Pick<ListUsageRequest, "attributionId" | "from" | "to"> & {56page: number;57};58const getUsagePage = async ({ attributionId, from, to, page }: GetUsagePageArgs) => {59const request: ListUsageRequest = {60attributionId,61from,62to,63order: Ordering.ORDERING_DESCENDING,64pagination: {65perPage: 1000,66page,67},68};6970return await getGitpodService().server.listUsage(request);71};727374