Compare commits
4 Commits
7c32f1aad2
...
c2d192d8a3
Author | SHA1 | Date | |
---|---|---|---|
c2d192d8a3 | |||
31734596f6 | |||
850fa0a760 | |||
1c0a9860fa |
1
.env
1
.env
@ -4,6 +4,7 @@ APIKEY=lfk
|
||||
EVENTNAME=Lauf für Kaya! 2025
|
||||
CURRENCYSYMBOL=€
|
||||
GOTENBERG_BASEURL=http://localhost:3001
|
||||
REDIS_ADDR=localhost:6379
|
||||
|
||||
CARD_SUBTITLE=Kaya ist cool
|
||||
CARD_BARCODEFORMAT=ean13
|
||||
|
26
README.md
26
README.md
@ -68,3 +68,29 @@ docker build -t registry.odit.services/lfk/document-server:latest .
|
||||
# multiarch
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 -t registry.odit.services/lfk/document-server:latest --push .
|
||||
```
|
||||
|
||||
## ⏱️ Benchmarks
|
||||
|
||||
### Barcode Generation
|
||||
|
||||
- Requests: 10000
|
||||
- Concurrency: Unlimited
|
||||
- Data: `123456789123`
|
||||
- Width: 1000
|
||||
- Height: 500
|
||||
|
||||
#### No cache
|
||||
|
||||
| Format | Requests/sec | Slowest | Fastest | Average |
|
||||
| ------- | ------------ | ------- | ------- | ------- |
|
||||
| Code128 | 763.3996 | 0.7995 | 0.0172 | 0.0654 |
|
||||
| EAN13 | 767.1170 | 0.7607 | 0.0171 | 0.0651 |
|
||||
| QR | 683.8472 | 0.6528 | 0.0178 | 0.0730 |
|
||||
|
||||
#### Redis cache
|
||||
|
||||
| Format | Requests/sec | Slowest | Fastest | Average |
|
||||
| ------- | ------------ | ------- | ------- | ------- |
|
||||
| Code128 | 15611.5521 | 0.0965 | 0.0006 | 0.0032 |
|
||||
| EAN13 | 14985.4401 | 0.0925 | 0.0006 | 0.0033 |
|
||||
| QR | 14306.2540 | 0.1143 | 0.0005 | 0.0035 |
|
@ -2,4 +2,8 @@ services:
|
||||
gotenberg:
|
||||
image: gotenberg/gotenberg:8
|
||||
ports:
|
||||
- "3001:3000"
|
||||
- "3001:3000"
|
||||
redis:
|
||||
image: docker.dragonflydb.io/dragonflydb/dragonfly
|
||||
ports:
|
||||
- "6379:6379"
|
@ -8,4 +8,8 @@ services:
|
||||
gotenberg:
|
||||
image: gotenberg/gotenberg:8
|
||||
ports:
|
||||
- "3001:3000"
|
||||
- "3001:3000"
|
||||
redis:
|
||||
image: docker.dragonflydb.io/dragonflydb/dragonfly
|
||||
ports:
|
||||
- "6379:6379"
|
@ -4,6 +4,7 @@ APIKEY=lfk
|
||||
EVENTNAME=Lauf für Kaya! 2025
|
||||
CURRENCYSYMBOL=€
|
||||
GOTENBERG_BASEURL=http://gotenberg:3000
|
||||
REDIS_ADDR=redis:6379
|
||||
|
||||
CARD_SUBTITLE=Kaya ist cool
|
||||
CARD_BARCODEFORMAT=ean13
|
||||
|
3
go.mod
3
go.mod
@ -14,6 +14,8 @@ require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
@ -32,6 +34,7 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/oxplot/papersizes v0.0.0-20181201065918-90a3a5ae1915 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
|
6
go.sum
6
go.sum
@ -4,9 +4,13 @@ github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7X
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4=
|
||||
github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
@ -54,6 +58,8 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
|
13
main.go
13
main.go
@ -12,6 +12,7 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/keyauth"
|
||||
"github.com/gofiber/swagger"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@ -73,7 +74,17 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
barcodeGenerator := &services.DefaultBarcodeService{}
|
||||
var redisClient *redis.Client
|
||||
if config.RedisAddr != "" {
|
||||
log.Println("Using redis at", config.RedisAddr)
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
Addr: config.RedisAddr,
|
||||
})
|
||||
}
|
||||
|
||||
barcodeGenerator := &services.DefaultBarcodeService{
|
||||
RedisClient: redisClient,
|
||||
}
|
||||
staticService := &services.DefaultStaticService{
|
||||
Cache: make(map[string]string),
|
||||
}
|
||||
|
@ -15,4 +15,5 @@ type Config struct {
|
||||
SponsoringBarcodePrefix string `mapstructure:"SPONSORING_BARCODEPREFIX"`
|
||||
CertificateFooter string `mapstructure:"CERTIFICATE_FOOTER"`
|
||||
GotenbergBaseUrl string `mapstructure:"GOTENBERG_BASEURL"`
|
||||
RedisAddr string `mapstructure:"REDIS_ADDR"`
|
||||
}
|
||||
|
@ -2,14 +2,18 @@ package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"image/png"
|
||||
"log"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/code128"
|
||||
"github.com/boombuler/barcode/ean"
|
||||
"github.com/boombuler/barcode/qr"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type BarcodeService interface {
|
||||
@ -18,13 +22,26 @@ type BarcodeService interface {
|
||||
}
|
||||
|
||||
type DefaultBarcodeService struct {
|
||||
RedisClient *redis.Client
|
||||
}
|
||||
|
||||
func (b *DefaultBarcodeService) GenerateBarcode(format string, content string, width int, height int) (bytes.Buffer, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
if !b.IsTypeSupported(format) {
|
||||
return bytes.Buffer{}, fmt.Errorf("unsupported barcode type: %s", format)
|
||||
}
|
||||
|
||||
if b.RedisClient != nil {
|
||||
cachedBarcode, err := b.RedisClient.Get(ctx, fmt.Sprintf("barcode:%s:%s:%d:%d", format, content, width, height)).Result()
|
||||
if err == nil {
|
||||
log.Printf("Cache hit for barcode:%s:%s:%d:%d", format, content, width, height)
|
||||
buf := bytes.Buffer{}
|
||||
buf.Write([]byte(cachedBarcode))
|
||||
return buf, nil
|
||||
}
|
||||
}
|
||||
|
||||
var generatedCode barcode.Barcode
|
||||
var err error
|
||||
|
||||
@ -60,6 +77,13 @@ func (b *DefaultBarcodeService) GenerateBarcode(format string, content string, w
|
||||
return bytes.Buffer{}, err
|
||||
}
|
||||
|
||||
if b.RedisClient != nil {
|
||||
err = b.RedisClient.Set(ctx, fmt.Sprintf("barcode:%s:%s:%d:%d", format, content, width, height), buf.String(), 10*time.Minute).Err()
|
||||
if err != nil {
|
||||
return bytes.Buffer{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user