@@ -202,13 +202,16 @@ class _GmailSmtpRelay implements EmailSender {
202202 // closing the old connection if there was any, ignoring errors
203203 await old? .close ();
204204
205- return _GmailConnection (
206- _parentZone,
207- PersistentConnection (
205+ // PersistentConnection needs to be created in its designated zone, as its
206+ // internal message subscription starts inside the constructor.
207+ final connectionZone = _ConnectionZone (_parentZone);
208+ final connection = await connectionZone._zone.run (
209+ () async => PersistentConnection (
208210 await _getSmtpServer (sender),
209211 timeout: Duration (seconds: 15 ),
210212 ),
211213 );
214+ return _GmailConnection (connectionZone, connection);
212215 });
213216 _connectionsBySender[sender] = newConnectionFuture;
214217 return newConnectionFuture;
@@ -281,28 +284,34 @@ class _GmailSmtpRelay implements EmailSender {
281284 }
282285}
283286
284- class _GmailConnection {
285- final DateTime created;
286- final PersistentConnection _connection;
287+ class _ConnectionZone {
287288 final Zone _parentZone;
288- DateTime _lastUsed;
289- var _sentCount = 0 ;
290289 Object ? _uncaughtError;
291290
292- _GmailConnection (this ._parentZone, this ._connection)
293- : created = clock.now (),
294- _lastUsed = clock.now ();
291+ _ConnectionZone (this ._parentZone);
295292
296293 late final _zone = _parentZone.fork (specification: ZoneSpecification (
297294 handleUncaughtError: (self, parent, zone, error, stackTrace) {
298295 _uncaughtError = error;
299296 _logger.severe ('Uncaught error while sending email' , error, stackTrace);
300297 },
301298 ));
299+ }
300+
301+ class _GmailConnection {
302+ final DateTime created;
303+ final PersistentConnection _connection;
304+ final _ConnectionZone _connectionZone;
305+ DateTime _lastUsed;
306+ var _sentCount = 0 ;
307+
308+ _GmailConnection (this ._connectionZone, this ._connection)
309+ : created = clock.now (),
310+ _lastUsed = clock.now ();
302311
303312 bool get isExpired {
304313 // The connection is in an unknown state, better not use it.
305- if (_uncaughtError != null ) {
314+ if (_connectionZone. _uncaughtError != null ) {
306315 return true ;
307316 }
308317 // There is a 100-recipient limit per SMTP transaction for smtp-relay.gmail.com.
@@ -325,8 +334,9 @@ class _GmailConnection {
325334 Future <SendReport > send (Message message) async {
326335 _sentCount += message.recipients.length + message.ccRecipients.length;
327336 try {
328- final r = await _zone.run (() async => await _connection.send (message));
329- if (_uncaughtError != null ) {
337+ final r = await _connectionZone._zone
338+ .run (() async => await _connection.send (message));
339+ if (_connectionZone._uncaughtError != null ) {
330340 throw EmailSenderException .failed ();
331341 }
332342 return r;
@@ -337,7 +347,7 @@ class _GmailConnection {
337347
338348 Future <void > close () async {
339349 try {
340- await _zone.run (() async {
350+ await _connectionZone. _zone.run (() async {
341351 await _connection.close ();
342352 });
343353 } catch (e, st) {
0 commit comments