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 2023-11-27 12:17:55 +02:00
parent 776f2a026c
commit 1daec3e890
No known key found for this signature in database
GPG Key ID: D7D916376026F177
2 changed files with 30 additions and 19 deletions

View File

@ -66,10 +66,14 @@ func (c *client) genSessionFilter(
}
// 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 {
return func(session *wtdb.ClientSession, _ uint16) bool {
return session.SeqNum < session.Policy.MaxUpdates
return func(session *wtdb.ClientSession, numUnAcked uint16) bool {
return session.SeqNum < session.Policy.MaxUpdates ||
numUnAcked > 0
}
}

View File

@ -2418,13 +2418,13 @@ var clientTests = []clientTest{
},
},
{
// Demonstrate that a client is un-able to remove a tower if
// there are persisted un-acked updates in a session that is
// not loaded as a candidate session on start-up.
//
// NOTE: This is a bug and will be fixed in a followup commit.
name: "can't remove tower with un-acked update in " +
"non-candidate session",
// Previously we would not load a session into memory if its
// seq num was equal to it's max-updates. This meant that we
// would then not properly handle any committed updates for the
// session meaning that we would then not remove the tower if
// needed. This test demonstrates that this has been fixed.
name: "can remove tower with an un-acked update in " +
"an exhausted session after a restart",
cfg: harnessCfg{
localBalance: localBalance,
remoteBalance: remoteBalance,
@ -2462,8 +2462,7 @@ var clientTests = []clientTest{
// update which will cause a CommittedUpdate to be
// persisted which will also mean that the SeqNum of the
// session is now equal to MaxUpdates of the session
// policy. This means that on start-up of the client,
// the session will not be loaded as a candidate.
// policy.
h.backupStates(chanID, numUpdates-1, numUpdates, nil)
tower, err := h.clientDB.LoadTower(
@ -2493,19 +2492,27 @@ var clientTests = []clientTest{
require.NoError(h.t, err)
// Now restart the client. On restart, the previous
// session will no longer be loaded as a candidate since
// it is now seen as exhausted.
// session should still be loaded even though it is
// exhausted since it has an un-acked update.
require.NoError(h.t, h.clientMgr.Stop())
h.startClient()
// Attempt to remove the tower. This will fail due to
// 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.
// Now remove the tower.
err = h.clientMgr.RemoveTower(
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)
},
},
{