Projects list cache

This commit is contained in:
Brieuc Dubois 2024-01-04 16:20:00 +01:00
parent 505e5aae75
commit 909ad208de
7 changed files with 98 additions and 45 deletions

View File

@ -23,29 +23,27 @@ func projectsRouter(router fiber.Router) error {
return nil
}
var projectsLastEdit time.Time;
var projectsLastEdit time.Time = time.Now().Truncate(time.Second);
func GetAllProjects(c *fiber.Ctx) error {
isCached, err := utils.Cache(c, projectsLastEdit);
isCached, err := utils.Cache(c, &projectsLastEdit);
if err == nil && isCached {
return nil;
}
projects, err := db.GetAllProjects()
currentTime := time.Now();
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Cannot retrieve projects",
"trace": fmt.Sprint(err),
})
}
err = c.Status(fiber.StatusOK).JSON(projects)
if err != nil {
return err;
}
projectsLastEdit = currentTime;
return nil;
}
@ -83,6 +81,8 @@ func CreateProject(c *fiber.Ctx) error {
})
}
projectsLastEdit = time.Now().Truncate(time.Second);
return c.Status(fiber.StatusCreated).JSON(fiber.Map{
"id": id,
})
@ -111,6 +111,8 @@ func UpdateProject(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNotFound)
}
projectsLastEdit = time.Now().Truncate(time.Second);
return c.SendStatus(fiber.StatusNoContent)
}
@ -132,6 +134,8 @@ func DeleteProject(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNotFound)
}
projectsLastEdit = time.Now().Truncate(time.Second);
return c.SendStatus(fiber.StatusNoContent)
}

View File

@ -33,7 +33,7 @@ func main() {
app.Use(cors.New(cors.Config{
AllowOrigins: origins,
AllowMethods: "GET,POST,PUT,DELETE",
AllowHeaders: "Origin, Content-Type, Accept",
AllowHeaders: "Origin, Content-Type, Accept, Cache-Control, Pragma,Expires, If-Modified-Since",
}))
// app.Use(cache.New())

View File

@ -6,16 +6,22 @@ import (
"github.com/gofiber/fiber/v2"
)
func Cache(c *fiber.Ctx, lastEdit time.Time) (bool, error) {
clientLast, err := time.Parse(time.RFC1123, c.Get("If-Modified-Since"))
func Cache(c *fiber.Ctx, lastEdit *time.Time) (bool, error) {
ifModifiedSince := c.Get("If-Modified-Since")
if ifModifiedSince == "" {
return false, nil
}
clientLast, err := time.Parse(time.RFC1123, ifModifiedSince)
if err != nil {
return false, err
}
if clientLast.Before(lastEdit) {
if !lastEdit.After(clientLast) {
c.SendStatus(fiber.StatusNotModified)
return true, nil
}
c.Set("Last-Modified", lastEdit.Format(time.RFC1123))
return false, nil
}

View File

@ -8,7 +8,8 @@
"name": "frontend",
"version": "0.0.1",
"dependencies": {
"axios": "^1.6.3",
"axios": "^1.6.4",
"axios-cache-interceptor": "^1.4.1",
"less": "^4.2.0",
"svelte-multiselect": "^10.2.0"
},
@ -1251,15 +1252,34 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz",
"integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.4.tgz",
"integrity": "sha512-heJnIs6N4aa1eSthhN9M5ioILu8Wi8vmQW9iHQ9NUvfkJb0lEEDUiIdQNAuBtfUt3FxReaKdpQA5DbmMOqzF/A==",
"dependencies": {
"follow-redirects": "^1.15.0",
"follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios-cache-interceptor": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-1.4.1.tgz",
"integrity": "sha512-Ax4+PiGfNxpQvyF00t55nFzWoVnqW7slKCg9va6dbqiuAGIxRE8r1uMzunw8TKJ5iwLivFqAb0EeiLeUCxuZIw==",
"dependencies": {
"cache-parser": "1.2.4",
"fast-defer": "1.1.8",
"object-code": "1.3.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/arthurfiorette/axios-cache-interceptor?sponsor=1"
},
"peerDependencies": {
"axios": "^1"
}
},
"node_modules/axobject-query": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
@ -1313,6 +1333,11 @@
"node": "*"
}
},
"node_modules/cache-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz",
"integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g=="
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -1880,6 +1905,11 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"node_modules/fast-defer": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.8.tgz",
"integrity": "sha512-lEJeOH5VL5R09j6AA0D4Uvq7AgsHw0dAImQQ+F3iSyHZuAxyQfWobsagGpTcOPvJr3urmKRHrs+Gs9hV+/Qm/Q=="
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@ -1990,9 +2020,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
@ -2665,6 +2695,11 @@
"node": ">=0.10.0"
}
},
"node_modules/object-code": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/object-code/-/object-code-1.3.2.tgz",
"integrity": "sha512-3CVDmQiru7YYVr+4OpCGrqkVE7GogmWinDcgfno1fXlKgIhtW9FhgHTiV98gMPUjQwWuWvijQDCY8sGnqKrhTw=="
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",

View File

@ -35,7 +35,8 @@
},
"type": "module",
"dependencies": {
"axios": "^1.6.3",
"axios": "^1.6.4",
"axios-cache-interceptor": "^1.4.1",
"less": "^4.2.0",
"svelte-multiselect": "^10.2.0"
}

View File

@ -19,9 +19,9 @@
projects = response.data || [];
} catch (e: any) {
toastAlert('Failed to fetch projects', e);
setTimeout(() => {
window.location.reload();
}, 11000);
// setTimeout(() => {
// window.location.reload();
// }, 11000);
}
});

View File

@ -1,27 +1,34 @@
import axios, { Axios, type AxiosResponse } from "axios";
import { backend } from "../stores/config";
import { toastAlert } from "./toasts";
import axios, { Axios, type AxiosResponse } from 'axios';
import { backend } from '../stores/config';
import { toastAlert } from './toasts';
import { setupCache } from 'axios-cache-interceptor';
export default new Axios({
...axios.defaults,
baseURL: backend + '/api',
validateStatus: () => true,
headers: {
'Content-Type': 'application/json'
},
});
export default setupCache(
new Axios({
...axios.defaults,
baseURL: backend + '/api',
validateStatus: () => true,
headers: {
'Content-Type': 'application/json'
}
}),
{
interpretHeader: true,
modifiedSince: true
}
);
export function processError (response: AxiosResponse<any, any>, message: string = '') {
let title = `${response.status} ${response.statusText}`;
let subtitle = message;
export function processError(response: AxiosResponse<any, any>, message: string = '') {
let title = `${response.status} ${response.statusText}`;
let subtitle = message;
if(response.headers["content-type"] === "application/json") {
const parsed = response.data;
subtitle = parsed.error;
if(response.data.trace) {
subtitle += '<br><br>' + parsed.trace;
}
}
if (response.headers['content-type'] === 'application/json') {
const parsed = response.data;
subtitle = parsed.error;
if (response.data.trace) {
subtitle += '<br><br>' + parsed.trace;
}
}
toastAlert(title, subtitle);
}
toastAlert(title, subtitle);
}