Running out of memory now

Save to DB happens on timed interval and on shutdown
This commit is contained in:
Brian Buller 2018-01-23 14:55:52 -06:00
parent 0850550be4
commit 84cba4d340
6 changed files with 116 additions and 43 deletions

View File

@ -20,13 +20,7 @@ func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData)
teamId := vars["id"]
if teamId == "" {
// Games List
// TODO: We should be able to just pass m.jam to the template instead of a custom struct
type gamesPageData struct {
Teams []Team
}
gpd := new(gamesPageData)
gpd.Teams = m.jam.Teams
page.TemplateData = gpd
page.TemplateData = m.jam
page.SubTitle = "Games"
page.show("admin-games.html", w)
} else {
@ -48,22 +42,50 @@ func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData)
page.session.setFlashMessage("Team game updated", "success")
}
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
case "screenshotupload":
if err := saveScreenshots(tm, req); err != nil {
var ss *Screenshot
tm, err := m.jam.GetTeamById(tm.UUID)
if err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
}
ss, err = ssFromRequest(tm, req)
if err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
}
gm := tm.Game
gm.Screenshots = append(gm.Screenshots, *ss)
if err = m.jam.UpdateGame(tm.UUID, gm); err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
} else {
page.session.setFlashMessage("Screenshot Uploaded", "success")
}
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
case "screenshotdelete":
var ss *Screenshot
var err error
ssid := vars["subid"]
if ss, err = NewScreenshot(tm.UUID, ssid); err != nil {
page.session.setFlashMessage("Error deleting screenshot: "+err.Error(), "error")
tm, err := m.jam.GetTeamById(tm.UUID)
if err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
break
}
if err = m.jam.DeleteScreenshot(ss); err != nil {
page.session.setFlashMessage("Error deleting screenshot: "+err.Error(), "error")
gm := tm.Game
if err = gm.RemoveScreenshot(ssid); err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
break
}
if err = m.jam.UpdateGame(tm.UUID, gm); err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
} else {
page.session.setFlashMessage("Screenshot Removed", "success")
}
redirect("/admin/teams/"+tm.UUID+"#game", w, req)
}
} else {
page.session.setFlashMessage("Not a valid team id", "error")
@ -72,13 +94,13 @@ func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData)
}
}
func saveScreenshots(tm *Team, req *http.Request) error {
func ssFromRequest(tm *Team, req *http.Request) (*Screenshot, error) {
var err error
var ss *Screenshot
file, hdr, err := req.FormFile("newssfile")
if err != nil {
return err
return nil, err
}
extIdx := strings.LastIndex(hdr.Filename, ".")
fltp := "png"
@ -89,29 +111,30 @@ func saveScreenshots(tm *Team, req *http.Request) error {
buf := new(bytes.Buffer)
// We convert everything to jpg
if err = jpeg.Encode(buf, mI, nil); err != nil {
return errors.New("Unable to encode image")
return nil, errors.New("Unable to encode image")
}
thm := resize.Resize(200, 0, mI, resize.Lanczos3)
thmBuf := new(bytes.Buffer)
var thmString string
if fltp == "gif" {
if err = gif.Encode(thmBuf, thm, nil); err != nil {
return errors.New("Unable to encode image")
return nil, errors.New("Unable to encode image")
}
} else {
if err = jpeg.Encode(thmBuf, thm, nil); err != nil {
return errors.New("Unable to encode image")
return nil, errors.New("Unable to encode image")
}
}
thmString = base64.StdEncoding.EncodeToString(thmBuf.Bytes())
if ss, err = NewScreenshot(tm.UUID, ""); err != nil {
return err
return nil, err
}
ss.Image = base64.StdEncoding.EncodeToString(buf.Bytes())
ss.Thumbnail = thmString
ss.Filetype = fltp
return m.jam.SaveScreenshot(ss)
return ss, nil
//return m.jam.SaveScreenshot(ss)
}

23
main.go
View File

@ -9,8 +9,11 @@ import (
"log"
"net/http"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
"golang.org/x/crypto/ssh/terminal"
@ -71,6 +74,15 @@ func main() {
if err = m.site.SaveToDB(); err != nil {
errorExit("Unable to save site config to DB: " + err.Error())
}
// Save changes to the DB every 5 minutes
go func() {
for {
m.saveChanges()
time.Sleep(5 * time.Minute)
}
}()
initialize()
r = mux.NewRouter()
@ -108,6 +120,17 @@ func main() {
chain := alice.New(loggingHandler).Then(r)
// Set up a channel to intercept Ctrl+C for graceful shutdowns
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
// Save the changes when the app quits
fmt.Println("\nFinishing up...")
m.saveChanges()
os.Exit(0)
}()
fmt.Printf("Listening on port %d\n", m.site.Port)
log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(m.site.Port), chain))
}

View File

@ -2,6 +2,7 @@ package main
import (
"errors"
"fmt"
"github.com/br0xen/boltease"
)
@ -114,22 +115,25 @@ func (m *model) saveChanges() error {
}
defer m.closeDB()
if m.site.NeedsSave() {
if err = m.site.SaveToDB(); err != nil {
return err
}
//if m.site.NeedsSave() {
fmt.Println("Saving Site data to DB")
if err = m.site.SaveToDB(); err != nil {
return err
}
if m.jam.IsChanged {
if err = m.jam.SaveToDB(); err != nil {
return err
}
m.jam.IsChanged = false
//}
//if m.jam.IsChanged {
fmt.Println("Saving Jam data to DB")
if err = m.jam.SaveToDB(); err != nil {
return err
}
if m.clientsUpdated {
if err = m.SaveAllClients(); err != nil {
return err
}
m.clientsUpdated = false
m.jam.IsChanged = false
//}
//if m.clientsUpdated {
fmt.Println("Saving Client data to DB")
if err = m.SaveAllClients(); err != nil {
return err
}
m.clientsUpdated = false
//}
return nil
}

View File

@ -2,6 +2,7 @@ package main
import (
"errors"
"fmt"
"github.com/pborman/uuid"
)
@ -45,12 +46,12 @@ func (gm *Game) RemoveScreenshot(ssId string) error {
for i, ss := range gm.Screenshots {
if ss.UUID == ssId {
idx = i
return nil
}
}
if idx < 0 {
return errors.New("Invalid Id")
}
fmt.Print("Removing Screenshot (", ssId, ") (IDX:", idx, ")\n")
gm.Screenshots = append(gm.Screenshots[:idx], gm.Screenshots[idx+1:]...)
return nil
}

View File

@ -2,6 +2,7 @@ package main
import (
"errors"
"fmt"
"strconv"
"time"
)
@ -30,7 +31,10 @@ func NewVote(clId string, tm time.Time) (*Vote, error) {
}
vt := new(Vote)
vt.Timestamp = tm
vt.mPath = []string{"jam", "votes", clId, tm.Format(time.RFC3339)}
return vt, nil
}
@ -52,9 +56,9 @@ func (gj *Gamejam) GetVoteWithTimeString(clId, ts string) (*Vote, error) {
}
func (gj *Gamejam) GetVote(clId string, ts time.Time) (*Vote, error) {
for _, v := range gj.Votes {
if v.ClientId == clId && v.Timestamp == ts {
return &v, nil
for i := range gj.Votes {
if gj.Votes[i].ClientId == clId && gj.Votes[i].Timestamp == ts {
return &gj.Votes[i], nil
}
}
return nil, errors.New("Couldn't find requested vote")
@ -96,6 +100,7 @@ func (gj *Gamejam) LoadAllVotes() []Vote {
continue
}
for _, t := range times {
fmt.Println("Loading Vote", cId, t)
if vt, err := gj.LoadVote(cId, t); err == nil {
ret = append(ret, *vt)
}
@ -116,7 +121,7 @@ func (gj *Gamejam) LoadVote(clientId, t string) (*Vote, error) {
return nil, errors.New("Error creating vote: " + err.Error())
}
var choices []string
if choices, err = m.bolt.GetKeyList(vt.mPath); err != nil {
if choices, err = gj.m.bolt.GetKeyList(vt.mPath); err != nil {
return nil, errors.New("Error creating vote: " + err.Error())
}
for _, v := range choices {
@ -124,8 +129,9 @@ func (gj *Gamejam) LoadVote(clientId, t string) (*Vote, error) {
var rank int
if rank, err = strconv.Atoi(v); err == nil {
ch.Rank = rank
ch.Team, _ = m.bolt.GetValue(vt.mPath, v)
vt.Choices = append(vt.Choices, *ch)
if ch.Team, err = gj.m.bolt.GetValue(vt.mPath, v); err == nil {
vt.Choices = append(vt.Choices, *ch)
}
}
}
return vt, nil

View File

@ -38,7 +38,8 @@ func loadVotingPage(w http.ResponseWriter, req *http.Request) {
Timestamp string
}
vpd := new(votingPageData)
tms := m.jam.Teams
tms := make([]Team, len(m.jam.Teams))
copy(tms, m.jam.Teams)
// Randomize the team list
rand.Seed(time.Now().Unix())
@ -173,6 +174,7 @@ func handleTeamMgmtRequest(w http.ResponseWriter, req *http.Request) {
page.SubTitle = "Team Management"
page.TemplateData = tm
page.show("public-teammgmt.html", w)
case "savemember":
m, err := NewTeamMember(tm.UUID, "")
if err != nil {
@ -189,6 +191,7 @@ func handleTeamMgmtRequest(w http.ResponseWriter, req *http.Request) {
page.session.setFlashMessage(m.Name+" added to team!", "success")
}
redirect("/team/"+tm.UUID+"#members", w, req)
case "deletemember":
mbrId := req.FormValue("memberid")
err := tm.RemoveTeamMemberById(mbrId)
@ -198,23 +201,36 @@ func handleTeamMgmtRequest(w http.ResponseWriter, req *http.Request) {
page.session.setFlashMessage("Team member removed", "success")
}
redirect("/team/"+tm.UUID, w, req)
case "savegame":
tm.Game.Name = req.FormValue("gamename")
tm.Game.Link = req.FormValue("gamelink")
tm.Game.Description = req.FormValue("gamedesc")
page.session.setFlashMessage("Team game updated", "success")
redirect("/team/"+tm.UUID, w, req)
case "screenshotupload":
if err := saveScreenshots(tm, req); err != nil {
ss, err := ssFromRequest(tm, req)
if err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
redirect("/team/"+tm.UUID, w, req)
}
gm := tm.Game
gm.Screenshots = append(gm.Screenshots, *ss)
if err = m.jam.UpdateGame(tm.UUID, gm); err != nil {
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
} else {
page.session.setFlashMessage("Screenshot Uploaded", "success")
}
redirect("/team/"+tm.UUID, w, req)
case "screenshotdelete":
ssid := vars["subid"]
if err := tm.Game.RemoveScreenshot(ssid); err != nil {
page.session.setFlashMessage("Error deleting screenshot: "+err.Error(), "error")
}
redirect("/team/"+tm.UUID, w, req)
}
} else {
http.Error(w, "Page Not Found", 404)