Skip to content

Commit

Permalink
pool: reopen connection closed by idle timeout
Browse files Browse the repository at this point in the history
Signed-off-by: Harshit Gangal <harshit@planetscale.com>
  • Loading branch information
harshit-gangal committed Feb 18, 2025
1 parent 67d081a commit 9ff4dea
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
14 changes: 12 additions & 2 deletions go/pools/smartconnpool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,16 @@ func (pool *ConnPool[C]) connReopen(ctx context.Context, dbconn *Pooled[C], now
return err
}

dbconn.timeUsed.set(now)
if dbconn.Conn.Setting() != nil {
err = dbconn.Conn.ApplySetting(ctx, dbconn.Conn.Setting())
if err != nil {
dbconn.Close()
return err
}
}

dbconn.timeCreated.set(now)
dbconn.timeUsed.set(now)
return nil
}

Expand Down Expand Up @@ -764,7 +772,9 @@ func (pool *ConnPool[C]) closeIdleResources(now time.Time) {
if conn.timeUsed.expired(mono, timeout) {
pool.Metrics.idleClosed.Add(1)
conn.Close()
pool.closedConn()
if err := pool.connReopen(context.Background(), conn, monotonicNow()); err != nil {
pool.closedConn()
}
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions go/pools/smartconnpool/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ func TestIdleTimeout(t *testing.T) {

conns = append(conns, r)
}
assert.GreaterOrEqual(t, state.open.Load(), int64(5))

// wait a long while; ensure that none of the conns have been closed
time.Sleep(1 * time.Second)
Expand All @@ -628,9 +629,15 @@ func TestIdleTimeout(t *testing.T) {
t.Fatalf("Connections remain open after 1 second")
}
}
// At least 5 connections should have been closed by now.
assert.GreaterOrEqual(t, p.Metrics.IdleClosed(), int64(5), "At least 5 connections should have been closed by now.")

// no need to assert anything: all the connections in the pool should are idle-closed
// now and if they're not the test will timeout and fail
// At any point, at least 4 connections should be open, with 1 either in the process of opening or already opened.
// The idle connection closer shuts down one connection at a time.
assert.GreaterOrEqual(t, state.open.Load(), int64(4))

// The number of available connections in the pool should remain at 5.
assert.EqualValues(t, 5, p.Available())
}

t.Run("WithoutSettings", func(t *testing.T) { testTimeout(t, nil) })
Expand Down

0 comments on commit 9ff4dea

Please sign in to comment.