Merge pull request #284 from writeas/high-load-error-page
Show 503 page on blogs under high load
This commit is contained in:
commit
dbd7eff7ea
|
@ -22,3 +22,7 @@ func (db *datastore) isDuplicateKeyErr(err error) bool {
|
|||
func (db *datastore) isIgnorableError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *datastore) isHighLoadError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -40,3 +40,13 @@ func (db *datastore) isIgnorableError(err error) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *datastore) isHighLoadError(err error) bool {
|
||||
if db.driverName == driverMySQL {
|
||||
if mysqlErr, ok := err.(*mysql.MySQLError); ok {
|
||||
return mysqlErr.Number == mySQLErrMaxUserConns || mysqlErr.Number == mySQLErrTooManyConns
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// +build sqlite,!wflib
|
||||
|
||||
/*
|
||||
* Copyright © 2019 A Bunch Tell LLC.
|
||||
* Copyright © 2019-2020 A Bunch Tell LLC.
|
||||
*
|
||||
* This file is part of WriteFreely.
|
||||
*
|
||||
|
@ -60,3 +60,13 @@ func (db *datastore) isIgnorableError(err error) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *datastore) isHighLoadError(err error) bool {
|
||||
if db.driverName == driverMySQL {
|
||||
if mysqlErr, ok := err.(*mysql.MySQLError); ok {
|
||||
return mysqlErr.Number == mySQLErrMaxUserConns || mysqlErr.Number == mySQLErrTooManyConns
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ import (
|
|||
const (
|
||||
mySQLErrDuplicateKey = 1062
|
||||
mySQLErrCollationMix = 1267
|
||||
mySQLErrTooManyConns = 1040
|
||||
mySQLErrMaxUserConns = 1203
|
||||
|
||||
driverMySQL = "mysql"
|
||||
driverSQLite = "sqlite3"
|
||||
|
@ -795,6 +797,8 @@ func (db *datastore) GetCollectionBy(condition string, value interface{}) (*Coll
|
|||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
return nil, impart.HTTPError{http.StatusNotFound, "Collection doesn't exist."}
|
||||
case db.isHighLoadError(err):
|
||||
return nil, ErrUnavailable
|
||||
case err != nil:
|
||||
log.Error("Failed selecting from collections: %v", err)
|
||||
return nil, err
|
||||
|
|
|
@ -37,6 +37,8 @@ var (
|
|||
ErrInternalGeneral = impart.HTTPError{http.StatusInternalServerError, "The humans messed something up. They've been notified."}
|
||||
ErrInternalCookieSession = impart.HTTPError{http.StatusInternalServerError, "Could not get cookie session."}
|
||||
|
||||
ErrUnavailable = impart.HTTPError{http.StatusServiceUnavailable, "Service temporarily unavailable due to high load."}
|
||||
|
||||
ErrCollectionNotFound = impart.HTTPError{http.StatusNotFound, "Collection doesn't exist."}
|
||||
ErrCollectionGone = impart.HTTPError{http.StatusGone, "This blog was unpublished."}
|
||||
ErrCollectionPageNotFound = impart.HTTPError{http.StatusNotFound, "Collection page doesn't exist."}
|
||||
|
|
|
@ -83,6 +83,7 @@ type ErrorPages struct {
|
|||
NotFound *template.Template
|
||||
Gone *template.Template
|
||||
InternalServerError *template.Template
|
||||
UnavailableError *template.Template
|
||||
Blank *template.Template
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,7 @@ func NewHandler(apper Apper) *Handler {
|
|||
NotFound: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>404</title></head><body><p>Not found.</p></body></html>{{end}}")),
|
||||
Gone: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>410</title></head><body><p>Gone.</p></body></html>{{end}}")),
|
||||
InternalServerError: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>500</title></head><body><p>Internal server error.</p></body></html>{{end}}")),
|
||||
UnavailableError: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>503</title></head><body><p>Service is temporarily unavailable.</p></body></html>{{end}}")),
|
||||
Blank: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>{{.Title}}</title></head><body><p>{{.Content}}</p></body></html>{{end}}")),
|
||||
},
|
||||
sessionStore: apper.App().SessionStore(),
|
||||
|
@ -111,6 +113,7 @@ func NewWFHandler(apper Apper) *Handler {
|
|||
NotFound: pages["404-general.tmpl"],
|
||||
Gone: pages["410.tmpl"],
|
||||
InternalServerError: pages["500.tmpl"],
|
||||
UnavailableError: pages["503.tmpl"],
|
||||
Blank: pages["blank.tmpl"],
|
||||
})
|
||||
return h
|
||||
|
@ -763,6 +766,10 @@ func (h *Handler) handleHTTPError(w http.ResponseWriter, r *http.Request, err er
|
|||
log.Info("handleHTTPErorr internal error render")
|
||||
h.errors.InternalServerError.ExecuteTemplate(w, "base", pageForReq(h.app.App(), r))
|
||||
return
|
||||
} else if err.Status == http.StatusServiceUnavailable {
|
||||
w.WriteHeader(err.Status)
|
||||
h.errors.UnavailableError.ExecuteTemplate(w, "base", pageForReq(h.app.App(), r))
|
||||
return
|
||||
} else if err.Status == http.StatusAccepted {
|
||||
impart.WriteSuccess(w, "", err.Status)
|
||||
return
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{{define "head"}}<title>Temporarily Unavailable — {{.SiteMetaName}}</title>{{end}}
|
||||
{{define "content"}}
|
||||
<div class="error-page">
|
||||
<p class="msg">The words aren't coming to me. 🗅</p>
|
||||
<p>We couldn't serve this page due to high server load. This should only be temporary.</p>
|
||||
</div>
|
||||
{{end}}
|
Loading…
Reference in New Issue