Pārlūkot izejas kodu

Show 503 page on collections under high load

This acknowledges "too many connections" and "max user connections"
errors in MySQL and propagates the error up the chain so we can notify
the user and return the correct HTTP code.
pull/284/head
Matt Baer pirms 4 gadiem
vecāks
revīzija
0285a9b0bd
5 mainītis faili ar 30 papildinājumiem un 0 dzēšanām
  1. +10
    -0
      database-no-sqlite.go
  2. +4
    -0
      database.go
  3. +2
    -0
      errors.go
  4. +7
    -0
      handle.go
  5. +7
    -0
      pages/503.tmpl

+ 10
- 0
database-no-sqlite.go Parādīt failu

@@ -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
}

+ 4
- 0
database.go Parādīt failu

@@ -39,6 +39,8 @@ import (
const (
mySQLErrDuplicateKey = 1062
mySQLErrCollationMix = 1267
mySQLErrTooManyConns = 1040
mySQLErrMaxUserConns = 1203

driverMySQL = "mysql"
driverSQLite = "sqlite3"
@@ -793,6 +795,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


+ 2
- 0
errors.go Parādīt failu

@@ -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."}


+ 7
- 0
handle.go Parādīt failu

@@ -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


+ 7
- 0
pages/503.tmpl Parādīt failu

@@ -0,0 +1,7 @@
{{define "head"}}<title>Temporarily Unavailable &mdash; {{.SiteMetaName}}</title>{{end}}
{{define "content"}}
<div class="error-page">
<p class="msg">The words aren't coming to me. &#x1F5C5;</p>
<p>We couldn't serve this page due to high server load. This should only be temporary.</p>
</div>
{{end}}

Notiek ielāde…
Atcelt
Saglabāt