etag write to file

handle query before db loaded
This commit is contained in:
thuanle
2024-07-14 00:48:58 +07:00
parent 12603bbf6c
commit eaeb32b421
4 changed files with 39 additions and 7 deletions

View File

@@ -2,10 +2,11 @@ services:
ip-info: ip-info:
build: . build: .
ports: ports:
- "8080:8080" - "28080:8080"
restart: always restart: always
volumes: volumes:
- ./data:/app/data - ./data:/app/data
environment: environment:
- GIN_MODE=release
- GIN_TRUSTED_PROXY_IP=127.0.0.1 - GIN_TRUSTED_PROXY_IP=127.0.0.1
- TZ=Asia/Ho_Chi_Minh - TZ=Asia/Ho_Chi_Minh

View File

@@ -8,7 +8,8 @@ import (
import reader "github.com/oschwald/maxminddb-golang" import reader "github.com/oschwald/maxminddb-golang"
type IpDb struct { type IpDb struct {
r *reader.Reader r *reader.Reader
mu sync.RWMutex
} }
var ( var (
@@ -25,6 +26,9 @@ func Ins() *IpDb {
} }
func (d *IpDb) Reload() error { func (d *IpDb) Reload() error {
d.mu.Lock()
defer d.mu.Unlock()
if d.r != nil { if d.r != nil {
_ = d.r.Close() _ = d.r.Close()
} }
@@ -37,3 +41,7 @@ func (d *IpDb) Reload() error {
d.r = r d.r = r
return nil return nil
} }
func (d *IpDb) IsLoaded() bool {
return d.r != nil
}

View File

@@ -9,6 +9,12 @@ import (
func HandleJson(c *gin.Context) { func HandleJson(c *gin.Context) {
ip := c.ClientIP() ip := c.ClientIP()
if !data.Ins().IsLoaded() {
log.Error().Msg("DB is not loaded")
c.String(http.StatusInternalServerError, "Try again later")
return
}
ipData, _, err := data.Ins().Query(ip) ipData, _, err := data.Ins().Query(ip)
if err != nil { if err != nil {
log.Err(err).Msg("Failed to query IP") log.Err(err).Msg("Failed to query IP")
@@ -17,6 +23,8 @@ func HandleJson(c *gin.Context) {
}) })
return return
} }
ipData["ip"] = ip ipData["ip"] = ip
c.JSON(http.StatusOK, ipData) c.JSON(http.StatusOK, ipData)
} }

View File

@@ -4,12 +4,11 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"net/http" "net/http"
"os"
"path" "path"
"thuanle.me/ip-info/configs" "thuanle.me/ip-info/configs"
) )
var etags = map[string]string{}
func download(url string) bool { func download(url string) bool {
log.Info().Str("url", url).Msg("Downloading DB") log.Info().Str("url", url).Msg("Downloading DB")
filename := configs.GeoDbFolder + path.Base(url) filename := configs.GeoDbFolder + path.Base(url)
@@ -17,7 +16,7 @@ func download(url string) bool {
client := resty.New() client := resty.New()
resp, err := client.R(). resp, err := client.R().
SetOutput(filename). SetOutput(filename).
SetHeader("If-None-Match", etags[url]). SetHeader("If-None-Match", readETag(filename)).
Get(url) Get(url)
if err != nil { if err != nil {
@@ -28,15 +27,31 @@ func download(url string) bool {
} }
if resp.StatusCode() == http.StatusOK { if resp.StatusCode() == http.StatusOK {
etags[url] = resp.Header().Get("Etag") writeETag(filename, resp.Header().Get("Etag"))
} else { } else {
//log.Printf("No update needed: %v", resp.Status()) //log.Printf("No update needed: %v", resp.Status())
return false return false
} }
log.Info(). log.Info().
Str("Etag", etags[url]).
Str("filename", filename). Str("filename", filename).
Msg("Downloaded DB") Msg("Downloaded DB")
return true return true
} }
// readETag reads the ETag from the file
func readETag(baseFile string) string {
data, err := os.ReadFile(baseFile + ".etag")
if err != nil {
return ""
}
return string(data)
}
// writeETag writes the ETag to the file
func writeETag(baseFile, etag string) {
err := os.WriteFile(baseFile+".etag", []byte(etag), 0644)
if err != nil {
log.Err(err).Msg("Failed to write ETag")
}
}