@@ -1560,7 +1560,7 @@ bucket_definitions:
1560
1560
} ) ;
1561
1561
// We have to trigger a new keepalive after the checkpoint, at least to cover postgres storage.
1562
1562
// This is what is effetively triggered with RouteAPI.createReplicationHead().
1563
- // MongoDB storage doesn't need this.
1563
+ // MongoDB storage doesn't explicitly need this anymore .
1564
1564
await bucketStorage . startBatch ( test_utils . BATCH_OPTIONS , async ( batch ) => {
1565
1565
await batch . keepalive ( '6/0' ) ;
1566
1566
} ) ;
@@ -1577,4 +1577,135 @@ bucket_definitions:
1577
1577
}
1578
1578
} ) ;
1579
1579
} ) ;
1580
+
1581
+ test ( 'custom write checkpoints - checkpoint after write' , async ( context ) => {
1582
+ await using factory = await generateStorageFactory ( ) ;
1583
+ const r = await factory . configureSyncRules ( {
1584
+ content : `
1585
+ bucket_definitions:
1586
+ mybucket:
1587
+ data: []
1588
+ ` ,
1589
+ validate : false
1590
+ } ) ;
1591
+ const bucketStorage = factory . getInstance ( r . persisted_sync_rules ! ) ;
1592
+ await bucketStorage . autoActivate ( ) ;
1593
+ bucketStorage . setWriteCheckpointMode ( storage . WriteCheckpointMode . CUSTOM ) ;
1594
+
1595
+ const abortController = new AbortController ( ) ;
1596
+ context . onTestFinished ( ( ) => abortController . abort ( ) ) ;
1597
+ const iter = bucketStorage
1598
+ . watchCheckpointChanges ( { user_id : 'user1' , signal : abortController . signal } )
1599
+ [ Symbol . asyncIterator ] ( ) ;
1600
+
1601
+ await bucketStorage . batchCreateCustomWriteCheckpoints ( [
1602
+ {
1603
+ checkpoint : 5n ,
1604
+ user_id : 'user1'
1605
+ }
1606
+ ] ) ;
1607
+
1608
+ await bucketStorage . startBatch ( test_utils . BATCH_OPTIONS , async ( batch ) => {
1609
+ await batch . keepalive ( '5/0' ) ;
1610
+ } ) ;
1611
+
1612
+ const result = await iter . next ( ) ;
1613
+ expect ( result ) . toMatchObject ( {
1614
+ done : false ,
1615
+ value : {
1616
+ base : {
1617
+ checkpoint : 0n ,
1618
+ lsn : '5/0'
1619
+ } ,
1620
+ writeCheckpoint : 5n
1621
+ }
1622
+ } ) ;
1623
+ } ) ;
1624
+
1625
+ test ( 'custom write checkpoints - write after checkpoint' , async ( context ) => {
1626
+ await using factory = await generateStorageFactory ( ) ;
1627
+ const r = await factory . configureSyncRules ( {
1628
+ content : `
1629
+ bucket_definitions:
1630
+ mybucket:
1631
+ data: []
1632
+ ` ,
1633
+ validate : false
1634
+ } ) ;
1635
+ const bucketStorage = factory . getInstance ( r . persisted_sync_rules ! ) ;
1636
+ await bucketStorage . autoActivate ( ) ;
1637
+ bucketStorage . setWriteCheckpointMode ( storage . WriteCheckpointMode . CUSTOM ) ;
1638
+
1639
+ const abortController = new AbortController ( ) ;
1640
+ context . onTestFinished ( ( ) => abortController . abort ( ) ) ;
1641
+ const iter = bucketStorage
1642
+ . watchCheckpointChanges ( { user_id : 'user1' , signal : abortController . signal } )
1643
+ [ Symbol . asyncIterator ] ( ) ;
1644
+
1645
+ await bucketStorage . startBatch ( test_utils . BATCH_OPTIONS , async ( batch ) => {
1646
+ await batch . keepalive ( '5/0' ) ;
1647
+ } ) ;
1648
+
1649
+ const result = await iter . next ( ) ;
1650
+ expect ( result ) . toMatchObject ( {
1651
+ done : false ,
1652
+ value : {
1653
+ base : {
1654
+ checkpoint : 0n ,
1655
+ lsn : '5/0'
1656
+ } ,
1657
+ writeCheckpoint : null
1658
+ }
1659
+ } ) ;
1660
+
1661
+ await bucketStorage . batchCreateCustomWriteCheckpoints ( [
1662
+ {
1663
+ checkpoint : 6n ,
1664
+ user_id : 'user1'
1665
+ }
1666
+ ] ) ;
1667
+ // We have to trigger a new keepalive after the checkpoint, at least to cover postgres storage.
1668
+ // This is what is effetively triggered with RouteAPI.createReplicationHead().
1669
+ // MongoDB storage doesn't explicitly need this anymore.
1670
+ await bucketStorage . startBatch ( test_utils . BATCH_OPTIONS , async ( batch ) => {
1671
+ await batch . keepalive ( '6/0' ) ;
1672
+ } ) ;
1673
+
1674
+ const result2 = await iter . next ( ) ;
1675
+ expect ( result2 ) . toMatchObject ( {
1676
+ done : false ,
1677
+ value : {
1678
+ base : {
1679
+ checkpoint : 0n ,
1680
+ lsn : '6/0'
1681
+ } ,
1682
+ writeCheckpoint : 6n
1683
+ }
1684
+ } ) ;
1685
+
1686
+ await bucketStorage . batchCreateCustomWriteCheckpoints ( [
1687
+ {
1688
+ checkpoint : 7n ,
1689
+ user_id : 'user1'
1690
+ }
1691
+ ] ) ;
1692
+ // We have to trigger a new keepalive after the checkpoint, at least to cover postgres storage.
1693
+ // This is what is effetively triggered with RouteAPI.createReplicationHead().
1694
+ // MongoDB storage doesn't explicitly need this anymore.
1695
+ await bucketStorage . startBatch ( test_utils . BATCH_OPTIONS , async ( batch ) => {
1696
+ await batch . keepalive ( '7/0' ) ;
1697
+ } ) ;
1698
+
1699
+ const result3 = await iter . next ( ) ;
1700
+ expect ( result3 ) . toMatchObject ( {
1701
+ done : false ,
1702
+ value : {
1703
+ base : {
1704
+ checkpoint : 0n ,
1705
+ lsn : '7/0'
1706
+ } ,
1707
+ writeCheckpoint : 7n
1708
+ }
1709
+ } ) ;
1710
+ } ) ;
1580
1711
}
0 commit comments