Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ final class BatchBackfiller extends RequestHandler {
}
final fsGrid = await _firestore.queryRecentCommitsAndTasks(
slug,
commitLimit: config.backfillerCommitLimit,
commitLimit: config.flags.backfillerCommitLimit,
branch: branch.reference,
);
await _doBackfillFrom(slug, fsGrid);
Expand All @@ -74,7 +74,7 @@ final class BatchBackfiller extends RequestHandler {
log.debug('Running default branch backfiller for "$slug"');
final fsGrid = await _firestore.queryRecentCommitsAndTasks(
slug,
commitLimit: config.backfillerCommitLimit,
commitLimit: config.flags.backfillerCommitLimit,
branch: Config.defaultBranch(slug),
);
return await _doBackfillFrom(slug, fsGrid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ final class VacuumStaleTasks extends RequestHandler {

final recentCommits = await _firestore.queryRecentCommitsAndTasks(
slug,
commitLimit: config.backfillerCommitLimit,
commitLimit: config.flags.backfillerCommitLimit,
status: TaskStatus.inProgress,
branch: branch,
);
Expand Down
23 changes: 13 additions & 10 deletions app_dart/lib/src/service/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
import '../../cocoon_service.dart';
import '../foundation/providers.dart' show Providers;
import '../foundation/typedefs.dart' show HttpClientProvider;
import 'flags/content_aware_hashing_flags.dart';
import 'github_service.dart';
import 'luci_build_service/cipd_version.dart';

Expand All @@ -33,6 +34,9 @@ interface class Config {
Config(this._cache, this._secrets, {required DynamicConfig dynamicConfig})
: _dynamicConfig = dynamicConfig;

/// Access dynamically configured flags.
DynamicConfig get flags => _dynamicConfig;

/// When present on a pull request, instructs Cocoon to submit it
/// automatically as soon as all the required checks pass.
///
Expand Down Expand Up @@ -211,12 +215,6 @@ interface class Config {
/// the next API call.
int get backfillerTargetLimit => 75;

/// Upper limit of commit rows to be backfilled in API call.
///
/// This limits the number of commits to be checked to backfill. When bots
/// are idle, we hope to scan as many commit rows as possible.
int get backfillerCommitLimit => _dynamicConfig.backfillerCommitLimit;

/// Upper limit of issue/PRs allowed each API call.
///
/// GitHub enforces a secondary rate limit on frequency API calls. This causes
Expand Down Expand Up @@ -504,7 +502,7 @@ interface class Config {
///
/// Should be read from git/HEAD/app_dart/config.yaml and cached between
/// services.
@JsonSerializable()
@JsonSerializable(explicitToJson: true)
@immutable
final class DynamicConfig {
/// Upper limit of commit rows to be backfilled in API call.
Expand All @@ -514,12 +512,17 @@ final class DynamicConfig {
@JsonKey(defaultValue: 50)
final int backfillerCommitLimit;

DynamicConfig({required this.backfillerCommitLimit});
final ContentAwareHashingJson contentAwareHashing;

DynamicConfig({
required this.backfillerCommitLimit,
required this.contentAwareHashing,
});

/// Connect the generated [_$DynamicConfigFromJson] function to the `fromJson`
/// factory.
factory DynamicConfig.fromJson(Map<String, Object?> json) =>
_$DynamicConfigFromJson(json);
factory DynamicConfig.fromJson(Map<String, Object?>? json) =>
_$DynamicConfigFromJson(json ?? {});

/// Connect the generated [_$DynamicConfigToJson] function to the `toJson` method.
Map<String, dynamic> toJson() => _$DynamicConfigToJson(this);
Expand Down
8 changes: 7 additions & 1 deletion app_dart/lib/src/service/config.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions app_dart/lib/src/service/flags/content_aware_hashing_flags.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2025 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 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';

part 'content_aware_hashing_flags.g.dart';

@JsonSerializable()
@immutable
final class ContentAwareHashingJson {
ContentAwareHashingJson({required this.waitOnContentHash});

/// Merge Groups should wait for the content hash before scheduling.
@JsonKey(defaultValue: false)
final bool waitOnContentHash;

/// Connect the generated [_$ContentAwareHashingJsonFromJson] function to the `fromJson`
/// factory.
factory ContentAwareHashingJson.fromJson(Map<String, Object?>? json) =>
_$ContentAwareHashingJsonFromJson(json ?? {});

/// Connect the generated [_$ContentAwareHashingJsonToJson] function to the `toJson` method.
Map<String, dynamic> toJson() => _$ContentAwareHashingJsonToJson(this);
}
19 changes: 19 additions & 0 deletions app_dart/lib/src/service/flags/content_aware_hashing_flags.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ void main() {
mockGithubChecksUtil = MockGithubChecksUtil();
firestore = FakeFirestoreService();
config = FakeConfig(
backfillerCommitLimitValue: 10,
backfillerTargetLimitValue: 100,
supportedReposValue: {Config.flutterSlug},
dynamicConfig: DynamicConfig.fromJson({'backfillerCommitLimit': 10}),
);
ciYamlFetcher = FakeCiYamlFetcher();

Expand Down Expand Up @@ -100,7 +100,7 @@ void main() {
}) async {
final grid = await firestore.queryRecentCommitsAndTasks(
Config.flutterSlug,
commitLimit: commits ?? config.backfillerCommitLimit,
commitLimit: commits ?? config.flags.backfillerCommitLimit,
branch: branch,
);

Expand Down Expand Up @@ -270,7 +270,7 @@ void main() {
});

test('only considers the top X commits', () async {
config.backfillerCommitLimitValue = 1;
config.dynamicConfig = DynamicConfig.fromJson({'backfillerCommitLimit': 1});

// dart format off
await fillStorageAndSetCiYaml([
Expand Down
2 changes: 1 addition & 1 deletion app_dart/test/service/dynamic_config_updater_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void main() {
'${requestUris.last}',
'https://raw.githubusercontent.com/flutter/cocoon/main/app_dart/config.yaml',
);
expect(config.backfillerCommitLimit, 100);
expect(config.flags.backfillerCommitLimit, 100);
});
}

Expand Down
13 changes: 7 additions & 6 deletions app_dart/test/src/fake_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class FakeConfig implements Config {
this.supportedReposValue,
this.batchSizeValue,
this.backfillerTargetLimitValue,
this.backfillerCommitLimitValue,
this.issueAndPRLimitValue,
this.githubRequestDelayValue,
DynamicConfig? dynamicConfig,
});
}) : dynamicConfig =
dynamicConfig ?? DynamicConfig.fromJson(<String, Object?>{});

gh.GitHub? githubClient;
GraphQLClient? githubGraphQLClient;
Expand All @@ -75,7 +75,6 @@ class FakeConfig implements Config {
String? releaseCandidateBranchPathValue;
Set<String>? rollerAccountsValue;
int? backfillerTargetLimitValue;
int? backfillerCommitLimitValue;
int? issueAndPRLimitValue;
String? flutterGoldPendingValue;
String? flutterGoldSuccessValue;
Expand All @@ -89,6 +88,7 @@ class FakeConfig implements Config {
Set<gh.RepositorySlug>? supportedReposValue;
Set<gh.RepositorySlug>? postsubmitSupportedReposValue;
Duration? githubRequestDelayValue;
DynamicConfig dynamicConfig;

@override
Future<gh.GitHub> createGitHubClient({
Expand Down Expand Up @@ -120,9 +120,6 @@ class FakeConfig implements Config {
@override
int get backfillerTargetLimit => backfillerTargetLimitValue ?? 50;

@override
int get backfillerCommitLimit => backfillerCommitLimitValue ?? 50;

@override
int get issueAndPRLimit => issueAndPRLimitValue ?? 2;

Expand Down Expand Up @@ -268,4 +265,8 @@ class FakeConfig implements Config {
@override
Future<String> get discordTreeStatusWebhookUrl async =>
'https://discord.com/api/webhooks/1234/abcd';

@override
// TODO: implement flags
DynamicConfig get flags => dynamicConfig;
}
19 changes: 11 additions & 8 deletions app_dart/test/src/utilities/mocks.mocks.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.