Attempt to rework stats handling, add support for '~' in paths

This commit is contained in:
Seednode 2023-09-13 12:30:24 -05:00
parent 61f10a6f3c
commit 65b77f33cc
4 changed files with 104 additions and 80 deletions

View File

@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"os/user"
"regexp" "regexp"
"crypto/rand" "crypto/rand"
@ -603,7 +604,18 @@ func pickFile(args []string, filters *filters, sort string, cache *fileCache, fo
} }
func normalizePath(path string) (string, error) { func normalizePath(path string) (string, error) {
path, err := filepath.EvalSymlinks(path) usr, err := user.Current()
if err != nil {
return "", err
}
if path == "~" {
path = usr.HomeDir
} else if strings.HasPrefix(path, "~/") {
path = filepath.Join(usr.HomeDir, path[2:])
}
path, err = filepath.EvalSymlinks(path)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -12,7 +12,7 @@ import (
) )
const ( const (
ReleaseVersion string = "0.78.0" ReleaseVersion string = "0.78.1"
) )
var ( var (

View File

@ -10,12 +10,10 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"os/signal"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
@ -69,14 +67,18 @@ func (stats *serveStats) Import(source *publicServeStats) {
copy(stats.list, source.List) copy(stats.list, source.List)
for k, v := range source.Count { for k, v := range source.Count {
fmt.Printf("Setting count[%s] to %d\n", k, v)
stats.count[k] = v stats.count[k] = v
} }
for k, v := range source.Size { for k, v := range source.Size {
fmt.Printf("Setting size[%s] to %v\n", k, v)
stats.size[k] = v stats.size[k] = v
} }
for k, v := range source.Times { for k, v := range source.Times {
fmt.Printf("Setting times[%s] to %v\n", k, v)
stats.times[k] = v stats.times[k] = v
} }
@ -84,6 +86,8 @@ func (stats *serveStats) Import(source *publicServeStats) {
} }
func (source *serveStats) Export() *publicServeStats { func (source *serveStats) Export() *publicServeStats {
source.mutex.RLock()
stats := &publicServeStats{ stats := &publicServeStats{
List: make([]string, len(source.list)), List: make([]string, len(source.list)),
Count: make(map[string]uint32, len(source.count)), Count: make(map[string]uint32, len(source.count)),
@ -91,8 +95,6 @@ func (source *serveStats) Export() *publicServeStats {
Times: make(map[string][]string, len(source.times)), Times: make(map[string][]string, len(source.times)),
} }
source.mutex.RLock()
copy(stats.List, source.list) copy(stats.List, source.list)
for k, v := range source.count { for k, v := range source.count {
@ -112,6 +114,61 @@ func (source *serveStats) Export() *publicServeStats {
return stats return stats
} }
func (stats *serveStats) exportFile(path string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer file.Close()
z, err := zstd.NewWriter(file)
if err != nil {
return err
}
defer z.Close()
enc := gob.NewEncoder(z)
err = enc.Encode(stats.Export())
if err != nil {
return err
}
return nil
}
func (stats *serveStats) importFile(path string) error {
file, err := os.OpenFile(path, os.O_RDONLY, 0600)
if err != nil {
return err
}
defer file.Close()
z, err := zstd.NewReader(file)
if err != nil {
return err
}
defer z.Close()
dec := gob.NewDecoder(z)
source := &publicServeStats{
List: []string{},
Count: make(map[string]uint32),
Size: make(map[string]string),
Times: make(map[string][]string),
}
err = dec.Decode(source)
if err != nil {
return err
}
stats.Import(source)
return nil
}
func (source *serveStats) listFiles(page int) ([]byte, error) { func (source *serveStats) listFiles(page int) ([]byte, error) {
stats := source.Export() stats := source.Export()
@ -151,61 +208,6 @@ func (source *serveStats) listFiles(page int) ([]byte, error) {
return r, nil return r, nil
} }
func (stats *serveStats) ExportFile(path string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer file.Close()
z, err := zstd.NewWriter(file)
if err != nil {
return err
}
defer z.Close()
enc := gob.NewEncoder(z)
err = enc.Encode(stats.Export())
if err != nil {
return err
}
return nil
}
func (stats *serveStats) ImportFile(path string) error {
file, err := os.OpenFile(path, os.O_RDONLY, 0600)
if err != nil {
return err
}
defer file.Close()
z, err := zstd.NewReader(file)
if err != nil {
return err
}
defer z.Close()
dec := gob.NewDecoder(z)
source := &publicServeStats{
List: []string{},
Count: make(map[string]uint32),
Size: make(map[string]string),
Times: make(map[string][]string),
}
err = dec.Decode(source)
if err != nil {
return err
}
stats.Import(source)
return nil
}
func serveStatsPage(args []string, stats *serveStats) httprouter.Handle { func serveStatsPage(args []string, stats *serveStats) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
startTime := time.Now() startTime := time.Now()
@ -238,29 +240,14 @@ func serveStatsPage(args []string, stats *serveStats) httprouter.Handle {
} }
if StatisticsFile != "" { if StatisticsFile != "" {
stats.ExportFile(StatisticsFile) stats.exportFile(StatisticsFile)
} }
} }
} }
func registerStatsHandlers(mux *httprouter.Router, args []string, stats *serveStats) { func registerStatsHandlers(mux *httprouter.Router, args []string, stats *serveStats) {
if StatisticsFile != "" {
stats.ImportFile(StatisticsFile)
gracefulShutdown := make(chan os.Signal, 1)
signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-gracefulShutdown
stats.ExportFile(StatisticsFile)
os.Exit(0)
}()
mux.GET("/stats", serveStatsPage(args, stats)) mux.GET("/stats", serveStatsPage(args, stats))
if PageLength != 0 { if PageLength != 0 {
mux.GET("/stats/:page", serveStatsPage(args, stats)) mux.GET("/stats/:page", serveStatsPage(args, stats))
} }
} }
}

View File

@ -12,12 +12,14 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"os/signal"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
@ -405,6 +407,29 @@ func ServePage(args []string) error {
} }
if Statistics { if Statistics {
if StatisticsFile != "" {
StatisticsFile, err = normalizePath(StatisticsFile)
if err != nil {
return err
}
err := stats.importFile(StatisticsFile)
if err != nil {
return err
}
gracefulShutdown := make(chan os.Signal, 1)
signal.Notify(gracefulShutdown, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-gracefulShutdown
stats.exportFile(StatisticsFile)
os.Exit(0)
}()
}
registerStatsHandlers(mux, args, stats) registerStatsHandlers(mux, args, stats)
} }