@@ -541,7 +541,7 @@ impl Router {
541
541
542
542
for packet in packets. drain ( 0 ..) {
543
543
match packet {
544
- Packet :: Publish ( mut publish, properties) => {
544
+ Packet :: Publish ( publish, properties) => {
545
545
let span = tracing:: error_span!( "publish" , topic = ?publish. topic, pkid = publish. pkid) ;
546
546
let _guard = span. enter ( ) ;
547
547
@@ -591,11 +591,6 @@ impl Router {
591
591
592
592
self . router_meters . total_publishes += 1 ;
593
593
594
- // Ignore retained messages
595
- if publish. retain {
596
- publish. retain = false ;
597
- }
598
-
599
594
// Try to append publish to commitlog
600
595
match append_to_commitlog (
601
596
id,
@@ -678,8 +673,6 @@ impl Router {
678
673
// and create DataRequest, while using the same datalog of "topic"
679
674
// NOTE: topic & $share/group/topic will have same filteridx!
680
675
self . prepare_filter ( id, cursor, idx, f, group, subscription_id) ;
681
- self . datalog
682
- . handle_retained_messages ( & filter, & mut self . notifications ) ;
683
676
684
677
let code = match f. qos {
685
678
QoS :: AtMostOnce => SubscribeReasonCode :: QoS0 ,
@@ -898,6 +891,7 @@ impl Router {
898
891
}
899
892
900
893
/// Apply filter and prepare this connection to receive subscription data
894
+ /// Handle retained messages as per subscription options!
901
895
fn prepare_filter (
902
896
& mut self ,
903
897
id : ConnectionId ,
@@ -946,6 +940,13 @@ impl Router {
946
940
. insert ( filter_path. clone ( ) , subscription_id) ;
947
941
}
948
942
943
+ // check is group is None because retained messages aren't sent
944
+ // for shared subscriptions
945
+ // TODO: use retain forward rules
946
+ let forward_retained = group. is_none ( ) ;
947
+
948
+ // call to `insert(_)` returns `true` if it didn't contain the filter_path already
949
+ // i.e. its a new subscription
949
950
if connection. subscriptions . insert ( filter_path. clone ( ) ) {
950
951
let request = DataRequest {
951
952
filter : filter_path. clone ( ) ,
@@ -954,6 +955,8 @@ impl Router {
954
955
cursor,
955
956
read_count : 0 ,
956
957
max_count : 100 ,
958
+ // set true for new subscriptions
959
+ forward_retained,
957
960
group,
958
961
} ;
959
962
@@ -962,6 +965,10 @@ impl Router {
962
965
debug_assert ! ( self . scheduler. check_tracker_duplicates( id) . is_none( ) )
963
966
}
964
967
968
+ // TODO: figure out how we can update existing DataRequest
969
+ // helpful in re-subscriptions and forwarding retained messages on
970
+ // every subscribe
971
+
965
972
let meter = & mut self . ibufs . get_mut ( id) . unwrap ( ) . meter ;
966
973
meter. register_subscription ( filter_path. clone ( ) ) ;
967
974
}
@@ -1193,10 +1200,11 @@ fn append_to_commitlog(
1193
1200
if publish. payload . is_empty ( ) {
1194
1201
datalog. remove_from_retained_publishes ( topic. to_owned ( ) ) ;
1195
1202
} else if publish. retain {
1196
- error ! ( "Unexpected: retain field was not unset" ) ;
1197
1203
datalog. insert_to_retained_publishes ( publish. clone ( ) , properties. clone ( ) , topic. to_owned ( ) ) ;
1198
1204
}
1199
1205
1206
+ // after recording retained message, we also send that message to existing subscribers
1207
+ // as normal publish message. Therefore we are setting retain to false
1200
1208
publish. retain = false ;
1201
1209
let pkid = publish. pkid ;
1202
1210
@@ -1358,7 +1366,23 @@ fn forward_device_data(
1358
1366
inflight_slots = 1 ;
1359
1367
}
1360
1368
1361
- let ( next, publishes) =
1369
+ let mut publishes = Vec :: new ( ) ;
1370
+
1371
+ if request. forward_retained {
1372
+ // NOTE: ideally we want to limit the number of read messages
1373
+ // and skip the messages previously read while reading next time.
1374
+ // but for now, we just try to read all messages and drop the excess ones
1375
+ let mut retained_publishes = datalog. read_retained_messages ( & request. filter ) ;
1376
+ retained_publishes. truncate ( inflight_slots as usize ) ;
1377
+
1378
+ publishes. extend ( retained_publishes. into_iter ( ) . map ( |p| ( p, None ) ) ) ;
1379
+ inflight_slots -= publishes. len ( ) as u64 ;
1380
+
1381
+ // we only want to forward retained messages once
1382
+ request. forward_retained = false ;
1383
+ }
1384
+
1385
+ let ( next, publishes_from_datalog) =
1362
1386
match datalog. native_readv ( request. filter_idx , request. cursor , inflight_slots) {
1363
1387
Ok ( v) => v,
1364
1388
Err ( e) => {
@@ -1367,6 +1391,12 @@ fn forward_device_data(
1367
1391
}
1368
1392
} ;
1369
1393
1394
+ publishes. extend (
1395
+ publishes_from_datalog
1396
+ . into_iter ( )
1397
+ . map ( |( p, offset) | ( p, Some ( offset) ) ) ,
1398
+ ) ;
1399
+
1370
1400
let ( start, next, caughtup) = match next {
1371
1401
Position :: Next { start, end } => ( start, end, false ) ,
1372
1402
Position :: Done { start, end } => ( start, end, true ) ,
0 commit comments