mirror of
https://github.com/sosedoff/pgweb.git
synced 2024-12-15 03:36:33 +03:00
Add idle timeout into session manager
This commit is contained in:
parent
0a133dc395
commit
16726e2461
@ -10,9 +10,10 @@ import (
|
||||
)
|
||||
|
||||
type SessionManager struct {
|
||||
logger *logrus.Logger
|
||||
sessions map[string]*client.Client
|
||||
mu sync.Mutex
|
||||
logger *logrus.Logger
|
||||
sessions map[string]*client.Client
|
||||
mu sync.Mutex
|
||||
idleTimeout time.Duration
|
||||
}
|
||||
|
||||
func NewSessionManager(logger *logrus.Logger) *SessionManager {
|
||||
@ -23,6 +24,10 @@ func NewSessionManager(logger *logrus.Logger) *SessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SessionManager) SetIdleTimeout(timeout time.Duration) {
|
||||
m.idleTimeout = timeout
|
||||
}
|
||||
|
||||
func (m *SessionManager) IDs() []string {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@ -79,6 +84,10 @@ func (m *SessionManager) Len() int {
|
||||
}
|
||||
|
||||
func (m *SessionManager) Cleanup() int {
|
||||
if m.idleTimeout == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
removed := 0
|
||||
|
||||
m.logger.Debug("starting idle sessions cleanup")
|
||||
@ -97,6 +106,8 @@ func (m *SessionManager) Cleanup() int {
|
||||
}
|
||||
|
||||
func (m *SessionManager) RunPeriodicCleanup() {
|
||||
m.logger.WithField("timeout", m.idleTimeout).Info("session manager cleanup enabled")
|
||||
|
||||
for range time.Tick(time.Minute) {
|
||||
m.Cleanup()
|
||||
}
|
||||
@ -106,9 +117,11 @@ func (m *SessionManager) staleSessions() []string {
|
||||
m.mu.TryLock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
ids := []string{}
|
||||
|
||||
for id, conn := range m.sessions {
|
||||
if conn.IsIdle() {
|
||||
if now.Sub(conn.LastQueryTime()) > m.idleTimeout {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package api
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/sosedoff/pgweb/pkg/client"
|
||||
"github.com/sosedoff/pgweb/pkg/command"
|
||||
)
|
||||
|
||||
func TestSessionManager(t *testing.T) {
|
||||
@ -60,20 +60,16 @@ func TestSessionManager(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("clean up stale sessions", func(t *testing.T) {
|
||||
defer func() {
|
||||
command.Opts.ConnectionIdleTimeout = 0
|
||||
}()
|
||||
|
||||
manager := NewSessionManager(logrus.New())
|
||||
conn := &client.Client{}
|
||||
manager.Add("foo", conn)
|
||||
|
||||
command.Opts.ConnectionIdleTimeout = 0
|
||||
assert.Equal(t, 1, manager.Len())
|
||||
assert.Equal(t, 0, manager.Cleanup())
|
||||
assert.Equal(t, 1, manager.Len())
|
||||
|
||||
command.Opts.ConnectionIdleTimeout = 1
|
||||
conn.Query("select 1")
|
||||
manager.SetIdleTimeout(time.Minute)
|
||||
assert.Equal(t, 1, manager.Cleanup())
|
||||
assert.Equal(t, 0, manager.Len())
|
||||
assert.True(t, conn.IsClosed())
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jessevdk/go-flags"
|
||||
@ -266,6 +267,7 @@ func Run() {
|
||||
api.DbSessions = api.NewSessionManager(logger)
|
||||
|
||||
if !command.Opts.DisableConnectionIdleTimeout {
|
||||
api.DbSessions.SetIdleTimeout(time.Minute * time.Duration(command.Opts.ConnectionIdleTimeout))
|
||||
go api.DbSessions.RunPeriodicCleanup()
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +335,10 @@ func (client *Client) ServerVersion() string {
|
||||
}
|
||||
|
||||
func (client *Client) query(query string, args ...interface{}) (*Result, error) {
|
||||
if client.db == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Update the last usage time
|
||||
defer func() {
|
||||
client.lastQueryTime = time.Now().UTC()
|
||||
@ -366,7 +370,7 @@ func (client *Client) query(query string, args ...interface{}) (*Result, error)
|
||||
result := Result{
|
||||
Columns: []string{"Rows Affected"},
|
||||
Rows: []Row{
|
||||
Row{affected},
|
||||
{affected},
|
||||
},
|
||||
}
|
||||
|
||||
@ -446,6 +450,10 @@ func (c *Client) IsClosed() bool {
|
||||
return c.closed
|
||||
}
|
||||
|
||||
func (c *Client) LastQueryTime() time.Time {
|
||||
return c.lastQueryTime
|
||||
}
|
||||
|
||||
func (client *Client) IsIdle() bool {
|
||||
mins := int(time.Since(client.lastQueryTime).Minutes())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user