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 # Highlights
* `pgterminate` name is derived from `pg_terminate_backend` function, it terminates backends. * `pgterminate` name is derived from `pg_terminate_backend` function, it terminates backends.
* backends are called sessions in `pgterminate`. * 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. * `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. * `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. * 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 return
default: default:
sessions := t.db.Sessions() sessions := t.db.Sessions()
// Cancel or terminate active sessions
if t.config.ActiveTimeout != 0 { if t.config.ActiveTimeout != 0 {
actives := activeSessions(sessions, t.config.ActiveTimeout) actives := t.filter(activeSessions(sessions, t.config.ActiveTimeout))
t.terminateAndNotify(t.filter(actives)) if t.config.Cancel {
t.db.CancelSessions(actives)
} else {
t.db.TerminateSessions(actives)
}
t.notify(actives)
} }
// Terminate idle sessions
if t.config.IdleTimeout != 0 { if t.config.IdleTimeout != 0 {
idles := idleSessions(sessions, t.config.IdleTimeout) idles := t.filter(idleSessions(sessions, t.config.IdleTimeout))
t.terminateAndNotify(t.filter(idles)) t.db.TerminateSessions(idles)
t.notify(idles)
} }
time.Sleep(time.Duration(t.config.Interval*1000) * time.Millisecond) time.Sleep(time.Duration(t.config.Interval*1000) * time.Millisecond)
} }
} }
} }
// terminateAndNotify terminates a list of sessions and notifies channel // notify sends sessions to channel
func (t *Terminator) terminateAndNotify(sessions []base.Session) { func (t *Terminator) notify(sessions []base.Session) {
if t.config.Cancel {
t.db.CancelSessions(sessions)
} else {
t.db.TerminateSessions(sessions)
}
for _, session := range sessions { for _, session := range sessions {
t.sessions <- session t.sessions <- session
} }