Terminate idle sessions with cancel option enabled

This commit is contained in:
Julien Riou 2018-07-01 15:01:51 +02:00
parent aa8cf4bb36
commit 054ac3928e
No known key found for this signature in database
GPG key ID: BA3E15176E45E85D
2 changed files with 17 additions and 12 deletions

View file

@ -8,7 +8,7 @@ With `pgterminate`, you shouldn't be paged at night because some queries has loc
# Highlights
* `pgterminate` name is derived from `pg_terminate_backend` function, it terminates backends.
* backends are called sessions in `pgterminate`.
* use `cancel` option to terminate query instead of session.
* `cancel` option terminate current query of active sessions instead of ending the whole backend. Idle sessions are terminated even with this option enabled because `pg_cancel_backend` function has no effect on them.
* `active` sessions are backends in `active` state for more than `active-timeout` seconds.
* `idle` sessions are backends in `idle`, `idle in transaction` or `idle in transaction (abort)` state for more than `idle-timeout` seconds.
* at least one of `active-timeout` and `idle-timeout` parameter is required, both can be used.

View file

@ -38,28 +38,33 @@ func (t *Terminator) Run() {
return
default:
sessions := t.db.Sessions()
// Cancel or terminate active sessions
if t.config.ActiveTimeout != 0 {
actives := activeSessions(sessions, t.config.ActiveTimeout)
t.terminateAndNotify(t.filter(actives))
actives := t.filter(activeSessions(sessions, t.config.ActiveTimeout))
if t.config.Cancel {
t.db.CancelSessions(actives)
} else {
t.db.TerminateSessions(actives)
}
t.notify(actives)
}
// Terminate idle sessions
if t.config.IdleTimeout != 0 {
idles := idleSessions(sessions, t.config.IdleTimeout)
t.terminateAndNotify(t.filter(idles))
idles := t.filter(idleSessions(sessions, t.config.IdleTimeout))
t.db.TerminateSessions(idles)
t.notify(idles)
}
time.Sleep(time.Duration(t.config.Interval*1000) * time.Millisecond)
}
}
}
// terminateAndNotify terminates a list of sessions and notifies channel
func (t *Terminator) terminateAndNotify(sessions []base.Session) {
if t.config.Cancel {
t.db.CancelSessions(sessions)
} else {
t.db.TerminateSessions(sessions)
}
// notify sends sessions to channel
func (t *Terminator) notify(sessions []base.Session) {
for _, session := range sessions {
t.sessions <- session
}