@@ -31,7 +31,10 @@ use super::flags::AtomicRelayServiceFlags;
31
31
use super :: options:: { RelayOptions , ReqExitPolicy , SubscribeAutoCloseOptions , SyncOptions } ;
32
32
use super :: ping:: PingTracker ;
33
33
use super :: stats:: RelayConnectionStats ;
34
- use super :: { Error , Reconciliation , RelayNotification , RelayStatus , SubscriptionAutoClosedReason } ;
34
+ use super :: {
35
+ Error , Reconciliation , RelayNotification , RelayStatus , SubscriptionActivity ,
36
+ SubscriptionAutoClosedReason ,
37
+ } ;
35
38
use crate :: policy:: AdmitStatus ;
36
39
use crate :: pool:: RelayPoolNotification ;
37
40
use crate :: relay:: status:: AtomicRelayStatus ;
@@ -44,6 +47,11 @@ enum IngesterCommand {
44
47
Authenticate { challenge : String } ,
45
48
}
46
49
50
+ struct HandleAutoClosing {
51
+ to_close : bool ,
52
+ reason : Option < SubscriptionAutoClosedReason > ,
53
+ }
54
+
47
55
#[ derive( Debug ) ]
48
56
struct RelayChannels {
49
57
nostr : (
@@ -384,7 +392,6 @@ impl InnerRelay {
384
392
RelayNotification :: RelayStatus { .. } => None ,
385
393
RelayNotification :: Authenticated => None ,
386
394
RelayNotification :: AuthenticationFailed => None ,
387
- RelayNotification :: SubscriptionAutoClosed { .. } => None ,
388
395
RelayNotification :: Shutdown => Some ( RelayPoolNotification :: Shutdown ) ,
389
396
} ;
390
397
@@ -1197,21 +1204,22 @@ impl InnerRelay {
1197
1204
filter : Filter ,
1198
1205
opts : SubscribeAutoCloseOptions ,
1199
1206
notifications : broadcast:: Receiver < RelayNotification > ,
1207
+ activity : Option < Sender < SubscriptionActivity > > ,
1200
1208
) {
1201
1209
let relay = self . clone ( ) ; // <-- FULL RELAY CLONE HERE
1202
1210
task:: spawn ( async move {
1203
1211
// Check if CLOSE needed
1204
1212
let to_close: bool = match relay
1205
- . handle_auto_closing ( & id, & filter, opts, notifications)
1213
+ . handle_auto_closing ( & id, & filter, opts, notifications, & activity )
1206
1214
. await
1207
1215
{
1208
- Some ( ( to_close, reason) ) => {
1209
- // Send subscription auto-closed notification
1216
+ Some ( HandleAutoClosing { to_close, reason } ) => {
1217
+ // Send activity
1210
1218
if let Some ( reason) = reason {
1211
- relay . send_notification (
1212
- RelayNotification :: SubscriptionAutoClosed { reason } ,
1213
- false ,
1214
- ) ;
1219
+ if let Some ( activity ) = & activity {
1220
+ // TODO: handle error?
1221
+ let _ = activity . send ( SubscriptionActivity :: Closed ( reason ) ) . await ;
1222
+ }
1215
1223
}
1216
1224
1217
1225
to_close
@@ -1223,6 +1231,9 @@ impl InnerRelay {
1223
1231
}
1224
1232
} ;
1225
1233
1234
+ // Drop activity sender to terminate the receiver activity loop
1235
+ drop ( activity) ;
1236
+
1226
1237
// Close subscription
1227
1238
if to_close {
1228
1239
tracing:: debug!( id = %id, "Auto-closing subscription." ) ;
@@ -1239,7 +1250,8 @@ impl InnerRelay {
1239
1250
filter : & Filter ,
1240
1251
opts : SubscribeAutoCloseOptions ,
1241
1252
mut notifications : broadcast:: Receiver < RelayNotification > ,
1242
- ) -> Option < ( bool , Option < SubscriptionAutoClosedReason > ) > {
1253
+ activity : & Option < Sender < SubscriptionActivity > > ,
1254
+ ) -> Option < HandleAutoClosing > {
1243
1255
time:: timeout ( opts. timeout , async move {
1244
1256
let mut counter: u16 = 0 ;
1245
1257
let mut received_eose: bool = false ;
@@ -1255,16 +1267,30 @@ impl InnerRelay {
1255
1267
if let ( Some ( idle_timeout) , Some ( last_event) ) = ( opts. idle_timeout , last_event) {
1256
1268
if last_event. elapsed ( ) > idle_timeout {
1257
1269
// Close the subscription
1258
- return Some ( ( true , None ) ) ; // TODO: use SubscriptionAutoClosedReason::Timeout?
1270
+ return Some ( HandleAutoClosing {
1271
+ to_close : true ,
1272
+ reason : None ,
1273
+ } ) ;
1259
1274
}
1260
1275
}
1261
1276
1262
1277
match notification {
1263
1278
RelayNotification :: Message { message, .. } => match message {
1264
1279
RelayMessage :: Event {
1265
- subscription_id, ..
1280
+ subscription_id,
1281
+ event,
1266
1282
} => {
1267
1283
if subscription_id. as_ref ( ) == id {
1284
+ // Send activity
1285
+ if let Some ( activity) = activity {
1286
+ // TODO: handle error?
1287
+ let _ = activity
1288
+ . send ( SubscriptionActivity :: ReceivedEvent (
1289
+ event. into_owned ( ) ,
1290
+ ) )
1291
+ . await ;
1292
+ }
1293
+
1268
1294
// If no-events timeout is enabled, update instant of last event received
1269
1295
if opts. idle_timeout . is_some ( ) {
1270
1296
last_event = Some ( Instant :: now ( ) ) ;
@@ -1302,21 +1328,21 @@ impl InnerRelay {
1302
1328
if self . state . is_auto_authentication_enabled ( ) {
1303
1329
require_resubscription = true ;
1304
1330
} else {
1305
- return Some ( (
1306
- false ,
1307
- Some ( SubscriptionAutoClosedReason :: Closed (
1331
+ return Some ( HandleAutoClosing {
1332
+ to_close : false , // No need to send CLOSE msg
1333
+ reason : Some ( SubscriptionAutoClosedReason :: Closed (
1308
1334
message. into_owned ( ) ,
1309
1335
) ) ,
1310
- ) ) ; // No need to send CLOSE msg
1336
+ } ) ;
1311
1337
}
1312
1338
}
1313
1339
_ => {
1314
- return Some ( (
1315
- false ,
1316
- Some ( SubscriptionAutoClosedReason :: Closed (
1340
+ return Some ( HandleAutoClosing {
1341
+ to_close : false , // No need to send CLOSE msg
1342
+ reason : Some ( SubscriptionAutoClosedReason :: Closed (
1317
1343
message. into_owned ( ) ,
1318
1344
) ) ,
1319
- ) ) ; // No need to send CLOSE msg
1345
+ } ) ;
1320
1346
}
1321
1347
}
1322
1348
}
@@ -1335,18 +1361,24 @@ impl InnerRelay {
1335
1361
}
1336
1362
}
1337
1363
RelayNotification :: AuthenticationFailed => {
1338
- return Some ( (
1339
- false ,
1340
- Some ( SubscriptionAutoClosedReason :: AuthenticationFailed ) ,
1341
- ) ) ; // No need to send CLOSE msg
1364
+ return Some ( HandleAutoClosing {
1365
+ to_close : false , // No need to send CLOSE msg
1366
+ reason : Some ( SubscriptionAutoClosedReason :: AuthenticationFailed ) ,
1367
+ } ) ;
1342
1368
}
1343
1369
RelayNotification :: RelayStatus { status } => {
1344
1370
if status. is_disconnected ( ) {
1345
- return Some ( ( false , None ) ) ; // No need to send CLOSE msg
1371
+ return Some ( HandleAutoClosing {
1372
+ to_close : false , // No need to send CLOSE msg
1373
+ reason : None ,
1374
+ } ) ;
1346
1375
}
1347
1376
}
1348
1377
RelayNotification :: Shutdown => {
1349
- return Some ( ( false , None ) ) ; // No need to send CLOSE msg
1378
+ return Some ( HandleAutoClosing {
1379
+ to_close : false , // No need to send CLOSE msg
1380
+ reason : None ,
1381
+ } ) ;
1350
1382
}
1351
1383
_ => ( ) ,
1352
1384
}
@@ -1356,6 +1388,25 @@ impl InnerRelay {
1356
1388
time:: timeout ( Some ( duration) , async {
1357
1389
while let Ok ( notification) = notifications. recv ( ) . await {
1358
1390
match notification {
1391
+ RelayNotification :: Message {
1392
+ message :
1393
+ RelayMessage :: Event {
1394
+ subscription_id,
1395
+ event,
1396
+ } ,
1397
+ } => {
1398
+ if subscription_id. as_ref ( ) == id {
1399
+ // Send activity
1400
+ if let Some ( activity) = activity {
1401
+ // TODO: handle error?
1402
+ let _ = activity
1403
+ . send ( SubscriptionActivity :: ReceivedEvent (
1404
+ event. into_owned ( ) ,
1405
+ ) )
1406
+ . await ;
1407
+ }
1408
+ }
1409
+ }
1359
1410
RelayNotification :: RelayStatus { status } => {
1360
1411
if status. is_disconnected ( ) {
1361
1412
return Ok ( ( ) ) ;
@@ -1373,7 +1424,10 @@ impl InnerRelay {
1373
1424
. await ;
1374
1425
}
1375
1426
1376
- Some ( ( true , Some ( SubscriptionAutoClosedReason :: Completed ) ) ) // Need to send CLOSE msg
1427
+ Some ( HandleAutoClosing {
1428
+ to_close : true , // Need to send CLOSE msg
1429
+ reason : Some ( SubscriptionAutoClosedReason :: Completed ) ,
1430
+ } )
1377
1431
} )
1378
1432
. await ?
1379
1433
}
0 commit comments