move gitea to my-recipes, commit works

This commit is contained in:
2026-08-27 09:14:21 +02:00
parent 4dd66d50bf
commit 6f63abecea
23 changed files with 692 additions and 195 deletions
+17
View File
@@ -0,0 +1,17 @@
module sqlite-ls
go 1.25.0
require modernc.org/sqlite v1.56.0
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.47.0 // indirect
modernc.org/libc v1.74.4 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)
+50
View File
@@ -0,0 +1,50 @@
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
modernc.org/cc/v4 v4.29.1 h1:MKgdCV3WykTSPqpVrnxdEDS0HEd2FHpKZDzxzU5LyeI=
modernc.org/cc/v4 v4.29.1/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
modernc.org/ccgo/v4 v4.34.6/go.mod h1:SZ8YcN9NG7XVsQYdm6jYBvi8PQP1qi+kqB6OhjqI3Fk=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.4 h1:2g65LGVSmFQrXeITAw97x7hCRvZFcyE1uDP+7Vng7JI=
modernc.org/gc/v3 v3.1.4/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.74.4 h1:fX1Omw4o2/1C2iRkkIsrQTasJQldLhRmuPreXLoWs9k=
modernc.org/libc v1.74.4/go.mod h1:eeQAS9W3sZeKYMFubydxJpII9ybHWshk+7or7bLG9co=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.56.0 h1:/D8e2RfFqoy/Zc6PuC76U28zFwmI/sYx1Kjm4yEn9e0=
modernc.org/sqlite v1.56.0/go.mod h1:yCJ2cmAaIkHQ25oXWrF8H4O1lIfPYPR26yCEDj2P3pQ=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+23
View File
@@ -0,0 +1,23 @@
project:
name: ls-stress-2
services:
- hostname: data1
type: local-storage:single@1
- hostname: data2
type: local-storage:single@1
- hostname: c1a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c1b
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2b
type: go@1
minContainers: 3
maxContainers: 3
+23
View File
@@ -0,0 +1,23 @@
project:
name: ls-stress-3
services:
- hostname: data1
type: local-storage:single@1
- hostname: data2
type: local-storage:single@1
- hostname: c1a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c1b
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2b
type: go@1
minContainers: 3
maxContainers: 3
+23
View File
@@ -0,0 +1,23 @@
project:
name: ls-stress-4
services:
- hostname: data1
type: local-storage:single@1
- hostname: data2
type: local-storage:single@1
- hostname: c1a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c1b
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2b
type: go@1
minContainers: 3
maxContainers: 3
+3
View File
@@ -0,0 +1,3 @@
services:
- hostname: data2
type: local-storage:single@1
+11
View File
@@ -0,0 +1,11 @@
project:
name: ls-disk-test
services:
- hostname: data1
type: local-storage:single@1
- hostname: c1a
type: go@1
minContainers: 2
maxContainers: 2
- hostname: dckr
type: docker@26.1
+178
View File
@@ -0,0 +1,178 @@
package main
import (
"crypto/rand"
"database/sql"
"encoding/json"
"log"
"net/http"
"os"
"strconv"
"strings"
"time"
_ "modernc.org/sqlite"
)
var (
db *sql.DB
hostname string
dbFile string
)
func main() {
hostname, _ = os.Hostname()
dbPath := os.Getenv("DB_PATH")
if dbPath == "" {
dbPath = "/mnt/data/poc.db"
}
dbFile = dbPath
var err error
db, err = sql.Open("sqlite", "file:"+dbPath+"?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)&_pragma=synchronous(NORMAL)")
if err != nil {
log.Fatal(err)
}
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
container TEXT NOT NULL,
msg TEXT NOT NULL,
created_at TEXT NOT NULL,
payload BLOB
)`); err != nil {
log.Fatal(err)
}
// the payload column was added after the first deploy, older DB files need it retrofitted
if _, err := db.Exec(`ALTER TABLE entries ADD COLUMN payload BLOB`); err != nil && !strings.Contains(err.Error(), "duplicate column") {
log.Fatal(err)
}
http.HandleFunc("/", handleStatus)
http.HandleFunc("/write", handleWrite)
http.HandleFunc("/read", handleRead)
http.HandleFunc("/checkpoint", handleCheckpoint)
log.Printf("listening on :8080, db=%s, container=%s", dbPath, hostname)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func respond(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}
func handleStatus(w http.ResponseWriter, r *http.Request) {
var count int64
var journalMode string
if err := db.QueryRow("SELECT COUNT(*) FROM entries").Scan(&count); err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
db.QueryRow("PRAGMA journal_mode").Scan(&journalMode)
fileSize := func(path string) int64 {
info, err := os.Stat(path)
if err != nil {
return 0
}
return info.Size()
}
respond(w, 200, map[string]any{
"container": hostname,
"entries": count,
"journalMode": journalMode,
"dbSizeBytes": fileSize(dbFile),
"walSizeBytes": fileSize(dbFile + "-wal"),
})
}
func handleWrite(w http.ResponseWriter, r *http.Request) {
msg := r.URL.Query().Get("msg")
if msg == "" {
msg = "hello"
}
intParam := func(key string, def, max int) int {
v, err := strconv.Atoi(r.URL.Query().Get(key))
if err != nil || v < 1 {
return def
}
return min(v, max)
}
n := intParam("n", 1, 10000)
size := intParam("size", 0, 1<<20)
tx, err := db.Begin()
if err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
defer tx.Rollback()
stmt, err := tx.Prepare("INSERT INTO entries (container, msg, created_at, payload) VALUES (?, ?, ?, ?)")
if err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
defer stmt.Close()
var lastId int64
now := time.Now().UTC().Format(time.RFC3339Nano)
for i := 0; i < n; i++ {
var payload []byte
if size > 0 {
payload = make([]byte, size)
rand.Read(payload)
}
res, err := stmt.Exec(hostname, msg, now, payload)
if err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
lastId, _ = res.LastInsertId()
}
if err := tx.Commit(); err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
respond(w, 200, map[string]any{"container": hostname, "inserted": n, "lastId": lastId})
}
func handleCheckpoint(w http.ResponseWriter, r *http.Request) {
var busy, logFrames, checkpointed int64
if err := db.QueryRow("PRAGMA wal_checkpoint(TRUNCATE)").Scan(&busy, &logFrames, &checkpointed); err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
respond(w, 200, map[string]any{"container": hostname, "busy": busy, "logFrames": logFrames, "checkpointed": checkpointed})
}
func handleRead(w http.ResponseWriter, r *http.Request) {
var count int64
if err := db.QueryRow("SELECT COUNT(*) FROM entries").Scan(&count); err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
rows, err := db.Query("SELECT id, container, msg, created_at FROM entries ORDER BY id DESC LIMIT 5")
if err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
defer rows.Close()
type entry struct {
Id int64 `json:"id"`
Container string `json:"container"`
Msg string `json:"msg"`
CreatedAt string `json:"createdAt"`
}
last := []entry{}
for rows.Next() {
var e entry
if err := rows.Scan(&e.Id, &e.Container, &e.Msg, &e.CreatedAt); err != nil {
respond(w, 500, map[string]any{"container": hostname, "error": err.Error()})
return
}
last = append(last, e)
}
respond(w, 200, map[string]any{"container": hostname, "entries": count, "last": last})
}
+37
View File
@@ -0,0 +1,37 @@
project:
name: ls-delete-stress
services:
- hostname: data1
type: local-storage:single@1
- hostname: data2
type: local-storage:single@1
- hostname: c1a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c1b
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c1c
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2a
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2b
type: go@1
minContainers: 3
maxContainers: 3
- hostname: c2c
type: go@1
minContainers: 3
maxContainers: 3
- hostname: cache
type: valkey@7.2
mode: NON_HA
- hostname: db
type: postgresql@16
mode: NON_HA
+39
View File
@@ -0,0 +1,39 @@
zerops:
- setup: c1a
build: &build
base: go@1
buildCommands:
- go build -o app main.go
deployFiles: app
run: &run-data1
base: go@1
ports:
- port: 8080
httpSupport: true
volume:
hostname: data1
mountPath: /mnt/data
start: ./app
- setup: c1b
build: *build
run: *run-data1
- setup: c1c
build: *build
run: *run-data1
- setup: c2a
build: *build
run: &run-data2
base: go@1
ports:
- port: 8080
httpSupport: true
volume:
hostname: data2
mountPath: /mnt/data
start: ./app
- setup: c2b
build: *build
run: *run-data2
- setup: c2c
build: *build
run: *run-data2