Skip to content

Commit 57bf459

Browse files
committed
Strict index builder timeout + exceptions are not catched.
1 parent 59937c1 commit 57bf459

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

app/lib/search/backend.dart

+22-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'package:meta/meta.dart';
1919
// ignore: implementation_imports
2020
import 'package:pana/src/dartdoc/pub_dartdoc_data.dart';
2121
import 'package:pool/pool.dart';
22+
import 'package:pub_dev/shared/monitoring.dart';
2223
import 'package:retry/retry.dart';
2324

2425
import '../../publisher/backend.dart';
@@ -55,6 +56,10 @@ final Logger _logger = Logger('pub.search.backend');
5556
/// building or updating the snapshot.
5657
const _defaultSnapshotBuildConcurrency = 8;
5758

59+
/// The (approximate) amount of time while the process holds the lock
60+
/// and works on index building and updates.
61+
const _maxLockHoldPeriod = Duration(days: 1);
62+
5863
/// Sets the backend service.
5964
void registerSearchBackend(SearchBackend backend) =>
6065
ss.register(#_searchBackend, backend);
@@ -101,15 +106,28 @@ class SearchBackend {
101106
'$runtimeVersion/search/update-snapshot',
102107
expiration: Duration(minutes: 20),
103108
);
109+
final started = clock.now();
104110
while (true) {
105111
try {
106112
await lock.withClaim((claim) async {
107-
await doCreateAndUpdateSnapshot(claim);
113+
// Force timeout exception if the process does not release the lock.
114+
final lockHoldTimeout = _maxLockHoldPeriod + Duration(hours: 1);
115+
await doCreateAndUpdateSnapshot(claim).timeout(lockHoldTimeout);
108116
});
109117
} catch (e, st) {
110-
_logger.warning('Snapshot update failed.', e, st);
118+
_logger.pubNoticeShout(
119+
'snapshot-building', 'Snapshot update failed.', e, st);
120+
// Force waiting at least an hour before we rethrow the exception
121+
final elapsed = clock.now().difference(started);
122+
if (elapsed < Duration(hours: 1)) {
123+
_logger.warning('Waiting before rethrowing exception.', e, st);
124+
await Future.delayed(Duration(hours: 1) - elapsed);
125+
}
126+
// Throwing here will crash the VM and force the instance to restart.
127+
rethrow;
111128
}
112-
// Wait for 1 minutes for sanity, before trying again.
129+
130+
// Allow another instance to get the lock and build the index.
113131
await Future.delayed(Duration(minutes: 1));
114132
}
115133
}
@@ -124,7 +142,7 @@ class SearchBackend {
124142

125143
// The claim will be released after a day, another process may
126144
// start to build the snapshot from scratch again.
127-
final workUntil = clock.now().add(Duration(days: 1));
145+
final workUntil = clock.now().add(_maxLockHoldPeriod);
128146

129147
// creating snapshot from scratch
130148
final snapshot = SearchSnapshot();

0 commit comments

Comments
 (0)