Skip to content

Commit 3026a95

Browse files
authored
Email sender: move PersistentConnection message subscription into the designated zone. (#8072)
1 parent b343a91 commit 3026a95

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

app/lib/frontend/email_sender.dart

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)