From e8f2412efe55c969390168e3ce0b41200f780a1e Mon Sep 17 00:00:00 2001 From: Jan C Date: Mon, 28 Mar 2016 14:30:15 +0200 Subject: cache hinzugefuegt. wird derzeit vom lists und grils modul verwendet. versuch die loadingzeit zu verringern (anscheinend wird im hintergrund auf jeder route der index requested, was ziemlich doof ist). diff --git a/cache/cache.go b/cache/cache.go new file mode 100644 index 0000000..ca588ae --- /dev/null +++ b/cache/cache.go @@ -0,0 +1,56 @@ +package cache + +import ( + "time" + "log" +) + +type CacheItem struct { + Expires time.Time + Value interface{} +} +type Cache struct { + items map[int]CacheItem +} + +func New() *Cache { + c := &Cache{ make(map[int]CacheItem) } + go c.ticker() + return c +} + +func (c *Cache) ticker() { + for _ = range time.NewTicker(time.Second * 1).C { + t := time.Now() + for key, item := range c.items { + if t.Sub(item.Expires) > 0 { + log.Println("cache delete", key) + delete(c.items, key) + } + } + } +} + +func (c *Cache) Insert(key int, item interface{}) { + c.items[key] = CacheItem{ time.Now().Add(time.Minute * 5), item } +} + +func (c *Cache) Remove(key int) { + delete(c.items, key) +} + +func (c *Cache) Clear() { + c.items = make(map[int]CacheItem) +} + +func (c *Cache) Get(key int) (interface{}, bool) { + if ci, ok := c.items[key]; ok { + return ci.Value, true + } + return nil, false +} + +func (c *Cache) Has(key int) bool { + _, ok := c.items[key] + return ok +} \ No newline at end of file diff --git a/main.go b/main.go index 6311304..dd24d01 100644 --- a/main.go +++ b/main.go @@ -17,12 +17,17 @@ import ( "github.com/julienschmidt/httprouter" _ "github.com/lib/pq" + "strings" ) var app *grilist.Grilist func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - http.Redirect(w, r, "/dashboard", 302) + if strings.Index(r.Referer(), "127.0.0.1") != -1 { + w.WriteHeader(200) + return + } + http.Redirect(w, r, "/dashboard", 301) } func loadModule(mod grilist.Module) error { @@ -61,6 +66,7 @@ func main() { router, } + router.GET("/", index) router.HandlerFunc("GET", "/login", login.DisplayLogin) router.HandlerFunc("POST", "/login", login.Login) router.HandlerFunc("GET", "/settings", login.DisplayUserSettings) @@ -68,8 +74,6 @@ func main() { router.HandlerFunc("GET", "/logout", login.Logout) router.HandlerFunc("GET", "/register", login.DisplayRegistration) router.HandlerFunc("POST", "/register", login.Register) - router.GET("/", index) - router.GET("/dashboard", viewDashboard) fs := http.FileServer(http.Dir("assets")) http.Handle("/assets/", http.StripPrefix("/assets/", fs)) @@ -81,6 +85,7 @@ func main() { loadModule(tags.New()) loadModule(search.New()) loadModule(user.New()) + router.GET("/dashboard", viewDashboard) log.Fatal(http.ListenAndServe(":8080", nil)) } diff --git a/modules/grils/gril.go b/modules/grils/gril.go index 7b782b3..f78d31f 100644 --- a/modules/grils/gril.go +++ b/modules/grils/gril.go @@ -46,12 +46,12 @@ func ImagePath(id int, prioritizeThumbnail bool) string { // Image Priority // without prioritizeThumbnail: Anilist > ACD (big) > ACD (thumbnail) // with prioritizeThumbnail: Anilist > ACD (thumbnail) > ACD (big) - + anilistPath := fmt.Sprintf("assets/img/gril/%d/%d.jpg", DataSourceAnilist, id) if _, err := os.Stat(anilistPath); err == nil { return fmt.Sprintf(anilistPath) } - + var big string exts := []string{"png", "jpg", "gif", "jpeg"} for _, ext := range exts { diff --git a/modules/grils/grils.go b/modules/grils/grils.go index fe947bc..791ea5e 100644 --- a/modules/grils/grils.go +++ b/modules/grils/grils.go @@ -6,16 +6,22 @@ import ( "net/http" "regexp" "strconv" + "time" "strings" - "time" "fagott.pw/charakterin" "fagott.pw/grilist/frontend" "fagott.pw/grilist/grilist" + "fagott.pw/grilist/cache" "github.com/julienschmidt/httprouter" ) +type CachedGril struct { + Created time.Time + Gril *Gril +} + var ( pgArrayReg = regexp.MustCompile(`(((?P(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)`) pgValueIdx int @@ -32,6 +38,7 @@ func findIdx() { type GrilsModule struct { g *grilist.Grilist + c *cache.Cache } func (m *GrilsModule) Name() string { @@ -43,6 +50,8 @@ func (m *GrilsModule) Init(g *grilist.Grilist) { m.g = g m.g.Router.GET("/gril/:id", m.viewGril) m.g.Router.GET("/gril/:id/*rest", m.viewGril) + + m.c = cache.New() } func (m *GrilsModule) getGrils(whereClause string, params ...interface{}) ([]*Gril, error) { @@ -143,6 +152,10 @@ func (m *GrilsModule) ProvideDashboardData(user *charakterin.User) []grilist.Das } func (m *GrilsModule) FromID(id int) (*Gril, error) { + if g, ok := m.c.Get(id); ok { + return g.(*Gril), nil + } + gril := &Gril{ ID: id, } @@ -155,6 +168,7 @@ func (m *GrilsModule) FromID(id int) (*Gril, error) { if err != nil { return nil, err } + m.c.Insert(id, gril) return gril, nil } diff --git a/modules/lists/lists.go b/modules/lists/lists.go index 836f6af..910162a 100644 --- a/modules/lists/lists.go +++ b/modules/lists/lists.go @@ -7,6 +7,7 @@ import ( "fagott.pw/charakterin" "fagott.pw/grilist/frontend" "fagott.pw/grilist/grilist" + "fagott.pw/grilist/cache" "fagott.pw/grilist/modules/grils" "fmt" "github.com/julienschmidt/httprouter" @@ -22,6 +23,7 @@ import ( // Module und so. type Module struct { g *grilist.Grilist + c *cache.Cache grils *grils.GrilsModule } @@ -76,6 +78,8 @@ func (m *Module) Init(g *grilist.Grilist) { m.g.Router.POST("/new/list", m.createList) m.g.Router.GET("/api/lists/user", m.APIgetUserLists) + + m.c = cache.New() } func (m *Module) getListGrils(list *List) error { @@ -85,6 +89,7 @@ func (m *Module) getListGrils(list *List) error { } defer rows.Close() + list.Grils = list.Grils[:0] for rows.Next() { var grilID int lg := &ListGril{} @@ -123,6 +128,12 @@ func (m *Module) getLists(whereClause string, params ...interface{}) ([]*List, e log.Println("error scanning row in getLists:", err) continue } + + if clist, ok := m.c.Get(list.ID); ok { + // weiteres parsen abbrechen + lists = append(lists, clist.(*List)) + continue + } // Owner kriegn owner, err := m.g.Charakterin.GetUserByID(ownerID) @@ -131,7 +142,8 @@ func (m *Module) getLists(whereClause string, params ...interface{}) ([]*List, e continue } list.Owner = owner - + + m.c.Insert(list.ID, list) lists = append(lists, list) } @@ -157,6 +169,17 @@ func (m *Module) GetUserLists(u *charakterin.User, withGrils bool) []*List { // FromID sucht nach der Liste mit der gegebenen ID und gibt sie, falls sie existiert, zurück. func (m *Module) FromID(id int, withGrils bool) (*List, error) { + if lst, ok := m.c.Get(id); ok { + l := lst.(*List) + // Potenzieller Optimierungsbedarf: neue query, wenn die Liste leer ist. updateGrilOrder nutzt derzeit aber genau dieses verhalten. + if withGrils && len(l.Grils) == 0 { + if err := m.getListGrils(l); err != nil { + return nil, err + } + } + return l, nil + } + lists, err := m.getLists(`id = $1`, id) if err != nil { return nil, err @@ -210,11 +233,12 @@ func (m *Module) ProvideDashboardData(user *charakterin.User) []grilist.Dashboar log.Println(err) return categories } - //for _, list := range lists { - //if err := m.getListGrils(list); err != nil { - // log.Println(err) - //} - //} + + for _, list := range lists { + if err := m.getListGrils(list); err != nil { + log.Println(err) + } + } categories = append(categories, grilist.DashboardCategory{ Title: "Neueste Listen", @@ -242,12 +266,14 @@ func (m *Module) viewList(w http.ResponseWriter, r *http.Request, p httprouter.P id, err := strconv.Atoi(sid) if err != nil { + log.Println("redir") http.Redirect(w, r, "/", 302) return } list, err := m.FromID(id, true) if err != nil { + log.Println("redir") http.Redirect(w, r, "/", 302) return } @@ -406,6 +432,12 @@ func (m *Module) updateGrilOrder(w http.ResponseWriter, r *http.Request, p httpr http.Error(w, "could not update gril order", 500) return } + + // wenn die liste im cache ist, die Grils clearen, damit beim naechsten aufruf die Gril-Liste neu geholt wird. + if l, ok := m.c.Get(listID); ok { + ls := l.(*List) + ls.Grils = ls.Grils[:0] + } w.WriteHeader(200) w.Write([]byte("ok")) diff --git a/modules/user/user.go b/modules/user/user.go index 06245e2..92a04db 100644 --- a/modules/user/user.go +++ b/modules/user/user.go @@ -27,13 +27,13 @@ func (m *Module) Name() string { func (m *Module) Init(g *grilist.Grilist) { m.g = g - + gm, ok := g.Modules["Lists"] if !ok { log.Fatal("tags: lists module not found") } m.lists = gm.(*lists.Module) - + m.g.Router.GET("/user/:id", m.viewUser) m.g.Router.GET("/user/:id/*rest", m.viewUser) } @@ -44,13 +44,13 @@ func (m *Module) ProvideDashboardData(user *charakterin.User) []grilist.Dashboar func (m *Module) viewUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { currentUser, _ := m.g.Charakterin.GetUserFromRequest(r) - + userID, err := strconv.Atoi(p.ByName("id")) if err != nil { http.Redirect(w, r, "/", 302) return } - + user := currentUser if user == nil || currentUser.ID != userID { user, err = m.g.Charakterin.GetUserByID(userID) @@ -59,13 +59,13 @@ func (m *Module) viewUser(w http.ResponseWriter, r *http.Request, p httprouter.P return } } - + userLists := m.lists.GetUserLists(user, true) - + data := m.g.Renderer.DefaultData() data["user"] = currentUser data["DisplayUser"] = user data["Lists"] = lists.ListsToCards(userLists) - + m.g.Renderer.RenderPage("user", w, data) } -- cgit v0.10.1