@@ -121,70 +121,54 @@ class TaskBackend {
121121 final aborted = _aborted = Completer ();
122122 final stopped = _stopped = Completer ();
123123
124- // Start scanning for packages to be tracked
125- final _doneScanning = Completer <void >();
124+ final scanLoop = _createLoop (
125+ name: 'scan-packages' ,
126+ aborted: aborted,
127+ fn: (claim, aborted) async {
128+ await _scanForPackageUpdates (claim, abort: aborted);
129+ },
130+ );
131+ final scheduleLoop = _createLoop (
132+ name: 'schedule' ,
133+ aborted: aborted,
134+ fn: (claim, aborted) async {
135+ await schedule (claim, taskWorkerCloudCompute, _db, abort: aborted);
136+ },
137+ );
138+
126139 scheduleMicrotask (() async {
127- try {
128- // Create a lock for task scheduling, so tasks
129- final lock = GlobalLock .create (
130- '$runtimeVersion /task/scanning' ,
131- expiration: Duration (minutes: 25 ),
132- );
140+ // Wait for background process to finish
141+ await Future .wait ([scanLoop, scheduleLoop]);
133142
134- while (! aborted.isCompleted) {
135- // Acquire the global lock and scan for package changes while lock is
136- // valid.
137- try {
138- await lock.withClaim ((claim) async {
139- await _scanForPackageUpdates (claim, abort: aborted);
140- }, abort: aborted);
141- } catch (e, st) {
142- // Log this as very bad, and then move on. Nothing good can come
143- // from straight up stopping.
144- _log.shout (
145- 'scanning failed (will retry when lock becomes free)' ,
146- e,
147- st,
148- );
149- // Sleep 5 minutes to reduce risk of degenerate behavior
150- await clock.delayed (Duration (minutes: 5 ));
151- }
152- }
153- } catch (e, st) {
154- _log.severe ('scanning loop crashed' , e, st);
155- } finally {
156- _log.info ('scanning loop stopped' );
157- _doneScanning.complete ();
158- }
143+ // Report background processes as stopped
144+ stopped.complete ();
159145 });
146+ }
160147
161- // Start background task to schedule tasks
162- final _doneScheduling = Completer <void >();
163- scheduleMicrotask (() async {
148+ Future <void > _createLoop ({
149+ required String name,
150+ required Completer aborted,
151+ required Future <void > Function (GlobalLockClaim claim, Completer aborted) fn,
152+ }) {
153+ return Future .microtask (() async {
164154 try {
165- // Create a lock for task scheduling, so tasks
155+ // A lock for this task loop makes sure we only have one
156+ // process at the time that tries to update the state.
166157 final lock = GlobalLock .create (
167- '$runtimeVersion /task/scheduler ' ,
158+ '$runtimeVersion /task/$ name -loop ' ,
168159 expiration: Duration (minutes: 25 ),
169160 );
170161
171162 while (! aborted.isCompleted) {
172- // Acquire the global lock and create VMs for pending packages, and
173- // kill overdue VMs.
174163 try {
175164 await lock.withClaim ((claim) async {
176- await schedule (
177- claim,
178- taskWorkerCloudCompute,
179- _db,
180- abort: aborted,
181- );
165+ await fn (claim, aborted);
182166 }, abort: aborted);
183167 } catch (e, st) {
184168 // Log this as very bad, and then move on. Nothing good can come
185169 // from straight up stopping.
186170 _log.shout (
187- 'scheduling iteration failed (will retry when lock becomes free)' ,
171+ 'task loop $ name failed (will retry when lock becomes free)' ,
188172 e,
189173 st,
190174 );
@@ -193,20 +177,11 @@ class TaskBackend {
193177 }
194178 }
195179 } catch (e, st) {
196- _log.severe ('scheduling loop crashed' , e, st);
180+ _log.severe ('task loop $ name crashed' , e, st);
197181 } finally {
198- _log.info ('scheduling loop stopped' );
199- _doneScheduling.complete ();
182+ _log.info ('task loop $name stopped' );
200183 }
201184 });
202-
203- scheduleMicrotask (() async {
204- // Wait for background process to finish
205- await Future .wait ([_doneScanning.future, _doneScheduling.future]);
206-
207- // Report background processes as stopped
208- stopped.complete ();
209- });
210185 }
211186
212187 /// Stop any background process that may be running.
0 commit comments