wtclient: use the new filter options to fix the demo'd bug

In this commit, we use the newly added session listing options to ensure
that we only see a session as exhausted if it does not have any un-acked
updates on disk. This fixes the bug previously demonstrated.
This commit is contained in:
Elle Mouton committed 2024-01-12 08:25:28 +02:00
1 parent 776f2a026c
commit 1daec3e890
2 files changed
+30 -19

No files matched your search

+7 -3
View File
@@ -66,10 +66,14 @@ func (c *client) genSessionFilter(
} }
// ExhaustedSessionFilter constructs a wtdb.ClientSessionFilterFn filter // ExhaustedSessionFilter constructs a wtdb.ClientSessionFilterFn filter
// function that will filter out any sessions that have been exhausted. // function that will filter out any sessions that have been exhausted. A
// session is considered exhausted only if it has no un-acked updates and the
// sequence number of the session is equal to the max updates of the session
// policy.
func ExhaustedSessionFilter() wtdb.ClientSessWithNumCommittedUpdatesFilterFn { func ExhaustedSessionFilter() wtdb.ClientSessWithNumCommittedUpdatesFilterFn {
return func(session *wtdb.ClientSession, _ uint16) bool { return func(session *wtdb.ClientSession, numUnAcked uint16) bool {
return session.SeqNum < session.Policy.MaxUpdates return session.SeqNum < session.Policy.MaxUpdates ||
numUnAcked > 0
} }
} }
+23 -16
View File
@@ -2418,13 +2418,13 @@ var clientTests = []clientTest{
}, },
}, },
{ {
// Demonstrate that a client is un-able to remove a tower if // Previously we would not load a session into memory if its
// there are persisted un-acked updates in a session that is // seq num was equal to it's max-updates. This meant that we
// not loaded as a candidate session on start-up. // would then not properly handle any committed updates for the
// // session meaning that we would then not remove the tower if
// NOTE: This is a bug and will be fixed in a followup commit. // needed. This test demonstrates that this has been fixed.
name: "can't remove tower with un-acked update in " + name: "can remove tower with an un-acked update in " +
"non-candidate session", "an exhausted session after a restart",
cfg: harnessCfg{ cfg: harnessCfg{
localBalance: localBalance, localBalance: localBalance,
remoteBalance: remoteBalance, remoteBalance: remoteBalance,
@@ -2462,8 +2462,7 @@ var clientTests = []clientTest{
// update which will cause a CommittedUpdate to be // update which will cause a CommittedUpdate to be
// persisted which will also mean that the SeqNum of the // persisted which will also mean that the SeqNum of the
// session is now equal to MaxUpdates of the session // session is now equal to MaxUpdates of the session
// policy. This means that on start-up of the client, // policy.
// the session will not be loaded as a candidate.
h.backupStates(chanID, numUpdates-1, numUpdates, nil) h.backupStates(chanID, numUpdates-1, numUpdates, nil)
tower, err := h.clientDB.LoadTower( tower, err := h.clientDB.LoadTower(
@@ -2493,19 +2492,27 @@ var clientTests = []clientTest{
require.NoError(h.t, err) require.NoError(h.t, err)
// Now restart the client. On restart, the previous // Now restart the client. On restart, the previous
// session will no longer be loaded as a candidate since // session should still be loaded even though it is
// it is now seen as exhausted. // exhausted since it has an un-acked update.
require.NoError(h.t, h.clientMgr.Stop()) require.NoError(h.t, h.clientMgr.Stop())
h.startClient() h.startClient()
// Attempt to remove the tower. This will fail due to // Now remove the tower.
// there still being un-acked updates for the tower
// since these are only (currently) properly handled for
// sessions loaded as candidate sessions on start-up.
err = h.clientMgr.RemoveTower( err = h.clientMgr.RemoveTower(
h.server.addr.IdentityKey, nil, h.server.addr.IdentityKey, nil,
) )
require.ErrorIs(h.t, err, wtdb.ErrTowerUnackedUpdates) require.NoError(h.t, err)
// Add a new tower.
server2 := newServerHarness(
h.t, h.net, towerAddr2Str, nil,
)
server2.start()
h.addTower(server2.addr)
// Now we assert that the backups are backed up to the
// new tower.
server2.waitForUpdates(hints[numUpdates-1:], waitTime)
}, },
}, },
{ {