blob: d8cdc0032aa8cfc1ab55d0de944e4c9330d739cd [file] [log] [blame]
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:meta/meta.dart';
import '../foundation/utils.dart';
import '../request_handling/body.dart';
import '../request_handling/request_handler.dart';
import '../service/github_service.dart';
import '../service/logging.dart';
@immutable
/// Endpoint to collect the current GitHub API quota usage of the flutter-dashboard app.
///
/// This endpoint pushes data to BigQuery for metric collection to analyze usage over time. There
/// is a cron job set to run every minute, behind a [CacheRequestHandler] to ensure there exists
/// at most one entry per repo per minute.
///
/// BigQuery entries contain the following fields:
/// `timestamp`: [DateTime] of this entry.
/// `limit`: Total API calls allowed on flutter-dashboard.
/// `remaining`: Total number of API calls remaining before flutter-dashboard is blocked from sending further requests.
/// `resets`: [DateTime] when [remaining] will reset back to [limit].
class GithubRateLimitStatus extends RequestHandler<Body> {
const GithubRateLimitStatus({
required super.config,
});
@override
Future<Body> get() async {
final GithubService githubService = await config.createDefaultGitHubService();
final Map<String, dynamic> quotaUsage = (await githubService.getRateLimit()).toJson();
quotaUsage['timestamp'] = DateTime.now().toIso8601String();
final int remainingQuota = quotaUsage['remaining'] as int;
final int quotaLimit = quotaUsage['limit'] as int;
const double githubQuotaUsageSLO = 0.5;
if (remainingQuota < githubQuotaUsageSLO * quotaLimit) {
log.warning(
'Remaining GitHub quota is $remainingQuota, which is less than quota usage SLO ${githubQuotaUsageSLO * quotaLimit} (${githubQuotaUsageSLO * 100}% of the limit $quotaLimit)).',
);
}
/// Insert quota usage to BigQuery
const String githubQuotaTable = 'GithubQuotaUsage';
await insertBigquery(githubQuotaTable, quotaUsage, await config.createTabledataResourceApi());
return Body.forJson(quotaUsage);
}
}