Skip to content

Commit 2f1dc4e

Browse files
authored
Integrity check: increased concurrency, time limit per entity processing. (#8847)
1 parent cd5a852 commit 2f1dc4e

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Important changes to data models, configuration, and migrations between each
22
AppEngine version, listed here to ease deployment and troubleshooting.
33

44
## Next Release (replace with git tag when deployed)
5+
* Bump runtimeVersion to `2025.07.04`.
6+
* Note: integrity check is running with internal concurrency of 4 and 15 minutes time limit / entity.
57

68
## `20250703t113600-all`
79
* Bump runtimeVersion to `2025.07.01`.

app/lib/shared/integrity.dart

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import '../publisher/models.dart';
2626
import '../service/email/email_templates.dart'
2727
show isValidEmail, looksLikeEmail;
2828
import '../shared/env_config.dart';
29+
import '../shared/monitoring.dart';
2930
import 'configuration.dart';
3031
import 'datastore.dart';
3132
import 'storage.dart';
@@ -947,15 +948,31 @@ class IntegrityChecker {
947948
}
948949

949950
Stream<String> _queryWithPool<R extends Model>(
950-
Stream<String> Function(R model) fn) async* {
951+
Stream<String> Function(R model) fn, {
952+
/// Note: This time limit aborts the integrity check after a reasonable
953+
/// amount of time has passed with an entity-related operation.
954+
///
955+
/// The integrity check process should be restarted soon after, and
956+
/// hopefully it should complete on the next round.
957+
Duration timeLimit = const Duration(minutes: 15),
958+
}) async* {
951959
final query = _db.query<R>();
952960
final pool = Pool(_concurrency);
953961
final futures = <Future<List<String>>>[];
954962
try {
955963
await for (final m in query.run()) {
956964
_updateUnmappedFields(m);
957-
final f = pool.withResource(() => fn(m).toList());
958-
futures.add(f);
965+
final taskFuture = pool.withResource(() async {
966+
final f = fn(m).toList();
967+
try {
968+
return await f.timeout(timeLimit);
969+
} on TimeoutException catch (e, st) {
970+
_logger.pubNoticeShout('integrity-check-timeout',
971+
'Integrity check operation timed out.', e, st);
972+
rethrow;
973+
}
974+
});
975+
futures.add(taskFuture);
959976
}
960977
for (final f in futures) {
961978
for (final item in await f) {

app/lib/shared/versions.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ final RegExp runtimeVersionPattern = RegExp(r'^\d{4}\.\d{2}\.\d{2}$');
2424
/// when the version switch happens.
2525
const _acceptedRuntimeVersions = <String>[
2626
// The current [runtimeVersion].
27-
'2025.07.01',
27+
'2025.07.04',
2828
// Fallback runtime versions.
29+
'2025.07.01',
2930
'2025.06.20',
30-
'2025.06.03',
3131
];
3232

3333
/// Sets the current runtime versions.

app/lib/tool/neat_task/pub_dev_tasks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ List<NeatPeriodicTaskScheduler> createPeriodicTaskSchedulers({
244244
_weekly(
245245
name: 'check-datastore-integrity',
246246
isRuntimeVersioned: true,
247-
task: () async => await IntegrityChecker(dbService, concurrency: 2)
247+
task: () async => await IntegrityChecker(dbService, concurrency: 4)
248248
.verifyAndLogIssues(),
249249
timeout: Duration(days: 1),
250250
),

0 commit comments

Comments
 (0)