gql dir ls
This commit is contained in:
parent
6a1e338af4
commit
e576e62599
23 changed files with 1671 additions and 138 deletions
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
|
@ -14,20 +15,21 @@ import (
|
|||
"time"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/src/config"
|
||||
"git.kmsign.ru/royalcat/tstor/src/delivery"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/datastorage"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/service"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/store"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
"git.kmsign.ru/royalcat/tstor/src/telemetry"
|
||||
"github.com/urfave/cli/v2"
|
||||
wnfs "github.com/willscott/go-nfs"
|
||||
|
||||
_ "git.kmsign.ru/royalcat/tstor/pkg/rlog"
|
||||
"git.kmsign.ru/royalcat/tstor/src/export/fuse"
|
||||
"git.kmsign.ru/royalcat/tstor/src/export/httpfs"
|
||||
"git.kmsign.ru/royalcat/tstor/src/export/nfs"
|
||||
"git.kmsign.ru/royalcat/tstor/src/export/webdav"
|
||||
"git.kmsign.ru/royalcat/tstor/src/http"
|
||||
dlog "git.kmsign.ru/royalcat/tstor/src/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -65,7 +67,17 @@ func run(configPath string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("error loading configuration: %w", err)
|
||||
}
|
||||
dlog.Load(&conf.Log)
|
||||
// dlog.Load(&conf.Log)
|
||||
|
||||
if conf.OtelHttp != "" {
|
||||
ctx := context.Background()
|
||||
client, err := telemetry.Setup(ctx, conf.OtelHttp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer client.Shutdown(ctx)
|
||||
}
|
||||
|
||||
log := slog.Default().With("component", "run")
|
||||
|
||||
|
@ -113,7 +125,10 @@ func run(configPath string) error {
|
|||
c.AddDhtNodes(conf.TorrentClient.DHTNodes)
|
||||
defer c.Close()
|
||||
|
||||
ts := service.NewService(conf.SourceDir, c, st, excludedFilesStore, infoBytesStore, conf.TorrentClient.AddTimeout, conf.TorrentClient.ReadTimeout)
|
||||
ts, err := service.NewService(conf.SourceDir, conf.TorrentClient, c, st, excludedFilesStore, infoBytesStore, conf.TorrentClient.AddTimeout, conf.TorrentClient.ReadTimeout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating service: %w", err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(conf.SourceDir, 0744); err != nil {
|
||||
return fmt.Errorf("error creating data folder: %w", err)
|
||||
|
@ -226,9 +241,9 @@ func run(configPath string) error {
|
|||
}()
|
||||
|
||||
go func() {
|
||||
logFilename := filepath.Join(conf.Log.Path, dlog.FileName)
|
||||
logFilename := filepath.Join(conf.Log.Path, "logs")
|
||||
|
||||
err := http.New(nil, service.NewStats(), ts, logFilename, conf)
|
||||
err := delivery.New(nil, service.NewStats(), ts, sfs, logFilename, conf)
|
||||
if err != nil {
|
||||
log.Error("error initializing HTTP server", "error", err)
|
||||
}
|
||||
|
|
46
go.mod
46
go.mod
|
@ -5,7 +5,9 @@ go 1.22.1
|
|||
require (
|
||||
github.com/99designs/gqlgen v0.17.43
|
||||
github.com/RoaringBitmap/roaring v1.2.3
|
||||
github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444
|
||||
github.com/agoda-com/opentelemetry-go/otelslog v0.1.1
|
||||
github.com/agoda-com/opentelemetry-logs-go v0.3.0
|
||||
github.com/anacrolix/dht/v2 v2.21.1
|
||||
github.com/anacrolix/log v0.14.6-0.20231202035202-ed7a02cad0b4
|
||||
github.com/anacrolix/missinggo/v2 v2.7.3
|
||||
github.com/anacrolix/torrent v1.55.0
|
||||
|
@ -25,14 +27,22 @@ require (
|
|||
github.com/knadh/koanf/providers/file v0.1.0
|
||||
github.com/knadh/koanf/providers/structs v0.1.0
|
||||
github.com/knadh/koanf/v2 v2.0.1
|
||||
github.com/lmittmann/tint v1.0.4
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2
|
||||
github.com/royalcat/kv v0.0.0-20240316134516-1bb692abce73
|
||||
github.com/ravilushqa/otelgqlgen v0.15.0
|
||||
github.com/royalcat/kv v0.0.0-20240318203654-181645f85b10
|
||||
github.com/rs/zerolog v1.32.0
|
||||
github.com/samber/slog-multi v1.0.2
|
||||
github.com/samber/slog-zerolog v1.0.0
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/urfave/cli/v2 v2.27.0
|
||||
github.com/vektah/gqlparser/v2 v2.5.11
|
||||
github.com/willscott/go-nfs v0.0.2
|
||||
go.opentelemetry.io/otel v1.24.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.46.0
|
||||
go.opentelemetry.io/otel/sdk v1.24.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.24.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b
|
||||
golang.org/x/net v0.19.0
|
||||
|
@ -57,11 +67,13 @@ require (
|
|||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.2 // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
|
@ -75,20 +87,21 @@ require (
|
|||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-llsqlite/adapter v0.0.0-20230927005056-7f5ce7f0c916 // indirect
|
||||
github.com/go-llsqlite/crawshaw v0.4.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.0 // indirect
|
||||
github.com/golang/glog v1.1.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/flatbuffers v2.0.8+incompatible // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
|
@ -96,7 +109,9 @@ require (
|
|||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/knadh/koanf/maps v0.1.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
|
@ -125,12 +140,17 @@ require (
|
|||
github.com/pion/webrtc/v3 v3.1.42 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.18.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.0 // indirect
|
||||
github.com/prometheus/common v0.45.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect
|
||||
github.com/sosodev/duration v1.1.0 // indirect
|
||||
github.com/samber/lo v1.38.1 // indirect
|
||||
github.com/sosodev/duration v1.2.0 // indirect
|
||||
github.com/tidwall/btree v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
|
@ -139,18 +159,24 @@ require (
|
|||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.8.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.8.0 // indirect
|
||||
go.opentelemetry.io/contrib v1.21.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/grpc v1.61.1 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.22.3 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
|
|
108
go.sum
108
go.sum
|
@ -34,6 +34,10 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
|
|||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/agoda-com/opentelemetry-go/otelslog v0.1.1 h1:6nV8PZCzySHuh9kP/HZ2OJqGucwQiM+yZRugKDvtzj4=
|
||||
github.com/agoda-com/opentelemetry-go/otelslog v0.1.1/go.mod h1:CSc0veIcY/HsIfH7l5PGtIpRvBttk09QUQlweVkD2PI=
|
||||
github.com/agoda-com/opentelemetry-logs-go v0.3.0 h1:d2lMVUfCDeLzVgTxMeSU8IWaMXjwD4sVKigEZBGwcsw=
|
||||
github.com/agoda-com/opentelemetry-logs-go v0.3.0/go.mod h1:k3QR1O5AOl+dFC7pkrK9wWmoD72jjDONPFHi9dAgLJc=
|
||||
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0=
|
||||
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k=
|
||||
github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk=
|
||||
|
@ -48,8 +52,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
|||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U=
|
||||
github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
|
||||
github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444 h1:8V0K09lrGoeT2KRJNOtspA7q+OMxGwQqK/Ug0IiaaRE=
|
||||
github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444/go.mod h1:MctKM1HS5YYDb3F30NGJxLE+QPuqWoT5ReW/4jt8xew=
|
||||
github.com/anacrolix/dht/v2 v2.21.1 h1:s1rKkfLLcmBHKv4v/mtMkIeHIEptzEFiB6xVu54+5/o=
|
||||
github.com/anacrolix/dht/v2 v2.21.1/go.mod h1:SDGC+sEs1pnO2sJGYuhvIis7T8749dDHNfcjtdH4e3g=
|
||||
github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.1.0/go.mod h1:My7T5oSqVfEn4MD4Meczkw/f5lSIndGAKu/0SM/rkf4=
|
||||
|
@ -115,6 +119,7 @@ github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d h1:2qVb9bs
|
|||
github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/billziss-gh/cgofuse v1.5.0 h1:kH516I/s+Ab4diL/Y/ayFeUjjA8ey+JK12xDfBf4HEs=
|
||||
github.com/billziss-gh/cgofuse v1.5.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
|
||||
|
@ -134,6 +139,8 @@ github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8/go.mod h1:spo1JLcs67
|
|||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
|
@ -148,6 +155,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
|||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -212,8 +220,8 @@ github.com/go-llsqlite/crawshaw v0.4.0/go.mod h1:/YJdV7uBQaYDE0fwe4z3wwJIZBJxdYz
|
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
|
@ -233,6 +241,7 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
|
|||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
|
@ -240,8 +249,8 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
|||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
||||
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
|
||||
github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
|
||||
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
|
@ -284,8 +293,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
|
@ -306,6 +315,8 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51
|
|||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
|
@ -367,12 +378,16 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
|
||||
github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
|
@ -465,21 +480,31 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
|
|||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
|
||||
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
|
||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
|
||||
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 h1:UVArwN/wkKjMVhh2EQGC0tEc1+FqiLlvYXY5mQ2f8Wg=
|
||||
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93/go.mod h1:Nfe4efndBz4TibWycNE+lqyJZiMX4ycx+QKV8Ta0f/o=
|
||||
github.com/ravilushqa/otelgqlgen v0.15.0 h1:U85nrlweMXTGaMChUViYM39/MXBZVeVVlpuHq+6eECQ=
|
||||
github.com/ravilushqa/otelgqlgen v0.15.0/go.mod h1:o+1Eju0VySmgq2BP8Vupz2YrN21Bj7D7imBqu3m2uB8=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
|
@ -489,17 +514,24 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
|||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/royalcat/kv v0.0.0-20240316120131-b774a9bff6f7 h1:fmBTD0RaTvWbd6KrgLVXSDUJ4dWTPOFUdkdHp+kYvRM=
|
||||
github.com/royalcat/kv v0.0.0-20240316120131-b774a9bff6f7/go.mod h1:Ff0Z/r1H3ojacpEe8SashMKJx6YCIhWrYtpdV8Y/k3A=
|
||||
github.com/royalcat/kv v0.0.0-20240316134516-1bb692abce73 h1:zeFE8Nx11oD6In+f+VDYwGH72t7NV6L5dqaNbDIhB1E=
|
||||
github.com/royalcat/kv v0.0.0-20240316134516-1bb692abce73/go.mod h1:Ff0Z/r1H3ojacpEe8SashMKJx6YCIhWrYtpdV8Y/k3A=
|
||||
github.com/royalcat/kv v0.0.0-20240318203654-181645f85b10 h1:8vwpCzvVqzNzkYRH9kA3GV5fkWs+8s0jdxtGvswL/MU=
|
||||
github.com/royalcat/kv v0.0.0-20240318203654-181645f85b10/go.mod h1:Ff0Z/r1H3ojacpEe8SashMKJx6YCIhWrYtpdV8Y/k3A=
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs=
|
||||
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
|
||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/samber/slog-multi v1.0.2 h1:6BVH9uHGAsiGkbbtQgAOQJMpKgV8unMrHhhJaw+X1EQ=
|
||||
github.com/samber/slog-multi v1.0.2/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo=
|
||||
github.com/samber/slog-zerolog v1.0.0 h1:YpRy0xux1uJr0Ng3wrEjv9nyvb4RAoNqkS611UjzeG8=
|
||||
github.com/samber/slog-zerolog v1.0.0/go.mod h1:N2/g/mNGRY1zqsydIYE0uKipSSFsPDjytoVkRnZ0Jp0=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
|
@ -511,8 +543,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
|||
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs=
|
||||
github.com/sosodev/duration v1.1.0 h1:kQcaiGbJaIsRqgQy7VGlZrVw1giWO+lDoX3MCPnpVO4=
|
||||
github.com/sosodev/duration v1.1.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
|
||||
github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us=
|
||||
github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -571,10 +603,28 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg=
|
||||
go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
|
||||
go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
|
||||
go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
|
||||
go.opentelemetry.io/contrib v1.21.1 h1:/U05KZ31iqMqAowhtW10cDPAViNY0tnpAacUgYBmuj8=
|
||||
go.opentelemetry.io/contrib v1.21.1/go.mod h1:usW9bPlrjHiJFbK0a6yK/M5wNHs3nLmtrT3vzhoD3co=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.46.0 h1:I8WIFXR351FoLJYuloU4EgXbtNX2URfU/85pUPheIEQ=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.46.0/go.mod h1:ztwVUHe5DTR/1v7PeuGRnU5Bbd4QKYwApWmuutKsJSs=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.24.0 h1:yyMQrPzF+k88/DbH7o4FMAs80puqd+9osbiBrJrz/w8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.24.0/go.mod h1:I6Y5FjH6rvEnTTAYQz3Mmv2kl6Ek5IIrmwTLqMrrOE0=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
|
||||
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
|
||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
|
@ -718,6 +768,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -725,8 +776,9 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -811,6 +863,12 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx
|
|||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos=
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
|
@ -821,6 +879,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
|||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY=
|
||||
google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -833,8 +893,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
type Query {
|
||||
torrents(filter: TorrentsFilter, pagination: Pagination): [Torrent!]!
|
||||
fsListDir(path: String!): [DirEntry!]!
|
||||
}
|
||||
|
||||
input TorrentsFilter {
|
||||
|
@ -40,4 +41,4 @@ input DateTimeFilter @oneOf {
|
|||
|
||||
input BooleanFilter @oneOf {
|
||||
eq: Boolean
|
||||
}
|
||||
}
|
||||
|
|
26
graphql/types/fs.graphql
Normal file
26
graphql/types/fs.graphql
Normal file
|
@ -0,0 +1,26 @@
|
|||
interface DirEntry {
|
||||
name: String!
|
||||
}
|
||||
|
||||
type Dir implements DirEntry {
|
||||
name: String!
|
||||
}
|
||||
|
||||
type File implements DirEntry {
|
||||
name: String!
|
||||
size: Int!
|
||||
}
|
||||
|
||||
type ResolverFS implements DirEntry {
|
||||
name: String!
|
||||
}
|
||||
|
||||
type TorrentFS implements DirEntry {
|
||||
name: String!
|
||||
torrent: Torrent!
|
||||
}
|
||||
|
||||
type ArchiveFS implements DirEntry {
|
||||
name: String!
|
||||
size: Int!
|
||||
}
|
70
pkg/rlog/rlog.go
Normal file
70
pkg/rlog/rlog.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package rlog
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
slogmulti "github.com/samber/slog-multi"
|
||||
slogzerolog "github.com/samber/slog-zerolog"
|
||||
)
|
||||
|
||||
const errKey = "error"
|
||||
const labelGroupKey = "labelGroup"
|
||||
|
||||
var zl = zerolog.New(&zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
|
||||
var handlers = []slog.Handler{
|
||||
slogzerolog.Option{Logger: &zl}.NewZerologHandler(),
|
||||
}
|
||||
|
||||
var defaultLogger = slog.New(slogmulti.Fanout(handlers...))
|
||||
|
||||
func init() {
|
||||
slog.SetDefault(defaultLogger)
|
||||
}
|
||||
|
||||
func AddHandler(nh slog.Handler) {
|
||||
handlers = append(handlers, nh)
|
||||
defaultLogger = slog.New(slogmulti.Fanout(handlers...))
|
||||
slog.SetDefault(defaultLogger)
|
||||
}
|
||||
|
||||
func ComponentLog(name string) *slog.Logger {
|
||||
return defaultLogger.With(slog.String("component", name))
|
||||
}
|
||||
|
||||
func ServiceLog(name string) *slog.Logger {
|
||||
return ComponentLog("service/" + name)
|
||||
}
|
||||
|
||||
func FunctionLog(log *slog.Logger, name string) *slog.Logger {
|
||||
return log.With(slog.String("function", name))
|
||||
}
|
||||
|
||||
func EndpointLog(log *slog.Logger, name string) *slog.Logger {
|
||||
return log.With(slog.String("endpoint", name))
|
||||
}
|
||||
|
||||
func Err(err error) slog.Attr {
|
||||
return slog.Attr{Key: errKey, Value: fmtErr(err)}
|
||||
}
|
||||
|
||||
func Label(args ...any) slog.Attr {
|
||||
return slog.Group(labelGroupKey, args...)
|
||||
}
|
||||
|
||||
// fmtErr returns a slog.GroupValue with keys "msg" and "trace". If the error
|
||||
// does not implement interface { StackTrace() errors.StackTrace }, the "trace"
|
||||
// key is omitted.
|
||||
func fmtErr(err error) slog.Value {
|
||||
if err == nil {
|
||||
return slog.AnyValue(nil)
|
||||
}
|
||||
|
||||
var groupValues []slog.Attr
|
||||
|
||||
groupValues = append(groupValues, slog.String("msg", err.Error()))
|
||||
|
||||
return slog.GroupValue(groupValues...)
|
||||
}
|
|
@ -8,6 +8,8 @@ type Config struct {
|
|||
Log Log `koanf:"log"`
|
||||
|
||||
SourceDir string `koanf:"source_dir"`
|
||||
|
||||
OtelHttp string `koanf:"otel_http"`
|
||||
}
|
||||
|
||||
type WebUi struct {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package http
|
||||
package delivery
|
||||
|
||||
import (
|
||||
"bytes"
|
File diff suppressed because it is too large
Load diff
|
@ -9,12 +9,25 @@ import (
|
|||
"github.com/anacrolix/torrent"
|
||||
)
|
||||
|
||||
type DirEntry interface {
|
||||
IsDirEntry()
|
||||
GetName() string
|
||||
}
|
||||
|
||||
type Progress interface {
|
||||
IsProgress()
|
||||
GetCurrent() int64
|
||||
GetTotal() int64
|
||||
}
|
||||
|
||||
type ArchiveFs struct {
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
func (ArchiveFs) IsDirEntry() {}
|
||||
func (this ArchiveFs) GetName() string { return this.Name }
|
||||
|
||||
type BooleanFilter struct {
|
||||
Eq *bool `json:"eq,omitempty"`
|
||||
}
|
||||
|
@ -27,10 +40,25 @@ type DateTimeFilter struct {
|
|||
Lte *time.Time `json:"lte,omitempty"`
|
||||
}
|
||||
|
||||
type Dir struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (Dir) IsDirEntry() {}
|
||||
func (this Dir) GetName() string { return this.Name }
|
||||
|
||||
type DownloadTorrentResponse struct {
|
||||
Task *Task `json:"task,omitempty"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
func (File) IsDirEntry() {}
|
||||
func (this File) GetName() string { return this.Name }
|
||||
|
||||
type IntFilter struct {
|
||||
Eq *int64 `json:"eq,omitempty"`
|
||||
Gt *int64 `json:"gt,omitempty"`
|
||||
|
@ -51,6 +79,13 @@ type Pagination struct {
|
|||
type Query struct {
|
||||
}
|
||||
|
||||
type ResolverFs struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (ResolverFs) IsDirEntry() {}
|
||||
func (this ResolverFs) GetName() string { return this.Name }
|
||||
|
||||
type Schema struct {
|
||||
Query *Query `json:"query,omitempty"`
|
||||
Mutation *Mutation `json:"mutation,omitempty"`
|
||||
|
@ -81,6 +116,14 @@ type Torrent struct {
|
|||
T *controller.Torrent `json:"-"`
|
||||
}
|
||||
|
||||
type TorrentFs struct {
|
||||
Name string `json:"name"`
|
||||
Torrent *Torrent `json:"torrent"`
|
||||
}
|
||||
|
||||
func (TorrentFs) IsDirEntry() {}
|
||||
func (this TorrentFs) GetName() string { return this.Name }
|
||||
|
||||
type TorrentFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size int64 `json:"size"`
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql"
|
||||
"git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
)
|
||||
|
||||
// Torrents is the resolver for the torrents field.
|
||||
|
@ -63,6 +64,42 @@ func (r *queryResolver) Torrents(ctx context.Context, filter *model.TorrentsFilt
|
|||
return tr, nil
|
||||
}
|
||||
|
||||
// FsListDir is the resolver for the fsListDir field.
|
||||
func (r *queryResolver) FsListDir(ctx context.Context, path string) ([]model.DirEntry, error) {
|
||||
entries, err := r.VFS.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := []model.DirEntry{}
|
||||
for _, e := range entries {
|
||||
switch e.(type) {
|
||||
case *vfs.TorrentFs:
|
||||
e := e.(*vfs.TorrentFs)
|
||||
out = append(out, model.TorrentFs{
|
||||
Name: e.Name(),
|
||||
Torrent: model.MapTorrent(e.Torrent),
|
||||
})
|
||||
default:
|
||||
if e.IsDir() {
|
||||
out = append(out, model.Dir{Name: e.Name()})
|
||||
} else {
|
||||
info, err := e.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, model.File{
|
||||
Name: e.Name(),
|
||||
Size: info.Size(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Query returns graph.QueryResolver implementation.
|
||||
func (r *Resolver) Query() graph.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package resolver
|
||||
|
||||
import "git.kmsign.ru/royalcat/tstor/src/host/service"
|
||||
import (
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/service"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
)
|
||||
|
||||
// This file will not be regenerated automatically.
|
||||
//
|
||||
|
@ -8,4 +11,5 @@ import "git.kmsign.ru/royalcat/tstor/src/host/service"
|
|||
|
||||
type Resolver struct {
|
||||
Service *service.Service
|
||||
VFS vfs.Filesystem
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package http
|
||||
package delivery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -7,15 +7,15 @@ import (
|
|||
|
||||
"git.kmsign.ru/royalcat/tstor"
|
||||
"git.kmsign.ru/royalcat/tstor/src/config"
|
||||
"git.kmsign.ru/royalcat/tstor/src/delivery"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/service"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
"github.com/anacrolix/missinggo/v2/filecache"
|
||||
"github.com/gin-contrib/pprof"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shurcooL/httpfs/html/vfstemplate"
|
||||
)
|
||||
|
||||
func New(fc *filecache.Cache, ss *service.Stats, s *service.Service, logPath string, cfg *config.Config) error {
|
||||
func New(fc *filecache.Cache, ss *service.Stats, s *service.Service, vfs vfs.Filesystem, logPath string, cfg *config.Config) error {
|
||||
log := slog.With()
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
@ -40,18 +40,16 @@ func New(fc *filecache.Cache, ss *service.Stats, s *service.Service, logPath str
|
|||
// r.GET("/routes", routesHandler(ss))
|
||||
r.GET("/logs", logsHandler)
|
||||
r.GET("/servers", serversFoldersHandler())
|
||||
r.Any("/graphql", gin.WrapH(delivery.GraphQLHandler(s)))
|
||||
r.Any("/graphql", gin.WrapH(GraphQLHandler(s, vfs)))
|
||||
|
||||
api := r.Group("/api")
|
||||
{
|
||||
api.GET("/log", apiLogHandler(logPath))
|
||||
api.GET("/status", apiStatusHandler(fc, ss))
|
||||
// api.GET("/servers", apiServersHandler(tss))
|
||||
|
||||
// api.GET("/routes", apiRoutesHandler(ss))
|
||||
// api.POST("/routes/:route/torrent", apiAddTorrentHandler(s))
|
||||
// api.DELETE("/routes/:route/torrent/:torrent_hash", apiDelTorrentHandler(s))
|
||||
|
||||
}
|
||||
|
||||
log.Info("starting webserver", "host", fmt.Sprintf("%s:%d", cfg.WebUi.IP, cfg.WebUi.Port))
|
|
@ -1,4 +1,4 @@
|
|||
package http
|
||||
package delivery
|
||||
|
||||
type RouteAdd struct {
|
||||
Magnet string `json:"magnet" binding:"required"`
|
|
@ -6,23 +6,26 @@ import (
|
|||
graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql"
|
||||
"git.kmsign.ru/royalcat/tstor/src/delivery/graphql/resolver"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/service"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler/extension"
|
||||
"github.com/99designs/gqlgen/graphql/handler/lru"
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/ravilushqa/otelgqlgen"
|
||||
)
|
||||
|
||||
func GraphQLHandler(service *service.Service) http.Handler {
|
||||
func GraphQLHandler(service *service.Service, vfs vfs.Filesystem) http.Handler {
|
||||
graphqlHandler := handler.NewDefaultServer(
|
||||
graph.NewExecutableSchema(
|
||||
graph.Config{
|
||||
Resolvers: &resolver.Resolver{Service: service},
|
||||
Resolvers: &resolver.Resolver{Service: service, VFS: vfs},
|
||||
Directives: graph.DirectiveRoot{
|
||||
OneOf: graph.OneOf,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
graphqlHandler.AddTransport(&transport.POST{})
|
||||
graphqlHandler.AddTransport(&transport.Websocket{})
|
||||
graphqlHandler.AddTransport(&transport.SSE{})
|
||||
|
@ -30,6 +33,7 @@ func GraphQLHandler(service *service.Service) http.Handler {
|
|||
graphqlHandler.SetQueryCache(lru.New(1000))
|
||||
graphqlHandler.Use(extension.Introspection{})
|
||||
graphqlHandler.Use(extension.AutomaticPersistedQuery{Cache: lru.New(100)})
|
||||
graphqlHandler.Use(otelgqlgen.Middleware())
|
||||
|
||||
return graphqlHandler
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package http
|
||||
package delivery
|
||||
|
||||
import (
|
||||
"net/http"
|
|
@ -5,24 +5,33 @@ import (
|
|||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/src/config"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/controller"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/datastorage"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/store"
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
"go.uber.org/multierr"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/anacrolix/torrent/types"
|
||||
"github.com/anacrolix/torrent/types/infohash"
|
||||
"github.com/royalcat/kv"
|
||||
)
|
||||
|
||||
type DirAquire struct {
|
||||
Name string
|
||||
Hashes []infohash.T
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
c *torrent.Client
|
||||
excludedFiles *store.FilesMappings
|
||||
|
@ -35,11 +44,21 @@ type Service struct {
|
|||
Storage datastorage.DataStorage
|
||||
SourceDir string
|
||||
|
||||
dirsAquire kv.Store[string, DirAquire]
|
||||
|
||||
log *slog.Logger
|
||||
addTimeout, readTimeout int
|
||||
}
|
||||
|
||||
func NewService(sourceDir string, c *torrent.Client, storage datastorage.DataStorage, excludedFiles *store.FilesMappings, infoBytes *store.InfoBytes, addTimeout, readTimeout int) *Service {
|
||||
func NewService(sourceDir string, cfg config.TorrentClient, c *torrent.Client,
|
||||
storage datastorage.DataStorage, excludedFiles *store.FilesMappings, infoBytes *store.InfoBytes,
|
||||
addTimeout, readTimeout int,
|
||||
) (*Service, error) {
|
||||
dirsAcquire, err := kv.NewBadgerKV[string, DirAquire](path.Join(cfg.MetadataFolder, "dir-acquire"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Service{
|
||||
log: slog.With("component", "torrent-service"),
|
||||
c: c,
|
||||
|
@ -49,6 +68,7 @@ func NewService(sourceDir string, c *torrent.Client, storage datastorage.DataSto
|
|||
Storage: storage,
|
||||
SourceDir: sourceDir,
|
||||
torrentLoaded: make(chan struct{}),
|
||||
dirsAquire: dirsAcquire,
|
||||
// stats: newStats(), // TODO persistent
|
||||
addTimeout: addTimeout,
|
||||
readTimeout: readTimeout,
|
||||
|
@ -62,7 +82,7 @@ func NewService(sourceDir string, c *torrent.Client, storage datastorage.DataSto
|
|||
close(s.torrentLoaded)
|
||||
}()
|
||||
|
||||
return s
|
||||
return s, nil
|
||||
}
|
||||
|
||||
var _ vfs.FsFactory = (*Service)(nil).NewTorrentFs
|
||||
|
@ -109,17 +129,16 @@ func (s *Service) AddTorrent(ctx context.Context, f vfs.File) (*torrent.Torrent,
|
|||
if err != nil {
|
||||
infoBytes = nil
|
||||
} else {
|
||||
// for _, t := range s.c.Torrents() {
|
||||
// if t.Name() == info.BestName() && t.InfoHash() != spec.InfoHash {
|
||||
// <-t.GotInfo()
|
||||
// if !isTorrentCompatable(*t.Info(), info) {
|
||||
// return nil, fmt.Errorf(
|
||||
// "torrent with name '%s' not compatable existing infohash: %s, new: %s",
|
||||
// t.Name(), t.InfoHash().HexString(), spec.InfoHash.HexString(),
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
compatable, _, err := s.checkTorrentCompatable(ctx, spec.InfoHash, info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !compatable {
|
||||
return nil, fmt.Errorf(
|
||||
"torrent with name '%s' not compatable existing infohash: %s, new: %s",
|
||||
t.Name(), t.InfoHash().HexString(), spec.InfoHash.HexString(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
t, _ = s.c.AddTorrentOpt(torrent.AddTorrentOpts{
|
||||
|
@ -149,9 +168,67 @@ func (s *Service) AddTorrent(ctx context.Context, f vfs.File) (*torrent.Torrent,
|
|||
return t, nil
|
||||
}
|
||||
|
||||
func isTorrentCompatable(existingInfo, newInfo metainfo.Info) bool {
|
||||
existingFiles := slices.Clone(existingInfo.Files)
|
||||
newFiles := slices.Clone(newInfo.Files)
|
||||
func (s *Service) checkTorrentCompatable(ctx context.Context, ih infohash.T, info metainfo.Info) (compatable bool, tryLater bool, err error) {
|
||||
log := s.log.With("new-name", info.BestName(), "new-infohash", ih.String())
|
||||
|
||||
name := info.BestName()
|
||||
|
||||
aq, found, err := s.dirsAquire.Get(ctx, info.BestName())
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
if !found {
|
||||
err = s.dirsAquire.Set(ctx, name, DirAquire{
|
||||
Name: name,
|
||||
Hashes: slices.Compact([]infohash.T{ih}),
|
||||
})
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
log.Debug("acquiring was not found, so created")
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
if slices.Contains(aq.Hashes, ih) {
|
||||
log.Debug("hash already know to be compatable")
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
for _, existingTorrent := range s.c.Torrents() {
|
||||
if existingTorrent.Name() != name || existingTorrent.InfoHash() == ih {
|
||||
continue
|
||||
}
|
||||
|
||||
existingInfo := existingTorrent.Info()
|
||||
|
||||
existingFiles := slices.Clone(existingInfo.Files)
|
||||
newFiles := slices.Clone(info.Files)
|
||||
|
||||
if !s.checkTorrentFilesCompatable(aq, existingFiles, newFiles) {
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
aq.Hashes = slicesUnique(append(aq.Hashes, ih))
|
||||
err = s.dirsAquire.Set(ctx, aq.Name, aq)
|
||||
if err != nil {
|
||||
log.Warn("torrent not compatible")
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if slices.Contains(aq.Hashes, ih) {
|
||||
log.Debug("hash is compatable")
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
log.Debug("torrent with same name not found, try later")
|
||||
return false, true, nil
|
||||
}
|
||||
|
||||
func (s *Service) checkTorrentFilesCompatable(aq DirAquire, existingFiles, newFiles []metainfo.FileInfo) bool {
|
||||
log := s.log.With("name", aq.Name)
|
||||
|
||||
pathCmp := func(a, b metainfo.FileInfo) int {
|
||||
return slices.Compare(a.BestPath(), b.BestPath())
|
||||
|
@ -167,14 +244,45 @@ func isTorrentCompatable(existingInfo, newInfo metainfo.Info) bool {
|
|||
}
|
||||
|
||||
if len(newFiles) > len(existingFiles) {
|
||||
all := append(existingFiles, newFiles...)
|
||||
slices.SortStableFunc(all, pathCmp)
|
||||
slices.CompactFunc(all, func(fi1, fi2 metainfo.FileInfo) bool {
|
||||
return slices.Equal(fi1.BestPath(), fi2.BestPath()) && fi1.Length == fi2.Length
|
||||
})
|
||||
type fileInfo struct {
|
||||
Path string
|
||||
Length int64
|
||||
}
|
||||
mapInfo := func(fi metainfo.FileInfo) fileInfo {
|
||||
return fileInfo{
|
||||
Path: strings.Join(fi.BestPath(), "/"),
|
||||
Length: fi.Length,
|
||||
}
|
||||
}
|
||||
|
||||
existingFiles := apply(existingFiles, mapInfo)
|
||||
newFiles := apply(newFiles, mapInfo)
|
||||
|
||||
for _, n := range newFiles {
|
||||
if slices.Contains(existingFiles, n) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, e := range existingFiles {
|
||||
if e.Path == n.Path && e.Length != n.Length {
|
||||
log.Warn("torrents not compatible, has files with different length", "path", n.Path, "existing-length", e.Length, "new-length", e.Length)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Service) getTorrentsByName(name string) []*torrent.Torrent {
|
||||
out := []*torrent.Torrent{}
|
||||
for _, t := range s.c.Torrents() {
|
||||
if t.Name() == name {
|
||||
out = append(out, t)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func isValidInfoHashBytes(d []byte) bool {
|
||||
|
@ -188,12 +296,17 @@ func (s *Service) NewTorrentFs(f vfs.File) (vfs.Filesystem, error) {
|
|||
defer cancel()
|
||||
defer f.Close()
|
||||
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t, err := s.AddTorrent(ctx, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vfs.NewTorrentFs(controller.NewTorrent(t, s.excludedFiles), s.readTimeout), nil
|
||||
return vfs.NewTorrentFs(info.Name(), controller.NewTorrent(t, s.excludedFiles), s.readTimeout), nil
|
||||
}
|
||||
|
||||
func (s *Service) Stats() (*Stats, error) {
|
||||
|
@ -252,3 +365,20 @@ func (s *Service) GetTorrent(infohashHex string) (*controller.Torrent, error) {
|
|||
|
||||
return controller.NewTorrent(t, s.excludedFiles), nil
|
||||
}
|
||||
|
||||
func slicesUnique[S ~[]E, E comparable](in S) S {
|
||||
m := map[E]struct{}{}
|
||||
for _, v := range in {
|
||||
m[v] = struct{}{}
|
||||
}
|
||||
|
||||
return maps.Keys(m)
|
||||
}
|
||||
|
||||
func apply[I, O any](in []I, f func(e I) O) []O {
|
||||
out := []O{}
|
||||
for _, v := range in {
|
||||
out = append(out, f(v))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ var ArchiveFactories = map[string]FsFactory{
|
|||
|
||||
type archiveLoader func(r iio.Reader, size int64) (map[string]*archiveFile, error)
|
||||
|
||||
var _ Filesystem = &archive{}
|
||||
var _ Filesystem = &ArchiveFS{}
|
||||
|
||||
type archive struct {
|
||||
type ArchiveFS struct {
|
||||
name string
|
||||
|
||||
r iio.Reader
|
||||
|
@ -52,8 +52,8 @@ type archive struct {
|
|||
files func() (map[string]File, error)
|
||||
}
|
||||
|
||||
func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *archive {
|
||||
return &archive{
|
||||
func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *ArchiveFS {
|
||||
return &ArchiveFS{
|
||||
name: name,
|
||||
r: r,
|
||||
size: size,
|
||||
|
@ -94,11 +94,11 @@ func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *ar
|
|||
}
|
||||
|
||||
// Unlink implements Filesystem.
|
||||
func (a *archive) Unlink(filename string) error {
|
||||
func (a *ArchiveFS) Unlink(filename string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (a *archive) Open(filename string) (File, error) {
|
||||
func (a *ArchiveFS) Open(filename string) (File, error) {
|
||||
files, err := a.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -107,7 +107,7 @@ func (a *archive) Open(filename string) (File, error) {
|
|||
return getFile(files, filename)
|
||||
}
|
||||
|
||||
func (fs *archive) ReadDir(path string) ([]fs.DirEntry, error) {
|
||||
func (fs *ArchiveFS) ReadDir(path string) ([]fs.DirEntry, error) {
|
||||
files, err := fs.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -117,7 +117,7 @@ func (fs *archive) ReadDir(path string) ([]fs.DirEntry, error) {
|
|||
}
|
||||
|
||||
// Stat implements Filesystem.
|
||||
func (afs *archive) Stat(filename string) (fs.FileInfo, error) {
|
||||
func (afs *ArchiveFS) Stat(filename string) (fs.FileInfo, error) {
|
||||
files, err := afs.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -51,7 +51,21 @@ func (r *ResolveFS) ReadDir(dir string) ([]fs.DirEntry, error) {
|
|||
out := make([]fs.DirEntry, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
if r.resolver.isNestedFs(e.Name()) {
|
||||
out = append(out, newDirInfo(e.Name()))
|
||||
filepath := path.Join(dir, e.Name())
|
||||
file, err := r.Open(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nfs, err := r.resolver.nestedFs(filepath, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if e, ok := nfs.(fs.DirEntry); ok {
|
||||
out = append(out, e)
|
||||
} else {
|
||||
out = append(out, newDirInfo(e.Name()))
|
||||
}
|
||||
} else {
|
||||
out = append(out, e)
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ func TestResolver(t *testing.T) {
|
|||
require.NoError(err)
|
||||
require.Equal("/f1.rar", fsPath)
|
||||
require.Equal("/f2.rar", nestedFsPath)
|
||||
require.IsType(&archive{}, nestedFs)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
})
|
||||
t.Run("root", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -123,7 +123,7 @@ func TestResolver(t *testing.T) {
|
|||
require.NoError(err)
|
||||
require.Equal("/f1.rar", fsPath)
|
||||
require.Equal("/", nestedFsPath)
|
||||
require.IsType(&archive{}, nestedFs)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
})
|
||||
t.Run("inside folder", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -134,7 +134,7 @@ func TestResolver(t *testing.T) {
|
|||
return &Dummy{}, nil
|
||||
})
|
||||
require.NoError(err)
|
||||
require.IsType(&archive{}, nestedFs)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
require.Equal("/test1/f1.rar", fsPath)
|
||||
require.Equal("/", nestedFsPath)
|
||||
})
|
||||
|
|
|
@ -21,8 +21,10 @@ import (
|
|||
var _ Filesystem = &TorrentFs{}
|
||||
|
||||
type TorrentFs struct {
|
||||
mu sync.Mutex
|
||||
c *controller.Torrent
|
||||
name string
|
||||
|
||||
mu sync.Mutex
|
||||
Torrent *controller.Torrent
|
||||
|
||||
readTimeout int
|
||||
|
||||
|
@ -31,14 +33,37 @@ type TorrentFs struct {
|
|||
resolver *resolver
|
||||
}
|
||||
|
||||
func NewTorrentFs(c *controller.Torrent, readTimeout int) *TorrentFs {
|
||||
func NewTorrentFs(name string, c *controller.Torrent, readTimeout int) *TorrentFs {
|
||||
return &TorrentFs{
|
||||
c: c,
|
||||
name: name,
|
||||
Torrent: c,
|
||||
readTimeout: readTimeout,
|
||||
resolver: newResolver(ArchiveFactories),
|
||||
}
|
||||
}
|
||||
|
||||
var _ fs.DirEntry = (*TorrentFs)(nil)
|
||||
|
||||
// Name implements fs.DirEntry.
|
||||
func (tfs *TorrentFs) Name() string {
|
||||
return tfs.name
|
||||
}
|
||||
|
||||
// Info implements fs.DirEntry.
|
||||
func (tfs *TorrentFs) Info() (fs.FileInfo, error) {
|
||||
return newDirInfo(tfs.name), nil
|
||||
}
|
||||
|
||||
// IsDir implements fs.DirEntry.
|
||||
func (tfs *TorrentFs) IsDir() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Type implements fs.DirEntry.
|
||||
func (tfs *TorrentFs) Type() fs.FileMode {
|
||||
return fs.ModeDir
|
||||
}
|
||||
|
||||
func (fs *TorrentFs) files() (map[string]File, error) {
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
|
@ -47,7 +72,7 @@ func (fs *TorrentFs) files() (map[string]File, error) {
|
|||
return fs.filesCache, nil
|
||||
}
|
||||
|
||||
files, err := fs.c.Files(context.Background())
|
||||
files, err := fs.Torrent.Files(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -65,8 +90,8 @@ func (fs *TorrentFs) files() (map[string]File, error) {
|
|||
}
|
||||
|
||||
// TODO optional
|
||||
if len(fs.filesCache) == 1 && fs.resolver.isNestedFs(fs.c.Name()) {
|
||||
filepath := "/" + fs.c.Name()
|
||||
if len(fs.filesCache) == 1 && fs.resolver.isNestedFs(fs.Torrent.Name()) {
|
||||
filepath := "/" + fs.Torrent.Name()
|
||||
if file, ok := fs.filesCache[filepath]; ok {
|
||||
nestedFs, err := fs.resolver.nestedFs(filepath, file)
|
||||
if err != nil {
|
||||
|
@ -86,7 +111,7 @@ func (fs *TorrentFs) files() (map[string]File, error) {
|
|||
}
|
||||
|
||||
DEFAULT_DIR:
|
||||
rootDir := "/" + fs.c.Name() + "/"
|
||||
rootDir := "/" + fs.Torrent.Name() + "/"
|
||||
singleDir := true
|
||||
for k, _ := range fs.filesCache {
|
||||
if !strings.HasPrefix(k, rootDir) {
|
||||
|
@ -238,7 +263,7 @@ func (fs *TorrentFs) Unlink(name string) error {
|
|||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
return fs.c.ExcludeFile(context.Background(), tfile.file)
|
||||
return fs.Torrent.ExcludeFile(context.Background(), tfile.file)
|
||||
}
|
||||
|
||||
type reader interface {
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/src/config"
|
||||
"github.com/lmittmann/tint"
|
||||
)
|
||||
|
||||
const FileName = "tstor.log"
|
||||
|
||||
func Load(config *config.Log) {
|
||||
level := slog.LevelInfo
|
||||
if config.Debug {
|
||||
level = slog.LevelDebug
|
||||
}
|
||||
// func Load(config *config.Log) {
|
||||
// level := slog.LevelInfo
|
||||
// if config.Debug {
|
||||
// level = slog.LevelDebug
|
||||
// }
|
||||
|
||||
slog.SetDefault(slog.New(
|
||||
tint.NewHandler(os.Stdout, &tint.Options{
|
||||
Level: level,
|
||||
TimeFormat: time.Kitchen,
|
||||
// NoColor: !isatty.IsTerminal(os.Stdout.Fd()),
|
||||
}),
|
||||
))
|
||||
}
|
||||
// slog.SetDefault(slog.New(
|
||||
// tint.NewHandler(os.Stdout, &tint.Options{
|
||||
// Level: level,
|
||||
// TimeFormat: time.Kitchen,
|
||||
// // NoColor: !isatty.IsTerminal(os.Stdout.Fd()),
|
||||
// }),
|
||||
// ))
|
||||
// }
|
||||
|
||||
// func newRollingFile(config *config.Log) io.Writer {
|
||||
// if err := os.MkdirAll(config.Path, 0744); err != nil {
|
||||
|
|
126
src/telemetry/setup.go
Normal file
126
src/telemetry/setup.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
package telemetry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/pkg/rlog"
|
||||
"github.com/agoda-com/opentelemetry-go/otelslog"
|
||||
"github.com/agoda-com/opentelemetry-logs-go/exporters/otlp/otlplogs"
|
||||
"github.com/agoda-com/opentelemetry-logs-go/exporters/otlp/otlplogs/otlplogshttp"
|
||||
logsdk "github.com/agoda-com/opentelemetry-logs-go/sdk/logs"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||
"go.opentelemetry.io/otel/exporters/prometheus"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
log *slog.Logger
|
||||
|
||||
tracerProvider *trace.TracerProvider
|
||||
metricProvider *metric.MeterProvider
|
||||
loggerProvider *logsdk.LoggerProvider
|
||||
}
|
||||
|
||||
func (client *Client) Shutdown(ctx context.Context) {
|
||||
log := rlog.FunctionLog(client.log, "Shutdown")
|
||||
if client.metricProvider == nil {
|
||||
err := client.metricProvider.Shutdown(ctx)
|
||||
if err != nil {
|
||||
log.Error("error shutting down metric provider", rlog.Err(err))
|
||||
}
|
||||
}
|
||||
if client.tracerProvider == nil {
|
||||
err := client.tracerProvider.Shutdown(ctx)
|
||||
if err != nil {
|
||||
log.Error("error shutting down tracer provider", rlog.Err(err))
|
||||
}
|
||||
}
|
||||
if client.loggerProvider == nil {
|
||||
err := client.loggerProvider.Shutdown(ctx)
|
||||
if err != nil {
|
||||
log.Error("error shutting down logger provider", rlog.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const appName = "tstor"
|
||||
|
||||
func Setup(ctx context.Context, endpoint string) (*Client, error) {
|
||||
log := rlog.ComponentLog("telemetry")
|
||||
|
||||
client := &Client{
|
||||
log: log,
|
||||
}
|
||||
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(cause error) {
|
||||
log.Error("otel error", rlog.Err(cause))
|
||||
}))
|
||||
|
||||
hostName, _ := os.Hostname()
|
||||
|
||||
r, err := resource.Merge(
|
||||
resource.Default(),
|
||||
resource.NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.ServiceName(appName),
|
||||
semconv.HostName(hostName),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metricExporter, err := prometheus.New(prometheus.WithNamespace(appName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.metricProvider = metric.NewMeterProvider(
|
||||
metric.WithReader(metricExporter),
|
||||
metric.WithResource(r),
|
||||
)
|
||||
otel.SetMeterProvider(client.metricProvider)
|
||||
log.Info("prometheus metrics provider initialized")
|
||||
|
||||
traceExporter, err := otlptracehttp.New(ctx,
|
||||
otlptracehttp.WithEndpoint(endpoint),
|
||||
otlptracehttp.WithRetry(otlptracehttp.RetryConfig{
|
||||
Enabled: false,
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.tracerProvider = trace.NewTracerProvider(
|
||||
trace.WithBatcher(traceExporter),
|
||||
trace.WithResource(r),
|
||||
)
|
||||
otel.SetTracerProvider(client.tracerProvider)
|
||||
log.Info("otel tracing provider initialized")
|
||||
|
||||
logExporter, err := otlplogs.NewExporter(ctx,
|
||||
otlplogs.WithClient(
|
||||
otlplogshttp.NewClient(otlplogshttp.WithEndpoint(endpoint)),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.loggerProvider = logsdk.NewLoggerProvider(
|
||||
logsdk.WithBatcher(logExporter),
|
||||
logsdk.WithResource(r),
|
||||
)
|
||||
|
||||
rlog.AddHandler(otelslog.NewOtelHandler(client.loggerProvider,
|
||||
&otelslog.HandlerOptions{
|
||||
Level: slog.LevelDebug,
|
||||
}),
|
||||
)
|
||||
client.log = slog.Default()
|
||||
|
||||
return client, nil
|
||||
}
|
Loading…
Reference in a new issue