refactor: split go-pkg
This commit is contained in:
parent
d67d768c1e
commit
0f665d3484
|
@ -1,23 +1,23 @@
|
||||||
scalar Time
|
scalar Time
|
||||||
scalar Map
|
scalar Map
|
||||||
|
|
||||||
type Connection @goModel(model: "go.sour.is/ev/pkg/gql.Connection") {
|
type Connection @goModel(model: "go.sour.is/pkg/gql.Connection") {
|
||||||
paging: PageInfo!
|
paging: PageInfo!
|
||||||
edges: [Edge!]!
|
edges: [Edge!]!
|
||||||
}
|
}
|
||||||
input PageInput @goModel(model: "go.sour.is/ev/pkg/gql.PageInput") {
|
input PageInput @goModel(model: "go.sour.is/pkg/gql.PageInput") {
|
||||||
after: Int = 0
|
after: Int = 0
|
||||||
before: Int
|
before: Int
|
||||||
count: Int = 30
|
count: Int = 30
|
||||||
}
|
}
|
||||||
type PageInfo @goModel(model: "go.sour.is/ev/pkg/gql.PageInfo") {
|
type PageInfo @goModel(model: "go.sour.is/pkg/gql.PageInfo") {
|
||||||
next: Boolean!
|
next: Boolean!
|
||||||
prev: Boolean!
|
prev: Boolean!
|
||||||
|
|
||||||
begin: Int!
|
begin: Int!
|
||||||
end: Int!
|
end: Int!
|
||||||
}
|
}
|
||||||
interface Edge @goModel(model: "go.sour.is/ev/pkg/gql.Edge"){
|
interface Edge @goModel(model: "go.sour.is/pkg/gql.Edge"){
|
||||||
id: ID!
|
id: ID!
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
"github.com/99designs/gqlgen/graphql"
|
||||||
|
"go.sour.is/pkg/gql"
|
||||||
|
"go.sour.is/pkg/gql/resolver"
|
||||||
|
|
||||||
"go.sour.is/ev/app/msgbus"
|
"go.sour.is/ev/app/msgbus"
|
||||||
"go.sour.is/ev/app/salty"
|
"go.sour.is/ev/app/salty"
|
||||||
"go.sour.is/ev/internal/graph/generated"
|
"go.sour.is/ev/internal/graph/generated"
|
||||||
"go.sour.is/ev/pkg/es"
|
"go.sour.is/ev/pkg/es"
|
||||||
"go.sour.is/ev/pkg/gql"
|
|
||||||
"go.sour.is/ev/pkg/gql/resolver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
|
|
|
@ -14,24 +14,23 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"go.opentelemetry.io/otel/metric/instrument"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.opentelemetry.io/otel/metric/instrument/syncint64"
|
|
||||||
"go.opentelemetry.io/otel/metric/unit"
|
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/gql"
|
"go.sour.is/pkg/gql"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
es *ev.EventStore
|
es *ev.EventStore
|
||||||
|
|
||||||
m_gql_posts syncint64.Counter
|
m_gql_posts metric.Int64Counter
|
||||||
m_gql_post_added syncint64.Counter
|
m_gql_post_added metric.Int64Counter
|
||||||
m_gql_post_added_event syncint64.Counter
|
m_gql_post_added_event metric.Int64Counter
|
||||||
m_req_time syncint64.Histogram
|
m_req_time metric.Int64Histogram
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgbusResolver interface {
|
type MsgbusResolver interface {
|
||||||
|
@ -56,24 +55,24 @@ func New(ctx context.Context, es *ev.EventStore) (*service, error) {
|
||||||
svc := &service{es: es}
|
svc := &service{es: es}
|
||||||
|
|
||||||
var err, errs error
|
var err, errs error
|
||||||
svc.m_gql_posts, err = m.SyncInt64().Counter("msgbus_posts",
|
svc.m_gql_posts, err = m.Int64Counter("msgbus_posts",
|
||||||
instrument.WithDescription("msgbus graphql posts requests"),
|
metric.WithDescription("msgbus graphql posts requests"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_gql_post_added, err = m.SyncInt64().Counter("msgbus_post_added",
|
svc.m_gql_post_added, err = m.Int64Counter("msgbus_post_added",
|
||||||
instrument.WithDescription("msgbus graphql post added subcription requests"),
|
metric.WithDescription("msgbus graphql post added subcription requests"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_gql_post_added_event, err = m.SyncInt64().Counter("msgbus_post_event",
|
svc.m_gql_post_added_event, err = m.Int64Counter("msgbus_post_event",
|
||||||
instrument.WithDescription("msgbus graphql post added subscription events"),
|
metric.WithDescription("msgbus graphql post added subscription events"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_req_time, err = m.SyncInt64().Histogram("msgbus_request_time",
|
svc.m_req_time, err = m.Int64Histogram("msgbus_request_time",
|
||||||
instrument.WithDescription("msgbus graphql post added subscription events"),
|
metric.WithDescription("msgbus graphql post added subscription events"),
|
||||||
instrument.WithUnit(unit.Unit("ns")),
|
metric.WithUnit("ns"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/tj/go-semver"
|
"github.com/tj/go-semver"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
|
|
|
@ -7,8 +7,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/keys-pub/keys/json"
|
"github.com/keys-pub/keys/json"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/set"
|
||||||
"go.sour.is/ev/pkg/set"
|
|
||||||
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Time time.Time
|
type Time time.Time
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/set"
|
"go.sour.is/pkg/set"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
|
|
|
@ -19,10 +19,10 @@ import (
|
||||||
"github.com/oklog/ulid/v2"
|
"github.com/oklog/ulid/v2"
|
||||||
contentnegotiation "gitlab.com/jamietanna/content-negotiation-go"
|
contentnegotiation "gitlab.com/jamietanna/content-negotiation-go"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -656,7 +656,6 @@ func fnOrderByPeer(rq *Request) listPeer {
|
||||||
v := peers[i]
|
v := peers[i]
|
||||||
sort.Sort(v.Results)
|
sort.Sort(v.Results)
|
||||||
|
|
||||||
|
|
||||||
v.Name = v.Results[0].Name
|
v.Name = v.Results[0].Name
|
||||||
v.Country = v.Results[0].Country
|
v.Country = v.Results[0].Country
|
||||||
v.Latency = v.Results[0].Latency
|
v.Latency = v.Results[0].Latency
|
||||||
|
|
|
@ -10,9 +10,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/set"
|
"go.sour.is/pkg/set"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RefreshJob retrieves peer info from the peerdb
|
// RefreshJob retrieves peer info from the peerdb
|
||||||
|
|
|
@ -6,11 +6,12 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/locker"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/locker"
|
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
|
"go.sour.is/ev"
|
||||||
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -11,10 +11,9 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/metric/instrument"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.opentelemetry.io/otel/metric/instrument/syncint64"
|
"go.sour.is/pkg/authreq"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/authreq"
|
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,9 +29,9 @@ func WithBlobStore(path string) *withBlobStore {
|
||||||
type withBlobStore struct {
|
type withBlobStore struct {
|
||||||
path string
|
path string
|
||||||
|
|
||||||
m_get_blob syncint64.Counter
|
m_get_blob metric.Int64Counter
|
||||||
m_put_blob syncint64.Counter
|
m_put_blob metric.Int64Counter
|
||||||
m_delete_blob syncint64.Counter
|
m_delete_blob metric.Int64Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *withBlobStore) ApplySalty(s *service) {}
|
func (o *withBlobStore) ApplySalty(s *service) {}
|
||||||
|
@ -49,18 +48,18 @@ func (o *withBlobStore) Setup(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
m := lg.Meter(ctx)
|
m := lg.Meter(ctx)
|
||||||
o.m_get_blob, err = m.SyncInt64().Counter("salty_get_blob",
|
o.m_get_blob, err = m.Int64Counter("salty_get_blob",
|
||||||
instrument.WithDescription("salty get blob called"),
|
metric.WithDescription("salty get blob called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
o.m_put_blob, err = m.SyncInt64().Counter("salty_put_blob",
|
o.m_put_blob, err = m.Int64Counter("salty_put_blob",
|
||||||
instrument.WithDescription("salty put blob called"),
|
metric.WithDescription("salty put blob called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
o.m_delete_blob, err = m.SyncInt64().Counter("salty_delete_blob",
|
o.m_delete_blob, err = m.Int64Counter("salty_delete_blob",
|
||||||
instrument.WithDescription("salty delete blob called"),
|
metric.WithDescription("salty delete blob called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/keys-pub/keys"
|
"github.com/keys-pub/keys"
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config represents a Salty Config for a User which at a minimum is required
|
// Config represents a Salty Config for a User which at a minimum is required
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/keys-pub/keys"
|
"github.com/keys-pub/keys"
|
||||||
"github.com/oklog/ulid/v2"
|
"github.com/oklog/ulid/v2"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/gql"
|
"go.sour.is/pkg/gql"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SaltyUser struct {
|
type SaltyUser struct {
|
||||||
|
|
|
@ -14,15 +14,13 @@ import (
|
||||||
|
|
||||||
"github.com/keys-pub/keys"
|
"github.com/keys-pub/keys"
|
||||||
"go.mills.io/saltyim"
|
"go.mills.io/saltyim"
|
||||||
"go.opentelemetry.io/otel/metric/instrument"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.opentelemetry.io/otel/metric/instrument/syncint64"
|
|
||||||
"go.opentelemetry.io/otel/metric/unit"
|
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/gql"
|
||||||
"go.sour.is/ev/pkg/gql"
|
"go.sour.is/pkg/lg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DNSResolver interface {
|
type DNSResolver interface {
|
||||||
|
@ -34,13 +32,13 @@ type service struct {
|
||||||
es *ev.EventStore
|
es *ev.EventStore
|
||||||
dns DNSResolver
|
dns DNSResolver
|
||||||
|
|
||||||
m_create_user syncint64.Counter
|
m_create_user metric.Int64Counter
|
||||||
m_get_user syncint64.Counter
|
m_get_user metric.Int64Counter
|
||||||
m_api_ping syncint64.Counter
|
m_api_ping metric.Int64Counter
|
||||||
m_api_register syncint64.Counter
|
m_api_register metric.Int64Counter
|
||||||
m_api_lookup syncint64.Counter
|
m_api_lookup metric.Int64Counter
|
||||||
m_api_send syncint64.Counter
|
m_api_send metric.Int64Counter
|
||||||
m_req_time syncint64.Histogram
|
m_req_time metric.Int64Histogram
|
||||||
|
|
||||||
opts []Option
|
opts []Option
|
||||||
}
|
}
|
||||||
|
@ -93,39 +91,39 @@ func New(ctx context.Context, es *ev.EventStore, opts ...Option) (*service, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
var err, errs error
|
var err, errs error
|
||||||
svc.m_create_user, err = m.SyncInt64().Counter("salty_create_user",
|
svc.m_create_user, err = m.Int64Counter("salty_create_user",
|
||||||
instrument.WithDescription("salty create user graphql called"),
|
metric.WithDescription("salty create user graphql called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_get_user, err = m.SyncInt64().Counter("salty_get_user",
|
svc.m_get_user, err = m.Int64Counter("salty_get_user",
|
||||||
instrument.WithDescription("salty get user graphql called"),
|
metric.WithDescription("salty get user graphql called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_api_ping, err = m.SyncInt64().Counter("salty_api_ping",
|
svc.m_api_ping, err = m.Int64Counter("salty_api_ping",
|
||||||
instrument.WithDescription("salty api ping called"),
|
metric.WithDescription("salty api ping called"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_api_register, err = m.SyncInt64().Counter("salty_api_register",
|
svc.m_api_register, err = m.Int64Counter("salty_api_register",
|
||||||
instrument.WithDescription("salty api register"),
|
metric.WithDescription("salty api register"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_api_lookup, err = m.SyncInt64().Counter("salty_api_lookup",
|
svc.m_api_lookup, err = m.Int64Counter("salty_api_lookup",
|
||||||
instrument.WithDescription("salty api ping lookup"),
|
metric.WithDescription("salty api ping lookup"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_api_send, err = m.SyncInt64().Counter("salty_api_send",
|
svc.m_api_send, err = m.Int64Counter("salty_api_send",
|
||||||
instrument.WithDescription("salty api ping send"),
|
metric.WithDescription("salty api ping send"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
svc.m_req_time, err = m.SyncInt64().Histogram("salty_request_time",
|
svc.m_req_time, err = m.Int64Histogram("salty_request_time",
|
||||||
instrument.WithDescription("histogram of requests"),
|
metric.WithDescription("histogram of requests"),
|
||||||
instrument.WithUnit(unit.Unit("ns")),
|
metric.WithUnit("ns"),
|
||||||
)
|
)
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package webfinger
|
package webfinger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SubjectSet struct {
|
type SubjectSet struct {
|
||||||
|
|
|
@ -8,10 +8,11 @@ import (
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/set"
|
||||||
"go.sour.is/ev/pkg/set"
|
"go.sour.is/pkg/slice"
|
||||||
"go.sour.is/ev/pkg/slice"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StreamID(subject string) string {
|
func StreamID(subject string) string {
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
|
|
||||||
jwt "github.com/golang-jwt/jwt/v4"
|
jwt "github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/matryer/is"
|
"github.com/matryer/is"
|
||||||
|
"go.sour.is/ev"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
|
||||||
"go.sour.is/ev/app/webfinger"
|
"go.sour.is/ev/app/webfinger"
|
||||||
memstore "go.sour.is/ev/pkg/es/driver/mem-store"
|
memstore "go.sour.is/ev/pkg/driver/mem-store"
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
"go.sour.is/ev/pkg/es/driver/streamer"
|
"go.sour.is/ev/pkg/driver/streamer"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParseJRD(t *testing.T) {
|
func TestParseJRD(t *testing.T) {
|
||||||
|
|
|
@ -20,10 +20,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
"go.sour.is/pkg/set"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/set"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/app/msgbus"
|
"go.sour.is/ev/app/msgbus"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
"go.sour.is/pkg/service"
|
||||||
"go.sour.is/ev/pkg/slice"
|
"go.sour.is/pkg/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -4,13 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/env"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
"go.sour.is/pkg/service"
|
||||||
|
"go.sour.is/pkg/slice"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/app/peerfinder"
|
"go.sour.is/ev/app/peerfinder"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
"go.sour.is/ev/pkg/env"
|
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
|
||||||
"go.sour.is/ev/pkg/service"
|
|
||||||
"go.sour.is/ev/pkg/slice"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -11,10 +11,10 @@ import (
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/app/salty"
|
"go.sour.is/ev/app/salty"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/ev/pkg/env"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
"go.sour.is/ev/pkg/slice"
|
"go.sour.is/pkg/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -7,12 +7,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/app/webfinger"
|
"go.sour.is/ev/app/webfinger"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/ev/pkg/env"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
"go.sour.is/ev/pkg/slice"
|
"go.sour.is/pkg/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
var apps service.Apps
|
var apps service.Apps
|
||||||
|
|
|
@ -3,18 +3,19 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/env"
|
"go.sour.is/pkg/service"
|
||||||
"go.sour.is/ev/pkg/es"
|
|
||||||
diskstore "go.sour.is/ev/pkg/es/driver/disk-store"
|
|
||||||
memstore "go.sour.is/ev/pkg/es/driver/mem-store"
|
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
|
||||||
resolvelinks "go.sour.is/ev/pkg/es/driver/resolve-links"
|
|
||||||
"go.sour.is/ev/pkg/es/driver/streamer"
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/service"
|
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
|
"go.sour.is/ev"
|
||||||
|
diskstore "go.sour.is/ev/pkg/driver/disk-store"
|
||||||
|
memstore "go.sour.is/ev/pkg/driver/mem-store"
|
||||||
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
|
resolvelinks "go.sour.is/ev/pkg/driver/resolve-links"
|
||||||
|
"go.sour.is/ev/pkg/driver/streamer"
|
||||||
|
"go.sour.is/ev/pkg/es"
|
||||||
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(10, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(10, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/gql/resolver"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
"go.sour.is/pkg/mux"
|
||||||
|
"go.sour.is/pkg/service"
|
||||||
|
"go.sour.is/pkg/slice"
|
||||||
|
|
||||||
"go.sour.is/ev/app/gql"
|
"go.sour.is/ev/app/gql"
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
"go.sour.is/ev/pkg/gql/resolver"
|
|
||||||
"go.sour.is/ev/pkg/mux"
|
|
||||||
"go.sour.is/ev/pkg/service"
|
|
||||||
"go.sour.is/ev/pkg/slice"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(90, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(90, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rs/cors"
|
"github.com/rs/cors"
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
"go.sour.is/ev/pkg/env"
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/ev/pkg/mux"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/service"
|
"go.sour.is/pkg/mux"
|
||||||
"go.sour.is/ev/pkg/slice"
|
"go.sour.is/pkg/service"
|
||||||
|
"go.sour.is/pkg/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = apps.Register(20, func(ctx context.Context, svc *service.Harness) error {
|
var _ = apps.Register(20, func(ctx context.Context, svc *service.Harness) error {
|
||||||
|
|
|
@ -16,10 +16,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docopt/docopt-go"
|
"github.com/docopt/docopt-go"
|
||||||
|
"go.sour.is/pkg/xdg"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"go.sour.is/ev/app/webfinger"
|
"go.sour.is/ev/app/webfinger"
|
||||||
"go.sour.is/ev/cmd/webfinger-cli/xdg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var usage = `Webfinger CLI.
|
var usage = `Webfinger CLI.
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
//go:build darwin
|
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package xdg
|
|
||||||
|
|
||||||
func literal(name string) string {
|
|
||||||
return "$" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultDataHome = "~/Library/Application Support"
|
|
||||||
defaultDataDirs = "/Library/Application Support"
|
|
||||||
defaultConfigHome = "~/Library/Preferences"
|
|
||||||
defaultConfigDirs = "/Library/Preferences"
|
|
||||||
defaultCacheHome = "~/Library/Caches"
|
|
||||||
defaultStateHome = "~/Library/Caches"
|
|
||||||
defaultRuntime = "~/Library/Application Support"
|
|
||||||
|
|
||||||
defaultDesktop = "~/Desktop"
|
|
||||||
defaultDownload = "~/Downloads"
|
|
||||||
defaultDocuments = "~/Documents"
|
|
||||||
defaultMusic = "~/Music"
|
|
||||||
defaultPictures = "~/Pictures"
|
|
||||||
defaultVideos = "~/Videos"
|
|
||||||
defaultTemplates = "~/Templates"
|
|
||||||
defaultPublic = "~/Public"
|
|
||||||
|
|
||||||
defaultApplicationDirs = "~/Applications:/Applications"
|
|
||||||
defaultFontDirs = "~/Library/Fonts:/Library/Fonts:/System/Library/Fonts:/Network/Library/Fonts"
|
|
||||||
)
|
|
|
@ -1,30 +0,0 @@
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package xdg
|
|
||||||
|
|
||||||
func literal(name string) string {
|
|
||||||
return "$" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultDataHome = "~/.local/share"
|
|
||||||
defaultDataDirs = "/usr/local/share:/usr/share"
|
|
||||||
defaultConfigHome = "~/.config"
|
|
||||||
defaultConfigDirs = "/etc/xdg"
|
|
||||||
defaultCacheHome = "~/.local/cache"
|
|
||||||
defaultStateHome = "~/.local/state"
|
|
||||||
defaultRuntime = "/run/user/$UID"
|
|
||||||
|
|
||||||
defaultDesktop = "~/Desktop"
|
|
||||||
defaultDownload = "~/Downloads"
|
|
||||||
defaultDocuments = "~/Documents"
|
|
||||||
defaultMusic = "~/Music"
|
|
||||||
defaultPictures = "~/Pictures"
|
|
||||||
defaultVideos = "~/Videos"
|
|
||||||
defaultTemplates = "~/Templates"
|
|
||||||
defaultPublic = "~/Public"
|
|
||||||
|
|
||||||
defaultApplicationDirs = "~/Applications:/Applications"
|
|
||||||
defaultFontDirs = "~/.local/share/fonts:/usr/local/share/fonts:/usr/share/fonts:~/.fonts"
|
|
||||||
)
|
|
|
@ -1,30 +0,0 @@
|
||||||
//go:build windows
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package xdg
|
|
||||||
|
|
||||||
func literal(name string) string {
|
|
||||||
return "%" + name + "%"
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultDataHome = `%LOCALAPPDATA%`
|
|
||||||
defaultDataDirs = `%APPDATA%\Roaming;%ProgramData%`
|
|
||||||
defaultConfigHome = `%LOCALAPPDATA%`
|
|
||||||
defaultConfigDirs = `%ProgramData%`
|
|
||||||
defaultCacheHome = `%LOCALAPPDATA%\cache`
|
|
||||||
defaultStateHome = `%LOCALAPPDATA%\state`
|
|
||||||
defaultRuntime = `%LOCALAPPDATA%`
|
|
||||||
|
|
||||||
defaultDesktop = `%USERPROFILE%\Desktop`
|
|
||||||
defaultDownload = `%USERPROFILE%\Downloads`
|
|
||||||
defaultDocuments = `%USERPROFILE%\Documents`
|
|
||||||
defaultMusic = `%USERPROFILE%\Music`
|
|
||||||
defaultPictures = `%USERPROFILE%\Pictures`
|
|
||||||
defaultVideos = `%USERPROFILE%\Videos`
|
|
||||||
defaultTemplates = `%USERPROFILE%\Templates`
|
|
||||||
defaultPublic = `%USERPROFILE%\Public`
|
|
||||||
|
|
||||||
defaultApplicationDirs = `%APPDATA%\Roaming\Microsoft\Windows\Start Menu\Programs`
|
|
||||||
defaultFontDirs = `%windir%\Fonts;%LOCALAPPDATA%\Microsoft\Windows\Fonts`
|
|
||||||
)
|
|
|
@ -1,52 +0,0 @@
|
||||||
package xdg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
EnvDataHome = setENV("XDG_DATA_HOME", defaultDataHome)
|
|
||||||
EnvDataDirs = setENV("XDG_DATA_DIRS", defaultDataDirs)
|
|
||||||
EnvConfigHome = setENV("XDG_CONFIG_HOME", defaultConfigHome)
|
|
||||||
EnvConfigDirs = setENV("XDG_CONFIG_DIRS", defaultConfigDirs)
|
|
||||||
EnvCacheHome = setENV("XDG_CACHE_HOME", defaultCacheHome)
|
|
||||||
EnvStateHome = setENV("XDG_STATE_HOME", defaultStateHome)
|
|
||||||
EnvRuntime = setENV("XDG_RUNTIME_DIR", defaultRuntime)
|
|
||||||
EnvDesktopDir = setENV("XDG_DESKTOP_DIR", defaultDesktop)
|
|
||||||
EnvDownloadDir = setENV("XDG_DOWNLOAD_DIR", defaultDownload)
|
|
||||||
EnvDocumentsDir = setENV("XDG_DOCUMENTS_DIR", defaultDocuments)
|
|
||||||
EnvMusicDir = setENV("XDG_MUSIC_DIR", defaultMusic)
|
|
||||||
EnvPicturesDir = setENV("XDG_PICTURES_DIR", defaultPictures)
|
|
||||||
EnvVideosDir = setENV("XDG_VIDEOS_DIR", defaultVideos)
|
|
||||||
EnvTemplatesDir = setENV("XDG_TEMPLATES_DIR", defaultTemplates)
|
|
||||||
EnvPublicShareDir = setENV("XDG_PUBLICSHARE_DIR", defaultPublic)
|
|
||||||
EnvApplicationsDir = setENV("XDG_APPLICATIONS_DIR", defaultApplicationDirs)
|
|
||||||
EnvFontsDir = setENV("XDG_FONTS_DIR", defaultFontDirs)
|
|
||||||
)
|
|
||||||
|
|
||||||
func setENV(name, value string) string {
|
|
||||||
if _, ok := os.LookupEnv(name); !ok {
|
|
||||||
os.Setenv(name, value)
|
|
||||||
}
|
|
||||||
return literal(name)
|
|
||||||
}
|
|
||||||
func Get(base, suffix string) string {
|
|
||||||
paths := strings.Split(os.ExpandEnv(base), string(os.PathListSeparator))
|
|
||||||
for i, path := range paths {
|
|
||||||
if strings.HasPrefix(path, "~") {
|
|
||||||
path = strings.Replace(path, "~", getHome(), 1)
|
|
||||||
}
|
|
||||||
paths[i] = os.ExpandEnv(filepath.Join(path, suffix))
|
|
||||||
}
|
|
||||||
return strings.Join(paths, string(os.PathListSeparator))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getHome() string {
|
|
||||||
home, err := os.UserHomeDir()
|
|
||||||
if err != nil {
|
|
||||||
return "."
|
|
||||||
}
|
|
||||||
return home
|
|
||||||
}
|
|
30
ev.go
30
ev.go
|
@ -8,13 +8,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric/instrument/syncint64"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/locker"
|
"go.sour.is/pkg/locker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
|
@ -32,19 +32,19 @@ func Init(ctx context.Context) error {
|
||||||
m := lg.Meter(ctx)
|
m := lg.Meter(ctx)
|
||||||
|
|
||||||
var err, errs error
|
var err, errs error
|
||||||
Mes_open, err = m.SyncInt64().Counter("es_open")
|
Mes_open, err = m.Int64Counter("es_open")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
Mes_read, err = m.SyncInt64().Counter("es_read")
|
Mes_read, err = m.Int64Counter("es_read")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
Mes_load, err = m.SyncInt64().Counter("es_load")
|
Mes_load, err = m.Int64Counter("es_load")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
Mes_save, err = m.SyncInt64().Counter("es_save")
|
Mes_save, err = m.Int64Counter("es_save")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
Mes_append, err = m.SyncInt64().Counter("es_append")
|
Mes_append, err = m.Int64Counter("es_append")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
|
@ -68,11 +68,11 @@ type EventStore struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Mes_open syncint64.Counter
|
Mes_open metric.Int64Counter
|
||||||
Mes_read syncint64.Counter
|
Mes_read metric.Int64Counter
|
||||||
Mes_load syncint64.Counter
|
Mes_load metric.Int64Counter
|
||||||
Mes_save syncint64.Counter
|
Mes_save metric.Int64Counter
|
||||||
Mes_append syncint64.Counter
|
Mes_append metric.Int64Counter
|
||||||
)
|
)
|
||||||
|
|
||||||
func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, error) {
|
func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, error) {
|
||||||
|
|
10
ev_test.go
10
ev_test.go
|
@ -12,11 +12,11 @@ import (
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/app/peerfinder"
|
"go.sour.is/ev/app/peerfinder"
|
||||||
memstore "go.sour.is/ev/pkg/es/driver/mem-store"
|
memstore "go.sour.is/ev/pkg/driver/mem-store"
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
resolvelinks "go.sour.is/ev/pkg/es/driver/resolve-links"
|
resolvelinks "go.sour.is/ev/pkg/driver/resolve-links"
|
||||||
"go.sour.is/ev/pkg/es/driver/streamer"
|
"go.sour.is/ev/pkg/driver/streamer"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
86
go.mod
86
go.mod
|
@ -3,30 +3,33 @@ module go.sour.is/ev
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/99designs/gqlgen v0.17.13
|
github.com/99designs/gqlgen v0.17.34
|
||||||
github.com/go-logr/stdr v1.2.2
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/logzio/logzio-go v1.0.6
|
github.com/ravilushqa/otelgqlgen v0.13.1 // indirect
|
||||||
github.com/ravilushqa/otelgqlgen v0.9.0
|
|
||||||
github.com/rs/cors v1.8.2
|
github.com/rs/cors v1.8.2
|
||||||
github.com/tidwall/wal v1.1.7
|
github.com/tidwall/wal v1.1.7
|
||||||
github.com/vektah/gqlparser/v2 v2.4.7
|
github.com/vektah/gqlparser/v2 v2.5.6
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0
|
go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.9.0
|
go.opentelemetry.io/otel v1.16.0
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.31.0
|
go.opentelemetry.io/otel/exporters/prometheus v0.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v0.31.0
|
go.opentelemetry.io/otel/metric v1.16.0
|
||||||
go.opentelemetry.io/otel/sdk v1.9.0
|
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.31.0
|
go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.9.0
|
go.opentelemetry.io/otel/trace v1.16.0
|
||||||
golang.org/x/sync v0.1.0
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/tj/go-semver v1.0.0
|
require github.com/tj/go-semver v1.0.0
|
||||||
|
|
||||||
require github.com/patrickmn/go-cache v2.1.0+incompatible
|
require (
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
|
go.sour.is/pkg v0.0.1
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect
|
||||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||||
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae // indirect
|
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae // indirect
|
||||||
)
|
)
|
||||||
|
@ -37,24 +40,20 @@ require (
|
||||||
github.com/agnivade/levenshtein v1.1.1 // indirect
|
github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/avast/retry-go v3.0.0+incompatible // indirect
|
github.com/avast/retry-go v3.0.0+incompatible // indirect
|
||||||
github.com/beeker1121/goque v2.1.0+incompatible // indirect
|
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
|
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
|
||||||
github.com/dchest/blake2b v1.0.0 // indirect
|
github.com/dchest/blake2b v1.0.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.2.4 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
|
||||||
github.com/jpillora/backoff v1.0.0 // indirect
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 // indirect
|
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 // indirect
|
||||||
github.com/keybase/saltpack v0.0.0-20221220231257-f6cce11cfd0f // indirect
|
github.com/keybase/saltpack v0.0.0-20221220231257-f6cce11cfd0f // indirect
|
||||||
|
@ -65,20 +64,15 @@ require (
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/onsi/ginkgo v1.14.0 // indirect
|
|
||||||
github.com/onsi/gomega v1.10.3 // indirect
|
|
||||||
github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect
|
github.com/petermattis/goid v0.0.0-20221215004737-a150e88a970d // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/posener/formatter v1.0.0 // indirect
|
github.com/posener/formatter v1.0.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
github.com/prometheus/client_model v0.4.0 // indirect
|
||||||
github.com/prometheus/client_model v0.3.0 // indirect
|
github.com/prometheus/common v0.42.0 // indirect
|
||||||
github.com/prometheus/common v0.39.0 // indirect
|
github.com/prometheus/procfs v0.10.1 // indirect
|
||||||
github.com/prometheus/procfs v0.9.0 // indirect
|
|
||||||
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
||||||
github.com/shirou/gopsutil/v3 v3.22.3 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
|
||||||
github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09 // indirect
|
github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09 // indirect
|
||||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
|
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
|
||||||
|
@ -86,31 +80,29 @@ require (
|
||||||
github.com/vmihailenco/tagparser v0.1.2 // indirect
|
github.com/vmihailenco/tagparser v0.1.2 // indirect
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/writeas/go-strip-markdown/v2 v2.1.1 // indirect
|
github.com/writeas/go-strip-markdown/v2 v2.1.1 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
|
||||||
go.mills.io/salty v0.0.0-20220322161301-ce2b9f6573fa // indirect
|
go.mills.io/salty v0.0.0-20220322161301-ce2b9f6573fa // indirect
|
||||||
go.opentelemetry.io/contrib v1.9.0 // indirect
|
go.opentelemetry.io/contrib v1.16.1 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v0.18.0 // indirect
|
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
|
||||||
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587 // indirect
|
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587 // indirect
|
||||||
go.yarn.social/types v0.0.0-20221027173319-2d00e96a95c1 // indirect
|
go.yarn.social/types v0.0.0-20221027173319-2d00e96a95c1 // indirect
|
||||||
golang.org/x/crypto v0.5.0 // indirect
|
golang.org/x/crypto v0.5.0 // indirect
|
||||||
golang.org/x/net v0.5.0 // indirect
|
golang.org/x/net v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.4.0 // indirect
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
golang.org/x/text v0.6.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||||
google.golang.org/grpc v1.46.2 // indirect
|
google.golang.org/grpc v1.55.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
nhooyr.io/websocket v1.8.7 // indirect
|
nhooyr.io/websocket v1.8.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.3
|
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||||
github.com/keys-pub/keys v0.1.22
|
github.com/keys-pub/keys v0.1.22
|
||||||
github.com/matryer/is v1.4.0
|
github.com/matryer/is v1.4.1
|
||||||
github.com/oklog/ulid/v2 v2.1.0
|
github.com/oklog/ulid/v2 v2.1.0
|
||||||
github.com/tidwall/gjson v1.14.4 // indirect
|
github.com/tidwall/gjson v1.14.4 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
@ -118,7 +110,7 @@ require (
|
||||||
github.com/tidwall/tinylru v1.1.0 // indirect
|
github.com/tidwall/tinylru v1.1.0 // indirect
|
||||||
gitlab.com/jamietanna/content-negotiation-go v0.2.0
|
gitlab.com/jamietanna/content-negotiation-go v0.2.0
|
||||||
go.mills.io/saltyim v0.0.0-20230128070719-15a64de82829
|
go.mills.io/saltyim v0.0.0-20230128070719-15a64de82829
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0
|
go.uber.org/multierr v1.11.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
243
go.sum
243
go.sum
|
@ -36,10 +36,9 @@ git.mills.io/prologic/msgbus v0.1.20 h1:RWhuRgLRHkaWKqgBgpQQhgtFXQBXJjO7Fardu6kc
|
||||||
git.mills.io/prologic/msgbus v0.1.20/go.mod h1:ZFnDXoFvujU18Hv45pk0isCWAGjpkHpY9+/WSLzKJek=
|
git.mills.io/prologic/msgbus v0.1.20/go.mod h1:ZFnDXoFvujU18Hv45pk0isCWAGjpkHpY9+/WSLzKJek=
|
||||||
git.mills.io/prologic/observe v0.0.0-20210712230028-fc31c7aa2bd1 h1:e6ZyAOFGLZJZYL2galNvfuNMqeQDdilmQ5WRBXCNL5s=
|
git.mills.io/prologic/observe v0.0.0-20210712230028-fc31c7aa2bd1 h1:e6ZyAOFGLZJZYL2galNvfuNMqeQDdilmQ5WRBXCNL5s=
|
||||||
git.mills.io/prologic/useragent v0.0.0-20210714100044-d249fe7921a0 h1:MojWEgZyiugUbgyjydrdSAkHlADnbt90dXyURRYFzQ4=
|
git.mills.io/prologic/useragent v0.0.0-20210714100044-d249fe7921a0 h1:MojWEgZyiugUbgyjydrdSAkHlADnbt90dXyURRYFzQ4=
|
||||||
github.com/99designs/gqlgen v0.17.13 h1:ETUEqvRg5Zvr1lXtpoRdj026fzVay0ZlJPwI33qXLIw=
|
github.com/99designs/gqlgen v0.17.34 h1:5cS5/OKFguQt+Ws56uj9FlG2xm1IlcJWNF2jrMIKYFQ=
|
||||||
github.com/99designs/gqlgen v0.17.13/go.mod h1:w1brbeOdqVyNJI553BGwtwdVcYu1LKeYE1opLWN9RgQ=
|
github.com/99designs/gqlgen v0.17.34/go.mod h1:Axcd3jIFHBVcqzixujJQr1wGqE+lGTpz6u4iZBZg1G8=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
@ -47,7 +46,6 @@ github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajF
|
||||||
github.com/ScaleFT/sshkeys v1.2.0 h1:5BRp6rTVIhJzXT3VcUQrKgXR8zWA3sOsNeuyW15WUA8=
|
github.com/ScaleFT/sshkeys v1.2.0 h1:5BRp6rTVIhJzXT3VcUQrKgXR8zWA3sOsNeuyW15WUA8=
|
||||||
github.com/ScaleFT/sshkeys v1.2.0/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
|
github.com/ScaleFT/sshkeys v1.2.0/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
|
||||||
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShHIyywFiUZ7OOabwd9Sfd8rw=
|
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShHIyywFiUZ7OOabwd9Sfd8rw=
|
||||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
|
||||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||||
|
@ -60,14 +58,11 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdK
|
||||||
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
||||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||||
github.com/badgerodon/ioutil v0.0.0-20150716134133-06e58e34b867/go.mod h1:Ctq1YQi0dOq7QgBLZZ7p1Fr3IbAAqL/yMqDIHoe9WtE=
|
github.com/badgerodon/ioutil v0.0.0-20150716134133-06e58e34b867/go.mod h1:Ctq1YQi0dOq7QgBLZZ7p1Fr3IbAAqL/yMqDIHoe9WtE=
|
||||||
github.com/beeker1121/goque v2.1.0+incompatible h1:m5pZ5b8nqzojS2DF2ioZphFYQUqGYsDORq6uefUItPM=
|
|
||||||
github.com/beeker1121/goque v2.1.0+incompatible/go.mod h1:L6dOWBhDOnxUVQsb0wkLve0VCnt2xJW/MI8pdRX4ANw=
|
|
||||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
@ -83,9 +78,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
|
||||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||||
|
@ -109,13 +102,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
|
||||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
@ -126,12 +116,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
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-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
@ -147,11 +135,11 @@ github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
|
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
|
||||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||||
|
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
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-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -178,11 +166,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
@ -194,7 +180,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
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.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
@ -226,9 +211,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE=
|
||||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
|
@ -239,7 +223,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
||||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/justinas/nosurf v1.1.1 h1:92Aw44hjSK4MxJeMSyDa7jwuI9GR2J/JCQiaKvXXSlk=
|
github.com/justinas/nosurf v1.1.1 h1:92Aw44hjSK4MxJeMSyDa7jwuI9GR2J/JCQiaKvXXSlk=
|
||||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
|
||||||
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 h1:yg56lYPqh9suJepqxOMd/liFgU/x+maRPiB30JNYykM=
|
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123 h1:yg56lYPqh9suJepqxOMd/liFgU/x+maRPiB30JNYykM=
|
||||||
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20=
|
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20=
|
||||||
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6/go.mod h1:N83iQ9rnnzi2KZuTu+0xBcD1JNWn1jSN140ggAF7HeE=
|
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6/go.mod h1:N83iQ9rnnzi2KZuTu+0xBcD1JNWn1jSN140ggAF7HeE=
|
||||||
|
@ -256,8 +239,8 @@ github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7y
|
||||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
@ -271,45 +254,25 @@ github.com/likexian/gokit v0.25.9 h1:rzSQ/dP7Qw+QUzSuWlrLF0AtZS3Di6uO5yWOKhx2Gk4
|
||||||
github.com/likexian/gokit v0.25.9/go.mod h1:oDDqJUcnnF9uAKuw54F7s6oEG+OJ7eallfDW2dq0A/o=
|
github.com/likexian/gokit v0.25.9/go.mod h1:oDDqJUcnnF9uAKuw54F7s6oEG+OJ7eallfDW2dq0A/o=
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||||
github.com/logzio/logzio-go v1.0.6 h1:BIVu5TWDZc0vlEkwSDjoxPlV/aMJV2LdM3k+CjdzFDg=
|
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||||
github.com/logzio/logzio-go v1.0.6/go.mod h1:ljlI3Zfi3hntJiHqCqWSUPT9cZP6yvDHUzDl5ZLGYRE=
|
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
|
||||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
|
||||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
|
||||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/maxence-charriere/go-app/v9 v9.4.1 h1:uDrMIvjzkXwBjw5594i7ZqD5LY5iN7j1KeMImjWAYiw=
|
github.com/maxence-charriere/go-app/v9 v9.4.1 h1:uDrMIvjzkXwBjw5594i7ZqD5LY5iN7j1KeMImjWAYiw=
|
||||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/mlctrez/goapp-mdc v0.2.6 h1:/nSRAqC3xz+GFCd3Zl3yI87bBeEpJVXi5FSMnRighXo=
|
github.com/mlctrez/goapp-mdc v0.2.6 h1:/nSRAqC3xz+GFCd3Zl3yI87bBeEpJVXi5FSMnRighXo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 h1:Ys0rDzh8s4UMlGaDa1UTA0sfKgvF0hQZzTYX8ktjiDc=
|
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 h1:Ys0rDzh8s4UMlGaDa1UTA0sfKgvF0hQZzTYX8ktjiDc=
|
||||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
|
||||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
||||||
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
|
||||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
|
||||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
|
||||||
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
|
|
||||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||||
|
@ -324,34 +287,29 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/formatter v1.0.0 h1:TwXJq26f9ERTjCpZj8xEWj77WPWfX/nBgGx52Ap/gYM=
|
github.com/posener/formatter v1.0.0 h1:TwXJq26f9ERTjCpZj8xEWj77WPWfX/nBgGx52Ap/gYM=
|
||||||
github.com/posener/formatter v1.0.0/go.mod h1:xrC89js6vw5dde/9yUKKU9MY5ivn980yX4VG7gYQTvU=
|
github.com/posener/formatter v1.0.0/go.mod h1:xrC89js6vw5dde/9yUKKU9MY5ivn980yX4VG7gYQTvU=
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
|
||||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||||
github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=
|
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||||
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
|
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||||
github.com/ravilushqa/otelgqlgen v0.9.0 h1:NgbrU9OHPKB/X6Ja618+SqPNls05M3T8aV1fkUiR9ow=
|
github.com/ravilushqa/otelgqlgen v0.13.1 h1:V+zFE75iDd2/CSzy5kKnb+Fi09SsE5535wv9U2nUEFE=
|
||||||
github.com/ravilushqa/otelgqlgen v0.9.0/go.mod h1:TqSvbt/7E23CHOOgL6G+42kCbhvxUpT/21tMsarq4Hk=
|
github.com/ravilushqa/otelgqlgen v0.13.1/go.mod h1:ZIyWykK2paCuNi9k8gk5edcNSwDJuxZaW90vZXpafxw=
|
||||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
|
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
|
||||||
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
|
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
|
||||||
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
|
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.3 h1:UebRzEomgMpv61e3hgD1tGooqX5trFbdU/ehphbHd00=
|
|
||||||
github.com/shirou/gopsutil/v3 v3.22.3/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM=
|
|
||||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
@ -362,10 +320,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
|
||||||
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae h1:RXzKJmV0lGvBpY8/43bJShhPYIssF7X18UVMs9KIgIQ=
|
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae h1:RXzKJmV0lGvBpY8/43bJShhPYIssF7X18UVMs9KIgIQ=
|
||||||
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae/go.mod h1:1xBq06Fnn6nvsoWc+BCWwFvC0Zx04/FA3mpq937vlyI=
|
github.com/taigrr/go-colorhash v0.0.0-20220329080504-742db7f45eae/go.mod h1:1xBq06Fnn6nvsoWc+BCWwFvC0Zx04/FA3mpq937vlyI=
|
||||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
@ -386,8 +341,6 @@ github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0
|
||||||
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||||
github.com/tj/go-semver v1.0.0 h1:vpn6Jmn6Hi3QSmrP1PzYcqScop9IZiGCVOSn18wzu8w=
|
github.com/tj/go-semver v1.0.0 h1:vpn6Jmn6Hi3QSmrP1PzYcqScop9IZiGCVOSn18wzu8w=
|
||||||
github.com/tj/go-semver v1.0.0/go.mod h1:YZuwVc013rh7KDV0k6tPbWrFeEHBHcp8amfJL+nHzjM=
|
github.com/tj/go-semver v1.0.0/go.mod h1:YZuwVc013rh7KDV0k6tPbWrFeEHBHcp8amfJL+nHzjM=
|
||||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
|
||||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
|
||||||
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||||
|
@ -396,10 +349,8 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/unrolled/logger v0.0.0-20201216141554-31a3694fe979 h1:47+K4wN0S8L3fUwgZtPEBIfNqtAE3tUvBfvHVZJAXfg=
|
github.com/unrolled/logger v0.0.0-20201216141554-31a3694fe979 h1:47+K4wN0S8L3fUwgZtPEBIfNqtAE3tUvBfvHVZJAXfg=
|
||||||
github.com/unrolled/render v1.4.1 h1:VdpMc2YkAOWzbmC/P2yoHhRDXgsaCQHcTJ1KK6SNCA4=
|
github.com/unrolled/render v1.4.1 h1:VdpMc2YkAOWzbmC/P2yoHhRDXgsaCQHcTJ1KK6SNCA4=
|
||||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU=
|
||||||
github.com/vektah/gqlparser/v2 v2.4.6/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME=
|
||||||
github.com/vektah/gqlparser/v2 v2.4.7 h1:yub2WLoSIr+chP1zMv6bjrsgTasfubxGZJeC8ISEpgE=
|
|
||||||
github.com/vektah/gqlparser/v2 v2.4.7/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
|
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||||
|
@ -411,14 +362,10 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||||
github.com/writeas/go-strip-markdown/v2 v2.1.1 h1:hAxUM21Uhznf/FnbVGiJciqzska6iLei22Ijc3q2e28=
|
github.com/writeas/go-strip-markdown/v2 v2.1.1 h1:hAxUM21Uhznf/FnbVGiJciqzska6iLei22Ijc3q2e28=
|
||||||
github.com/writeas/go-strip-markdown/v2 v2.1.1/go.mod h1:UvvgPJgn1vvN8nWuE5e7v/+qmDu3BSVnKAB6Gl7hFzA=
|
github.com/writeas/go-strip-markdown/v2 v2.1.1/go.mod h1:UvvgPJgn1vvN8nWuE5e7v/+qmDu3BSVnKAB6Gl7hFzA=
|
||||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
|
||||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
|
||||||
gitlab.com/jamietanna/content-negotiation-go v0.2.0 h1:vT0OLEPQ6DYRG3/1F7joXSNjVQHGivJ6+JzODlJfjWw=
|
gitlab.com/jamietanna/content-negotiation-go v0.2.0 h1:vT0OLEPQ6DYRG3/1F7joXSNjVQHGivJ6+JzODlJfjWw=
|
||||||
gitlab.com/jamietanna/content-negotiation-go v0.2.0/go.mod h1:n4ZZ8/X5TstnjYRnjEtR/fC7MCTe+aRKM7PQlLBH3PQ=
|
gitlab.com/jamietanna/content-negotiation-go v0.2.0/go.mod h1:n4ZZ8/X5TstnjYRnjEtR/fC7MCTe+aRKM7PQlLBH3PQ=
|
||||||
go.mills.io/salty v0.0.0-20220322161301-ce2b9f6573fa h1:KBxzYJMWP7MXd72RgqsMCGOSEqV6aaDDSdSb8usJCzQ=
|
go.mills.io/salty v0.0.0-20220322161301-ce2b9f6573fa h1:KBxzYJMWP7MXd72RgqsMCGOSEqV6aaDDSdSb8usJCzQ=
|
||||||
|
@ -430,38 +377,37 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
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.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opentelemetry.io/contrib v1.9.0 h1:2KAoCVu4OMI9TYoSWvcV7+UbbIPOi4623S77nV+M/Ks=
|
go.opentelemetry.io/contrib v1.16.1 h1:EpASvVyGx6/ZTlmXzxYfTMZxHROelCeXXa2uLiwltcs=
|
||||||
go.opentelemetry.io/contrib v1.9.0/go.mod h1:yp0N4+hnpWCpnMzs6T6WbD9Amfg7reEZsS0jAd/5M2Q=
|
go.opentelemetry.io/contrib v1.16.1/go.mod h1:gIzjwWFoGazJmtCaDgViqOSJPde2mCWzv60o0bWPcZs=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0 h1:9NkMW03wwEzPtP/KciZ4Ozu/Uz5ZA7kfqXJIObnrjGU=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0/go.mod h1:548ZsYzmT4PL4zWKRd8q/N4z0Wxzn/ZxUE+lkEpwWQA=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8=
|
||||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0 h1:zt4RDodWkgiHk8tyUmFOjFoOOfyGH7vwIbUzKP6CCh8=
|
go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 h1:EbmAUG9hEAMXyfWEasIt2kmh/WmXUznUksChApTgBGc=
|
||||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0/go.mod h1:5wIoZE96WbcQVU3D6UF/ukRfFQXbB6OYgeWi9CjHa90=
|
go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0/go.mod h1:rD9feqRYP24P14t5kmhNMqsqm1jvKmpx2H2rKVw52V8=
|
||||||
go.opentelemetry.io/otel v1.9.0 h1:8WZNQFIB2a71LnANS9JeyidJKKGOOremcUtb/OtHISw=
|
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
|
||||||
go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo=
|
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 h1:ggqApEjDKczicksfvZUCxuvoyDmR6Sbm56LwiK8DVR0=
|
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY=
|
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 h1:NN90Cuna0CnBg8YNu1Q0V35i2E8LDByFOwHRCq/ZP9I=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0/go.mod h1:0EsCXjZAiiZGnLdEUXM9YjCKuuLZMYyglh2QDXcYKVA=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0 h1:FAF9l8Wjxi9Ad2k/vLTfHZyzXYX72C62wBGpV3G6AIo=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0/go.mod h1:smUdtylgc0YQiUr2PuifS4hBXhAS5xtR6WQhxP1wiNA=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.31.0 h1:jwtnOGBM8dIty5AVZ+9ZCzZexCea3aVKmUfZAQcHqxs=
|
go.opentelemetry.io/otel/exporters/prometheus v0.39.0 h1:whAaiHxOatgtKd+w0dOi//1KUxj3KoPINZdtDaDj3IA=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.31.0/go.mod h1:QarXIB8L79IwIPoNgG3A6zNvBgVmcppeFogV1d8612s=
|
go.opentelemetry.io/otel/exporters/prometheus v0.39.0/go.mod h1:4jo5Q4CROlCpSPsXLhymi+LYrDXd2ObU5wbKayfZs7Y=
|
||||||
go.opentelemetry.io/otel/metric v0.31.0 h1:6SiklT+gfWAwWUR0meEMxQBtihpiEs4c+vL9spDTqUs=
|
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
|
||||||
go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A=
|
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
|
||||||
go.opentelemetry.io/otel/sdk v1.9.0 h1:LNXp1vrr83fNXTHgU8eO89mhzxb/bbWAsHG6fNf3qWo=
|
go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE=
|
||||||
go.opentelemetry.io/otel/sdk v1.9.0/go.mod h1:AEZc8nt5bd2F7BC24J5R0mrjYnpEgYHyTcM/vrSple4=
|
go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.31.0 h1:2sZx4R43ZMhJdteKAlKoHvRgrMp53V1aRxvEf5lCq8Q=
|
go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.31.0/go.mod h1:fl0SmNnX9mN9xgU6OLYLMBMrNAsaZQi7qBwprwO3abk=
|
go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI=
|
||||||
go.opentelemetry.io/otel/trace v1.9.0 h1:oZaCNJUjWcg60VXWee8lJKlqhPbXAPB51URuR47pQYc=
|
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
|
||||||
go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo=
|
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.opentelemetry.io/proto/otlp v0.18.0 h1:W5hyXNComRa23tGpKwG+FRAc4rfF6ZUg1JReK+QHS80=
|
go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw=
|
||||||
go.opentelemetry.io/proto/otlp v0.18.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.sour.is/pkg v0.0.1 h1:wajjul3FNTljfcsNqNHsnelyVvsq8buuKrfxncJDuu0=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.sour.is/pkg v0.0.1/go.mod h1:jOdxxKILf+kXQmk1cG3sN4Ogxk8C4/14mxhy/QEJjv4=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
|
||||||
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587 h1:MuJTXSxPUNxqzT+q+fulCjkivDeC5jjZ7TSsf/f/24M=
|
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587 h1:MuJTXSxPUNxqzT+q+fulCjkivDeC5jjZ7TSsf/f/24M=
|
||||||
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587/go.mod h1:XcveSVLWxkBBW32VEAnewBcnEYw8O2Vb/xqJmXC54Hs=
|
go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587/go.mod h1:XcveSVLWxkBBW32VEAnewBcnEYw8O2Vb/xqJmXC54Hs=
|
||||||
go.yarn.social/types v0.0.0-20221025190911-9524f5b4a743/go.mod h1:XN+G4HprNn/Gp7OF2zveqsCRSWFCHtOaIRh2GlcK+U4=
|
go.yarn.social/types v0.0.0-20221025190911-9524f5b4a743/go.mod h1:XN+G4HprNn/Gp7OF2zveqsCRSWFCHtOaIRh2GlcK+U4=
|
||||||
|
@ -510,12 +456,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
@ -537,21 +480,17 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -568,10 +507,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -580,11 +518,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -600,44 +534,34 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
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=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -681,13 +605,10 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
|
||||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
|
@ -743,8 +664,9 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE=
|
|
||||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
|
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
|
||||||
|
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
@ -761,8 +683,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||||
google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
|
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
||||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
@ -776,24 +698,17 @@ 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-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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
1
internal/graph/generated/pkg.go
Normal file
1
internal/graph/generated/pkg.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package generated
|
|
@ -5,11 +5,12 @@ package resolver
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/gql"
|
||||||
|
|
||||||
"go.sour.is/ev/app/msgbus"
|
"go.sour.is/ev/app/msgbus"
|
||||||
"go.sour.is/ev/app/salty"
|
"go.sour.is/ev/app/salty"
|
||||||
"go.sour.is/ev/internal/graph/generated"
|
"go.sour.is/ev/internal/graph/generated"
|
||||||
"go.sour.is/ev/pkg/es"
|
"go.sour.is/ev/pkg/es"
|
||||||
"go.sour.is/ev/pkg/gql"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Resolver struct{}
|
type Resolver struct{}
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package lg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.uber.org/multierr"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init(ctx context.Context, name string) (context.Context, func(context.Context) error) {
|
|
||||||
ctx, span := Span(ctx)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
stop := [3]func() error{
|
|
||||||
initLogger(name),
|
|
||||||
}
|
|
||||||
ctx, stop[1] = initMetrics(ctx, name)
|
|
||||||
ctx, stop[2] = initTracing(ctx, name)
|
|
||||||
|
|
||||||
reverse(stop[:])
|
|
||||||
|
|
||||||
return ctx, func(context.Context) error {
|
|
||||||
log.Println("flushing logs...")
|
|
||||||
errs := make([]error, len(stop))
|
|
||||||
for i, fn := range stop {
|
|
||||||
if fn != nil {
|
|
||||||
errs[i] = fn()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Println("all stopped.")
|
|
||||||
return multierr.Combine(errs...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func env(name, defaultValue string) string {
|
|
||||||
name = strings.TrimSpace(name)
|
|
||||||
defaultValue = strings.TrimSpace(defaultValue)
|
|
||||||
if v := strings.TrimSpace(os.Getenv(name)); v != "" {
|
|
||||||
log.Println("# ", name, "=", v)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
log.Println("# ", name, "=", defaultValue, "(default)")
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
type secret string
|
|
||||||
|
|
||||||
func (s secret) String() string {
|
|
||||||
if s == "" {
|
|
||||||
return "(nil)"
|
|
||||||
}
|
|
||||||
return "***"
|
|
||||||
}
|
|
||||||
func (s secret) Secret() string {
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
func envSecret(name, defaultValue string) secret {
|
|
||||||
name = strings.TrimSpace(name)
|
|
||||||
defaultValue = strings.TrimSpace(defaultValue)
|
|
||||||
if v := strings.TrimSpace(os.Getenv(name)); v != "" {
|
|
||||||
log.Println("# ", name, "=", secret(v))
|
|
||||||
return secret(v)
|
|
||||||
}
|
|
||||||
log.Println("# ", name, "=", secret(defaultValue), "(default)")
|
|
||||||
return secret(defaultValue)
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
package lg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"runtime/debug"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-logr/stdr"
|
|
||||||
"github.com/logzio/logzio-go"
|
|
||||||
"go.opentelemetry.io/otel"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logzwriter struct {
|
|
||||||
name string
|
|
||||||
pkg string
|
|
||||||
goversion string
|
|
||||||
hostname string
|
|
||||||
|
|
||||||
w io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *logzwriter) Write(b []byte) (int, error) {
|
|
||||||
i := 0
|
|
||||||
for _, sp := range bytes.Split(b, []byte("\n")) {
|
|
||||||
msg := struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
Host string `json:"host"`
|
|
||||||
GoVersion string `json:"go_version"`
|
|
||||||
Package string `json:"pkg"`
|
|
||||||
App string `json:"app"`
|
|
||||||
}{
|
|
||||||
Message: strings.TrimSpace(string(sp)),
|
|
||||||
Host: l.hostname,
|
|
||||||
GoVersion: l.goversion,
|
|
||||||
Package: l.pkg,
|
|
||||||
App: l.name,
|
|
||||||
}
|
|
||||||
|
|
||||||
if msg.Message == "" || strings.HasPrefix(msg.Message, "#") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := l.w.Write(b)
|
|
||||||
|
|
||||||
i += j
|
|
||||||
if err != nil {
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initLogger(name string) func() error {
|
|
||||||
log.SetPrefix("[" + name + "] ")
|
|
||||||
log.SetFlags(log.LstdFlags&^(log.Ldate|log.Ltime) | log.Lshortfile)
|
|
||||||
|
|
||||||
token := envSecret("LOGZIO_LOG_TOKEN", "")
|
|
||||||
if token == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := logzio.New(
|
|
||||||
token.Secret(),
|
|
||||||
// logzio.SetDebug(os.Stderr),
|
|
||||||
logzio.SetUrl(env("LOGZIO_LOG_URL", "https://listener.lg.io:8071")),
|
|
||||||
logzio.SetDrainDuration(time.Second*5),
|
|
||||||
logzio.SetTempDirectory(env("LOGZIO_DIR", os.TempDir())),
|
|
||||||
logzio.SetCheckDiskSpace(true),
|
|
||||||
logzio.SetDrainDiskThreshold(70),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
w := io.MultiWriter(os.Stderr, lzw(l, name))
|
|
||||||
log.SetOutput(w)
|
|
||||||
otel.SetLogger(stdr.New(log.Default()))
|
|
||||||
|
|
||||||
return func() error {
|
|
||||||
defer log.Println("logger stopped")
|
|
||||||
log.SetOutput(os.Stderr)
|
|
||||||
l.Stop()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func lzw(l io.Writer, name string) io.Writer {
|
|
||||||
lz := &logzwriter{
|
|
||||||
name: name,
|
|
||||||
w: l,
|
|
||||||
}
|
|
||||||
|
|
||||||
if info, ok := debug.ReadBuildInfo(); ok {
|
|
||||||
lz.goversion = info.GoVersion
|
|
||||||
lz.pkg = info.Path
|
|
||||||
}
|
|
||||||
if hostname, err := os.Hostname(); err == nil {
|
|
||||||
lz.hostname = hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
return lz
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
package lg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"runtime/debug"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/contrib/instrumentation/runtime"
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/exporters/prometheus"
|
|
||||||
"go.opentelemetry.io/otel/metric"
|
|
||||||
"go.opentelemetry.io/otel/metric/global"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
|
|
||||||
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/export/aggregation"
|
|
||||||
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
|
|
||||||
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
|
||||||
)
|
|
||||||
|
|
||||||
var meterKey = contextKey{"meter"}
|
|
||||||
var promHTTPKey = contextKey{"promHTTP"}
|
|
||||||
|
|
||||||
func Meter(ctx context.Context) metric.Meter {
|
|
||||||
if t := fromContext[contextKey, metric.Meter](ctx, tracerKey); t != nil {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
return global.Meter("")
|
|
||||||
}
|
|
||||||
func NewHTTP(ctx context.Context) *httpHandle {
|
|
||||||
t := fromContext[contextKey, *prometheus.Exporter](ctx, promHTTPKey)
|
|
||||||
return &httpHandle{t}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initMetrics(ctx context.Context, name string) (context.Context, func() error) {
|
|
||||||
goversion := ""
|
|
||||||
pkg := ""
|
|
||||||
host := ""
|
|
||||||
if info, ok := debug.ReadBuildInfo(); ok {
|
|
||||||
goversion = info.GoVersion
|
|
||||||
pkg = info.Path
|
|
||||||
}
|
|
||||||
if h, err := os.Hostname(); err == nil {
|
|
||||||
host = h
|
|
||||||
}
|
|
||||||
|
|
||||||
config := prometheus.Config{
|
|
||||||
DefaultHistogramBoundaries: []float64{
|
|
||||||
2 << 6, 2 << 8, 2 << 10, 2 << 12, 2 << 14, 2 << 16, 2 << 18, 2 << 20, 2 << 22, 2 << 24, 2 << 26, 2 << 28,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
cont := controller.New(
|
|
||||||
processor.NewFactory(
|
|
||||||
selector.NewWithHistogramDistribution(
|
|
||||||
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
|
|
||||||
),
|
|
||||||
aggregation.CumulativeTemporalitySelector(),
|
|
||||||
processor.WithMemory(true),
|
|
||||||
),
|
|
||||||
controller.WithResource(
|
|
||||||
resource.NewWithAttributes(
|
|
||||||
semconv.SchemaURL,
|
|
||||||
attribute.String("app", name),
|
|
||||||
attribute.String("host", host),
|
|
||||||
attribute.String("go_version", goversion),
|
|
||||||
attribute.String("pkg", pkg),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
ex, err := prometheus.New(config, cont)
|
|
||||||
if err != nil {
|
|
||||||
return ctx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = toContext(ctx, promHTTPKey, ex)
|
|
||||||
|
|
||||||
global.SetMeterProvider(cont)
|
|
||||||
m := cont.Meter(name)
|
|
||||||
ctx = toContext(ctx, meterKey, m)
|
|
||||||
runtime.Start()
|
|
||||||
|
|
||||||
return ctx, func() error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
defer log.Println("metrics stopped")
|
|
||||||
return cont.Stop(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpHandle struct {
|
|
||||||
exp *prometheus.Exporter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *httpHandle) RegisterHTTP(mux *http.ServeMux) {
|
|
||||||
if h.exp == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mux.Handle("/metrics", h.exp)
|
|
||||||
}
|
|
|
@ -1,176 +0,0 @@
|
||||||
package lg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
|
||||||
"go.opentelemetry.io/otel"
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
|
||||||
"go.opentelemetry.io/otel/propagation"
|
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
)
|
|
||||||
|
|
||||||
type contextKey struct {
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
var tracerKey = contextKey{"tracer"}
|
|
||||||
|
|
||||||
func Tracer(ctx context.Context) trace.Tracer {
|
|
||||||
if t := fromContext[contextKey, trace.Tracer](ctx, tracerKey); t != nil {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
return otel.Tracer("")
|
|
||||||
}
|
|
||||||
|
|
||||||
func attrs(ctx context.Context) (string, []attribute.KeyValue) {
|
|
||||||
var attrs []attribute.KeyValue
|
|
||||||
var name string
|
|
||||||
if pc, file, line, ok := runtime.Caller(2); ok {
|
|
||||||
if fn := runtime.FuncForPC(pc); fn != nil {
|
|
||||||
name = fn.Name()
|
|
||||||
}
|
|
||||||
attrs = append(attrs,
|
|
||||||
attribute.String("pc", fmt.Sprintf("%v", pc)),
|
|
||||||
attribute.String("file", file),
|
|
||||||
attribute.Int("line", line),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return name, attrs
|
|
||||||
}
|
|
||||||
|
|
||||||
func Span(ctx context.Context, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
|
||||||
name, attrs := attrs(ctx)
|
|
||||||
attrs = append(attrs, attribute.String("name", name))
|
|
||||||
ctx, span := Tracer(ctx).Start(ctx, name, opts...)
|
|
||||||
span.SetAttributes(attrs...)
|
|
||||||
|
|
||||||
return ctx, span
|
|
||||||
}
|
|
||||||
func NamedSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
|
||||||
_, attrs := attrs(ctx)
|
|
||||||
attrs = append(attrs, attribute.String("name", name))
|
|
||||||
ctx, span := Tracer(ctx).Start(ctx, name, opts...)
|
|
||||||
span.SetAttributes(attrs...)
|
|
||||||
|
|
||||||
return ctx, span
|
|
||||||
}
|
|
||||||
|
|
||||||
func Fork(ctx context.Context, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
|
||||||
name, attrs := attrs(ctx)
|
|
||||||
childCTX, childSpan := Tracer(ctx).Start(context.Background(), name, append(opts, trace.WithLinks(trace.LinkFromContext(ctx)))...)
|
|
||||||
childSpan.SetAttributes(attrs...)
|
|
||||||
|
|
||||||
_, span := Tracer(ctx).Start(ctx, name, append(opts, trace.WithLinks(trace.LinkFromContext(childCTX)))...)
|
|
||||||
span.SetAttributes(attrs...)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return childCTX, childSpan
|
|
||||||
}
|
|
||||||
|
|
||||||
type SampleRate string
|
|
||||||
|
|
||||||
const (
|
|
||||||
SampleAlways SampleRate = "always"
|
|
||||||
SampleNever SampleRate = "never"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initTracing(ctx context.Context, name string) (context.Context, func() error) {
|
|
||||||
res, err := resource.New(ctx,
|
|
||||||
resource.WithAttributes(
|
|
||||||
semconv.ServiceNameKey.String(name),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(wrap(err, "failed to create trace resource"))
|
|
||||||
return ctx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
exporterAddr := env("EV_TRACE_ENDPOINT", "")
|
|
||||||
if exporterAddr == "" {
|
|
||||||
return ctx, nil
|
|
||||||
}
|
|
||||||
traceExporter, err := otlptracehttp.New(ctx,
|
|
||||||
otlptracehttp.WithInsecure(),
|
|
||||||
otlptracehttp.WithEndpoint(exporterAddr),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(wrap(err, "failed to create trace exporter"))
|
|
||||||
return ctx, nil
|
|
||||||
}
|
|
||||||
bsp := sdktrace.NewBatchSpanProcessor(traceExporter)
|
|
||||||
|
|
||||||
var sample sdktrace.TracerProviderOption
|
|
||||||
sampleRate := SampleRate(env("EV_TRACE_SAMPLE", string(SampleNever)))
|
|
||||||
switch sampleRate {
|
|
||||||
case "always":
|
|
||||||
sample = sdktrace.WithSampler(sdktrace.AlwaysSample())
|
|
||||||
case "never":
|
|
||||||
sample = sdktrace.WithSampler(sdktrace.NeverSample())
|
|
||||||
default:
|
|
||||||
if v, err := strconv.Atoi(string(sampleRate)); err != nil {
|
|
||||||
sample = sdktrace.WithSampler(sdktrace.NeverSample())
|
|
||||||
} else {
|
|
||||||
sample = sdktrace.WithSampler(sdktrace.TraceIDRatioBased(float64(v) * 0.01))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tracerProvider := sdktrace.NewTracerProvider(
|
|
||||||
sample,
|
|
||||||
sdktrace.WithResource(res),
|
|
||||||
sdktrace.WithSpanProcessor(bsp),
|
|
||||||
)
|
|
||||||
otel.SetTracerProvider(tracerProvider)
|
|
||||||
otel.SetTextMapPropagator(propagation.TraceContext{})
|
|
||||||
|
|
||||||
ctx = toContext(ctx, tracerKey, otel.Tracer(name))
|
|
||||||
|
|
||||||
return ctx, func() error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
defer log.Println("tracer stopped")
|
|
||||||
return wrap(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func wrap(err error, s string) error {
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf(s, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func reverse[T any](s []T) {
|
|
||||||
first, last := 0, len(s)-1
|
|
||||||
for first < last {
|
|
||||||
s[first], s[last] = s[last], s[first]
|
|
||||||
first++
|
|
||||||
last--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Htrace(h http.Handler, name string) http.Handler {
|
|
||||||
return otelhttp.NewHandler(h, name, otelhttp.WithSpanNameFormatter(func(operation string, r *http.Request) string {
|
|
||||||
return fmt.Sprintf("%s: %s", operation, r.RequestURI)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func toContext[K comparable, V any](ctx context.Context, key K, value V) context.Context {
|
|
||||||
return context.WithValue(ctx, key, value)
|
|
||||||
}
|
|
||||||
func fromContext[K comparable, V any](ctx context.Context, key K) V {
|
|
||||||
var empty V
|
|
||||||
if v, ok := ctx.Value(key).(V); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return empty
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
package authreq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"crypto/ed25519"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"hash/fnv"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
)
|
|
||||||
|
|
||||||
var SignatureLifetime = 30 * time.Minute
|
|
||||||
var AuthHeader = "Authorization"
|
|
||||||
|
|
||||||
func Sign(req *http.Request, key ed25519.PrivateKey) (*http.Request, error) {
|
|
||||||
pub := enc([]byte(key.Public().(ed25519.PublicKey)))
|
|
||||||
|
|
||||||
h := fnv.New128a()
|
|
||||||
fmt.Fprint(h, req.Method, req.URL.String())
|
|
||||||
|
|
||||||
if req.Body != nil {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
w := io.MultiWriter(h, b)
|
|
||||||
_, err := io.Copy(w, req.Body)
|
|
||||||
if err != nil {
|
|
||||||
return req, err
|
|
||||||
}
|
|
||||||
req.Body = io.NopCloser(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, jwt.RegisteredClaims{
|
|
||||||
Subject: enc(h.Sum(nil)),
|
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(SignatureLifetime)),
|
|
||||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
||||||
Issuer: pub,
|
|
||||||
})
|
|
||||||
|
|
||||||
sig, err := token.SignedString(key)
|
|
||||||
if err != nil {
|
|
||||||
return req, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set(AuthHeader, sig)
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Authorization(hdlr http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
auth := req.Header.Get(AuthHeader)
|
|
||||||
if auth == "" {
|
|
||||||
rw.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h := fnv.New128a()
|
|
||||||
fmt.Fprint(h, req.Method, req.URL.String())
|
|
||||||
|
|
||||||
if req.Body != nil {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
w := io.MultiWriter(h, b)
|
|
||||||
_, err := io.Copy(w, req.Body)
|
|
||||||
if err != nil {
|
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subject := enc(h.Sum(nil))
|
|
||||||
token, err := jwt.ParseWithClaims(
|
|
||||||
string(auth),
|
|
||||||
&jwt.RegisteredClaims{},
|
|
||||||
func(tok *jwt.Token) (any, error) {
|
|
||||||
c, ok := tok.Claims.(*jwt.RegisteredClaims)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("wrong type of claim")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub, err := dec(c.Issuer)
|
|
||||||
return ed25519.PublicKey(pub), err
|
|
||||||
},
|
|
||||||
jwt.WithValidMethods([]string{jwt.SigningMethodEdDSA.Alg()}),
|
|
||||||
jwt.WithJSONNumber(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c, ok := token.Claims.(*jwt.RegisteredClaims)
|
|
||||||
if !ok {
|
|
||||||
rw.WriteHeader(http.StatusUnprocessableEntity)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req = req.WithContext(context.WithValue(req.Context(), contextKey, c))
|
|
||||||
|
|
||||||
if c.Subject != subject {
|
|
||||||
rw.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hdlr.ServeHTTP(rw, req)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func enc(b []byte) string {
|
|
||||||
return base64.RawURLEncoding.EncodeToString(b)
|
|
||||||
}
|
|
||||||
func dec(s string) ([]byte, error) {
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
return base64.RawURLEncoding.DecodeString(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
var contextKey = struct{ name string }{"jwtClaim"}
|
|
||||||
|
|
||||||
func FromContext(ctx context.Context) *jwt.RegisteredClaims {
|
|
||||||
if v := ctx.Value(contextKey); v != nil {
|
|
||||||
if c, ok := v.(*jwt.RegisteredClaims); ok {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
package authreq_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"encoding/base64"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev/pkg/authreq"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGETRequest(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
pub, priv, err := ed25519.GenerateKey(nil)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, "http://example.com/"+enc(pub)+"/test?q=test", nil)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
req, err = authreq.Sign(req, priv)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
t.Log(enc(pub))
|
|
||||||
t.Log(req.Header.Get(authreq.AuthHeader))
|
|
||||||
|
|
||||||
var hdlr http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
c := authreq.FromContext(r.Context())
|
|
||||||
if c == nil {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(req.URL.Path, c.Issuer) {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
hdlr = authreq.Authorization(hdlr)
|
|
||||||
|
|
||||||
rw := httptest.NewRecorder()
|
|
||||||
|
|
||||||
hdlr.ServeHTTP(rw, req)
|
|
||||||
|
|
||||||
is.Equal(rw.Code, http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPOSTRequest(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
content := "this is post!"
|
|
||||||
|
|
||||||
pub, priv, err := ed25519.GenerateKey(nil)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, "http://example.com/"+enc(pub)+"/test?q=test", strings.NewReader(content))
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
req, err = authreq.Sign(req, priv)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
t.Log(enc(pub))
|
|
||||||
t.Log(req.Header.Get(authreq.AuthHeader))
|
|
||||||
|
|
||||||
var hdlr http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
c := authreq.FromContext(r.Context())
|
|
||||||
if c == nil {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
contentCheck, err := io.ReadAll(r.Body)
|
|
||||||
r.Body.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log(string(contentCheck))
|
|
||||||
if !strings.Contains(req.URL.Path, c.Issuer) {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
hdlr = authreq.Authorization(hdlr)
|
|
||||||
|
|
||||||
rw := httptest.NewRecorder()
|
|
||||||
|
|
||||||
hdlr.ServeHTTP(rw, req)
|
|
||||||
|
|
||||||
is.Equal(rw.Code, http.StatusOK)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func enc(b []byte) string {
|
|
||||||
return base64.RawURLEncoding.EncodeToString(b)
|
|
||||||
}
|
|
238
pkg/cache/cache.go
vendored
238
pkg/cache/cache.go
vendored
|
@ -1,238 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val
|
|
||||||
DefaultEvictedBufferSize = 16
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cache is a thread-safe fixed size LRU cache.
|
|
||||||
type Cache[K comparable, V any] struct {
|
|
||||||
lru *LRU[K, V]
|
|
||||||
evictedKeys []K
|
|
||||||
evictedVals []V
|
|
||||||
onEvictedCB func(ctx context.Context, k K, v V)
|
|
||||||
lock sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates an LRU of the given size.
|
|
||||||
func NewCache[K comparable, V any](size int) (*Cache[K, V], error) {
|
|
||||||
return NewWithEvict[K, V](size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithEvict constructs a fixed size cache with the given eviction
|
|
||||||
// callback.
|
|
||||||
func NewWithEvict[K comparable, V any](size int, onEvicted func(context.Context, K, V)) (c *Cache[K, V], err error) {
|
|
||||||
// create a cache with default settings
|
|
||||||
c = &Cache[K, V]{
|
|
||||||
onEvictedCB: onEvicted,
|
|
||||||
}
|
|
||||||
if onEvicted != nil {
|
|
||||||
c.initEvictBuffers()
|
|
||||||
onEvicted = c.onEvicted
|
|
||||||
}
|
|
||||||
c.lru, err = NewLRU(size, onEvicted)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Cache[K, V]) initEvictBuffers() {
|
|
||||||
c.evictedKeys = make([]K, 0, DefaultEvictedBufferSize)
|
|
||||||
c.evictedVals = make([]V, 0, DefaultEvictedBufferSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// onEvicted save evicted key/val and sent in externally registered callback
|
|
||||||
// outside of critical section
|
|
||||||
func (c *Cache[K, V]) onEvicted(ctx context.Context, k K, v V) {
|
|
||||||
c.evictedKeys = append(c.evictedKeys, k)
|
|
||||||
c.evictedVals = append(c.evictedVals, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Purge is used to completely clear the cache.
|
|
||||||
func (c *Cache[K, V]) Purge(ctx context.Context) {
|
|
||||||
var ks []K
|
|
||||||
var vs []V
|
|
||||||
c.lock.Lock()
|
|
||||||
c.lru.Purge(ctx)
|
|
||||||
if c.onEvictedCB != nil && len(c.evictedKeys) > 0 {
|
|
||||||
ks, vs = c.evictedKeys, c.evictedVals
|
|
||||||
c.initEvictBuffers()
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
// invoke callback outside of critical section
|
|
||||||
if c.onEvictedCB != nil {
|
|
||||||
for i := 0; i < len(ks); i++ {
|
|
||||||
c.onEvictedCB(ctx, ks[i], vs[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
|
||||||
func (c *Cache[K, V]) Add(ctx context.Context, key K, value V) (evicted bool) {
|
|
||||||
var k K
|
|
||||||
var v V
|
|
||||||
c.lock.Lock()
|
|
||||||
evicted = c.lru.Add(ctx, key, value)
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
|
||||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
c.onEvictedCB(ctx, k, v)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get looks up a key's value from the cache.
|
|
||||||
func (c *Cache[K, V]) Get(key K) (value *V, ok bool) {
|
|
||||||
c.lock.Lock()
|
|
||||||
value, ok = c.lru.Get(key)
|
|
||||||
c.lock.Unlock()
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains checks if a key is in the cache, without updating the
|
|
||||||
// recent-ness or deleting it for being stale.
|
|
||||||
func (c *Cache[K, V]) Contains(key K) bool {
|
|
||||||
c.lock.RLock()
|
|
||||||
containKey := c.lru.Contains(key)
|
|
||||||
c.lock.RUnlock()
|
|
||||||
return containKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peek returns the key value (or undefined if not found) without updating
|
|
||||||
// the "recently used"-ness of the key.
|
|
||||||
func (c *Cache[K, V]) Peek(key K) (value *V, ok bool) {
|
|
||||||
c.lock.RLock()
|
|
||||||
value, ok = c.lru.Peek(key)
|
|
||||||
c.lock.RUnlock()
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContainsOrAdd checks if a key is in the cache without updating the
|
|
||||||
// recent-ness or deleting it for being stale, and if not, adds the value.
|
|
||||||
// Returns whether found and whether an eviction occurred.
|
|
||||||
func (c *Cache[K, V]) ContainsOrAdd(ctx context.Context, key K, value V) (ok, evicted bool) {
|
|
||||||
var k K
|
|
||||||
var v V
|
|
||||||
c.lock.Lock()
|
|
||||||
if c.lru.Contains(key) {
|
|
||||||
c.lock.Unlock()
|
|
||||||
return true, false
|
|
||||||
}
|
|
||||||
evicted = c.lru.Add(ctx, key, value)
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
|
||||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
c.onEvictedCB(ctx, k, v)
|
|
||||||
}
|
|
||||||
return false, evicted
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeekOrAdd checks if a key is in the cache without updating the
|
|
||||||
// recent-ness or deleting it for being stale, and if not, adds the value.
|
|
||||||
// Returns whether found and whether an eviction occurred.
|
|
||||||
func (c *Cache[K, V]) PeekOrAdd(ctx context.Context, key K, value V) (previous *V, ok, evicted bool) {
|
|
||||||
var k K
|
|
||||||
var v V
|
|
||||||
c.lock.Lock()
|
|
||||||
previous, ok = c.lru.Peek(key)
|
|
||||||
if ok {
|
|
||||||
c.lock.Unlock()
|
|
||||||
return previous, true, false
|
|
||||||
}
|
|
||||||
evicted = c.lru.Add(ctx, key, value)
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
|
||||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && evicted {
|
|
||||||
c.onEvictedCB(ctx, k, v)
|
|
||||||
}
|
|
||||||
return nil, false, evicted
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove removes the provided key from the cache.
|
|
||||||
func (c *Cache[K, V]) Remove(ctx context.Context, key K) (present bool) {
|
|
||||||
var k K
|
|
||||||
var v V
|
|
||||||
c.lock.Lock()
|
|
||||||
present = c.lru.Remove(ctx, key)
|
|
||||||
if c.onEvictedCB != nil && present {
|
|
||||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
|
||||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && present {
|
|
||||||
c.onEvicted(ctx, k, v)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize changes the cache size.
|
|
||||||
func (c *Cache[K, V]) Resize(ctx context.Context, size int) (evicted int) {
|
|
||||||
var ks []K
|
|
||||||
var vs []V
|
|
||||||
c.lock.Lock()
|
|
||||||
evicted = c.lru.Resize(ctx, size)
|
|
||||||
if c.onEvictedCB != nil && evicted > 0 {
|
|
||||||
ks, vs = c.evictedKeys, c.evictedVals
|
|
||||||
c.initEvictBuffers()
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && evicted > 0 {
|
|
||||||
for i := 0; i < len(ks); i++ {
|
|
||||||
c.onEvictedCB(ctx, ks[i], vs[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return evicted
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveOldest removes the oldest item from the cache.
|
|
||||||
func (c *Cache[K, V]) RemoveOldest(ctx context.Context) (key *K, value *V, ok bool) {
|
|
||||||
var k K
|
|
||||||
var v V
|
|
||||||
c.lock.Lock()
|
|
||||||
key, value, ok = c.lru.RemoveOldest(ctx)
|
|
||||||
if c.onEvictedCB != nil && ok {
|
|
||||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
|
||||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
|
||||||
}
|
|
||||||
c.lock.Unlock()
|
|
||||||
if c.onEvictedCB != nil && ok {
|
|
||||||
c.onEvictedCB(ctx, k, v)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOldest returns the oldest entry
|
|
||||||
func (c *Cache[K, V]) GetOldest() (key *K, value *V, ok bool) {
|
|
||||||
c.lock.RLock()
|
|
||||||
key, value, ok = c.lru.GetOldest()
|
|
||||||
c.lock.RUnlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
|
||||||
func (c *Cache[K, V]) Keys() []K {
|
|
||||||
c.lock.RLock()
|
|
||||||
keys := c.lru.Keys()
|
|
||||||
c.lock.RUnlock()
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of items in the cache.
|
|
||||||
func (c *Cache[K, V]) Len() int {
|
|
||||||
c.lock.RLock()
|
|
||||||
length := c.lru.Len()
|
|
||||||
c.lock.RUnlock()
|
|
||||||
return length
|
|
||||||
}
|
|
131
pkg/cache/cache_test.go
vendored
131
pkg/cache/cache_test.go
vendored
|
@ -1,131 +0,0 @@
|
||||||
package cache_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev/pkg/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCache(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
c, err := cache.NewCache[string, int](1)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
evicted := c.Add(ctx, "one", 1)
|
|
||||||
is.True(!evicted)
|
|
||||||
|
|
||||||
is.True(c.Contains("one"))
|
|
||||||
_, ok := c.Peek("one")
|
|
||||||
is.True(ok)
|
|
||||||
|
|
||||||
ok, evicted = c.ContainsOrAdd(ctx, "two", 2)
|
|
||||||
is.True(!ok)
|
|
||||||
is.True(evicted)
|
|
||||||
|
|
||||||
is.True(!c.Contains("one"))
|
|
||||||
is.True(c.Contains("two"))
|
|
||||||
|
|
||||||
is.Equal(c.Len(), 1)
|
|
||||||
is.Equal(c.Keys(), []string{"two"})
|
|
||||||
|
|
||||||
v, ok := c.Get("two")
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*v, 2)
|
|
||||||
|
|
||||||
evictCount := c.Resize(ctx, 100)
|
|
||||||
is.True(evictCount == 0)
|
|
||||||
|
|
||||||
c.Add(ctx, "one", 1)
|
|
||||||
|
|
||||||
prev, ok, evicted := c.PeekOrAdd(ctx, "three", 3)
|
|
||||||
is.True(!ok)
|
|
||||||
is.True(!evicted)
|
|
||||||
is.Equal(prev, nil)
|
|
||||||
|
|
||||||
key, value, ok := c.GetOldest()
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*key, "two")
|
|
||||||
is.Equal(*value, 2)
|
|
||||||
|
|
||||||
key, value, ok = c.RemoveOldest(ctx)
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*key, "two")
|
|
||||||
is.Equal(*value, 2)
|
|
||||||
|
|
||||||
c.Remove(ctx, "one")
|
|
||||||
|
|
||||||
c.Purge(ctx)
|
|
||||||
is.True(!c.Contains("three"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCacheWithEvict(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
evictions := 0
|
|
||||||
|
|
||||||
c, err := cache.NewWithEvict(1, func(ctx context.Context, s string, i int) { evictions++ })
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
key, value, ok := c.GetOldest()
|
|
||||||
is.True(!ok)
|
|
||||||
is.Equal(key, nil)
|
|
||||||
is.Equal(value, nil)
|
|
||||||
|
|
||||||
key, value, ok = c.RemoveOldest(ctx)
|
|
||||||
is.True(!ok)
|
|
||||||
is.Equal(key, nil)
|
|
||||||
is.Equal(value, nil)
|
|
||||||
|
|
||||||
evicted := c.Add(ctx, "one", 1)
|
|
||||||
is.True(!evicted)
|
|
||||||
|
|
||||||
is.True(c.Contains("one"))
|
|
||||||
_, ok = c.Peek("one")
|
|
||||||
is.True(ok)
|
|
||||||
|
|
||||||
ok, evicted = c.ContainsOrAdd(ctx, "two", 2)
|
|
||||||
is.True(!ok)
|
|
||||||
is.True(evicted)
|
|
||||||
|
|
||||||
is.True(!c.Contains("one"))
|
|
||||||
is.True(c.Contains("two"))
|
|
||||||
|
|
||||||
is.Equal(c.Len(), 1)
|
|
||||||
is.Equal(c.Keys(), []string{"two"})
|
|
||||||
|
|
||||||
v, ok := c.Get("two")
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*v, 2)
|
|
||||||
|
|
||||||
evictCount := c.Resize(ctx, 100)
|
|
||||||
is.True(evictCount == 0)
|
|
||||||
|
|
||||||
c.Add(ctx, "one", 1)
|
|
||||||
|
|
||||||
prev, ok, evicted := c.PeekOrAdd(ctx, "three", 3)
|
|
||||||
is.True(!ok)
|
|
||||||
is.True(!evicted)
|
|
||||||
is.Equal(prev, nil)
|
|
||||||
|
|
||||||
key, value, ok = c.GetOldest()
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*key, "two")
|
|
||||||
is.Equal(*value, 2)
|
|
||||||
|
|
||||||
key, value, ok = c.RemoveOldest(ctx)
|
|
||||||
is.True(ok)
|
|
||||||
is.Equal(*key, "two")
|
|
||||||
is.Equal(*value, 2)
|
|
||||||
|
|
||||||
c.Resize(ctx, 1)
|
|
||||||
|
|
||||||
c.Purge(ctx)
|
|
||||||
is.True(!c.Contains("three"))
|
|
||||||
|
|
||||||
is.Equal(evictions, 4)
|
|
||||||
}
|
|
235
pkg/cache/list.go
vendored
235
pkg/cache/list.go
vendored
|
@ -1,235 +0,0 @@
|
||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package list implements a doubly linked list.
|
|
||||||
//
|
|
||||||
// To iterate over a list (where l is a *List):
|
|
||||||
//
|
|
||||||
// for e := l.Front(); e != nil; e = e.Next() {
|
|
||||||
// // do something with e.Value
|
|
||||||
// }
|
|
||||||
package cache
|
|
||||||
|
|
||||||
// Element is an element of a linked list.
|
|
||||||
type Element[V any] struct {
|
|
||||||
// Next and previous pointers in the doubly-linked list of elements.
|
|
||||||
// To simplify the implementation, internally a list l is implemented
|
|
||||||
// as a ring, such that &l.root is both the next element of the last
|
|
||||||
// list element (l.Back()) and the previous element of the first list
|
|
||||||
// element (l.Front()).
|
|
||||||
next, prev *Element[V]
|
|
||||||
|
|
||||||
// The list to which this element belongs.
|
|
||||||
list *List[V]
|
|
||||||
|
|
||||||
// The value stored with this element.
|
|
||||||
Value V
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns the next list element or nil.
|
|
||||||
func (e *Element[V]) Next() *Element[V] {
|
|
||||||
if p := e.next; e.list != nil && p != &e.list.root {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prev returns the previous list element or nil.
|
|
||||||
func (e *Element[V]) Prev() *Element[V] {
|
|
||||||
if p := e.prev; e.list != nil && p != &e.list.root {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// List represents a doubly linked list.
|
|
||||||
// The zero value for List is an empty list ready to use.
|
|
||||||
type List[V any] struct {
|
|
||||||
root Element[V] // sentinel list element, only &root, root.prev, and root.next are used
|
|
||||||
len int // current list length excluding (this) sentinel element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initializes or clears list l.
|
|
||||||
func (l *List[V]) Init() *List[V] {
|
|
||||||
l.root.next = &l.root
|
|
||||||
l.root.prev = &l.root
|
|
||||||
l.len = 0
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewList returns an initialized list.
|
|
||||||
func NewList[V any]() *List[V] { return new(List[V]).Init() }
|
|
||||||
|
|
||||||
// Len returns the number of elements of list l.
|
|
||||||
// The complexity is O(1).
|
|
||||||
func (l *List[V]) Len() int { return l.len }
|
|
||||||
|
|
||||||
// Front returns the first element of list l or nil if the list is empty.
|
|
||||||
func (l *List[V]) Front() *Element[V] {
|
|
||||||
if l.len == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return l.root.next
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back returns the last element of list l or nil if the list is empty.
|
|
||||||
func (l *List[V]) Back() *Element[V] {
|
|
||||||
if l.len == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return l.root.prev
|
|
||||||
}
|
|
||||||
|
|
||||||
// lazyInit lazily initializes a zero List value.
|
|
||||||
func (l *List[V]) lazyInit() {
|
|
||||||
if l.root.next == nil {
|
|
||||||
l.Init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert inserts e after at, increments l.len, and returns e.
|
|
||||||
func (l *List[V]) insert(e, at *Element[V]) *Element[V] {
|
|
||||||
e.prev = at
|
|
||||||
e.next = at.next
|
|
||||||
e.prev.next = e
|
|
||||||
e.next.prev = e
|
|
||||||
e.list = l
|
|
||||||
l.len++
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
|
|
||||||
func (l *List[V]) insertValue(v V, at *Element[V]) *Element[V] {
|
|
||||||
return l.insert(&Element[V]{Value: v}, at)
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove removes e from its list, decrements l.len
|
|
||||||
func (l *List[V]) remove(e *Element[V]) {
|
|
||||||
e.prev.next = e.next
|
|
||||||
e.next.prev = e.prev
|
|
||||||
e.next = nil // avoid memory leaks
|
|
||||||
e.prev = nil // avoid memory leaks
|
|
||||||
e.list = nil
|
|
||||||
l.len--
|
|
||||||
}
|
|
||||||
|
|
||||||
// move moves e to next to at.
|
|
||||||
func (l *List[V]) move(e, at *Element[V]) {
|
|
||||||
if e == at {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
e.prev.next = e.next
|
|
||||||
e.next.prev = e.prev
|
|
||||||
|
|
||||||
e.prev = at
|
|
||||||
e.next = at.next
|
|
||||||
e.prev.next = e
|
|
||||||
e.next.prev = e
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove removes e from l if e is an element of list l.
|
|
||||||
// It returns the element value e.Value.
|
|
||||||
// The element must not be nil.
|
|
||||||
func (l *List[V]) Remove(e *Element[V]) any {
|
|
||||||
if e.list == l {
|
|
||||||
// if e.list == l, l must have been initialized when e was inserted
|
|
||||||
// in l or l == nil (e is a zero Element) and l.remove will crash
|
|
||||||
l.remove(e)
|
|
||||||
}
|
|
||||||
return e.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushFront inserts a new element e with value v at the front of list l and returns e.
|
|
||||||
func (l *List[V]) PushFront(v V) *Element[V] {
|
|
||||||
l.lazyInit()
|
|
||||||
return l.insertValue(v, &l.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushBack inserts a new element e with value v at the back of list l and returns e.
|
|
||||||
func (l *List[V]) PushBack(v V) *Element[V] {
|
|
||||||
l.lazyInit()
|
|
||||||
return l.insertValue(v, l.root.prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertBefore inserts a new element e with value v immediately before mark and returns e.
|
|
||||||
// If mark is not an element of l, the list is not modified.
|
|
||||||
// The mark must not be nil.
|
|
||||||
func (l *List[V]) InsertBefore(v V, mark *Element[V]) *Element[V] {
|
|
||||||
if mark.list != l {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// see comment in List.Remove about initialization of l
|
|
||||||
return l.insertValue(v, mark.prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InsertAfter inserts a new element e with value v immediately after mark and returns e.
|
|
||||||
// If mark is not an element of l, the list is not modified.
|
|
||||||
// The mark must not be nil.
|
|
||||||
func (l *List[V]) InsertAfter(v V, mark *Element[V]) *Element[V] {
|
|
||||||
if mark.list != l {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// see comment in List.Remove about initialization of l
|
|
||||||
return l.insertValue(v, mark)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveToFront moves element e to the front of list l.
|
|
||||||
// If e is not an element of l, the list is not modified.
|
|
||||||
// The element must not be nil.
|
|
||||||
func (l *List[V]) MoveToFront(e *Element[V]) {
|
|
||||||
if e.list != l || l.root.next == e {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// see comment in List.Remove about initialization of l
|
|
||||||
l.move(e, &l.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveToBack moves element e to the back of list l.
|
|
||||||
// If e is not an element of l, the list is not modified.
|
|
||||||
// The element must not be nil.
|
|
||||||
func (l *List[V]) MoveToBack(e *Element[V]) {
|
|
||||||
if e.list != l || l.root.prev == e {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// see comment in List.Remove about initialization of l
|
|
||||||
l.move(e, l.root.prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveBefore moves element e to its new position before mark.
|
|
||||||
// If e or mark is not an element of l, or e == mark, the list is not modified.
|
|
||||||
// The element and mark must not be nil.
|
|
||||||
func (l *List[V]) MoveBefore(e, mark *Element[V]) {
|
|
||||||
if e.list != l || e == mark || mark.list != l {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l.move(e, mark.prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveAfter moves element e to its new position after mark.
|
|
||||||
// If e or mark is not an element of l, or e == mark, the list is not modified.
|
|
||||||
// The element and mark must not be nil.
|
|
||||||
func (l *List[V]) MoveAfter(e, mark *Element[V]) {
|
|
||||||
if e.list != l || e == mark || mark.list != l {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l.move(e, mark)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushBackList inserts a copy of another list at the back of list l.
|
|
||||||
// The lists l and other may be the same. They must not be nil.
|
|
||||||
func (l *List[V]) PushBackList(other *List[V]) {
|
|
||||||
l.lazyInit()
|
|
||||||
for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
|
|
||||||
l.insertValue(e.Value, l.root.prev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushFrontList inserts a copy of another list at the front of list l.
|
|
||||||
// The lists l and other may be the same. They must not be nil.
|
|
||||||
func (l *List[V]) PushFrontList(other *List[V]) {
|
|
||||||
l.lazyInit()
|
|
||||||
for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
|
|
||||||
l.insertValue(e.Value, &l.root)
|
|
||||||
}
|
|
||||||
}
|
|
175
pkg/cache/lru.go
vendored
175
pkg/cache/lru.go
vendored
|
@ -1,175 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EvictCallback is used to get a callback when a cache entry is evicted
|
|
||||||
type EvictCallback[K comparable, V any] func(context.Context, K, V)
|
|
||||||
|
|
||||||
// LRU implements a non-thread safe fixed size LRU cache
|
|
||||||
type LRU[K comparable, V any] struct {
|
|
||||||
size int
|
|
||||||
evictList *List[entry[K, V]]
|
|
||||||
items map[K]*Element[entry[K, V]]
|
|
||||||
onEvict EvictCallback[K, V]
|
|
||||||
}
|
|
||||||
|
|
||||||
// entry is used to hold a value in the evictList
|
|
||||||
type entry[K comparable, V any] struct {
|
|
||||||
key K
|
|
||||||
value V
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLRU constructs an LRU of the given size
|
|
||||||
func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V]) (*LRU[K, V], error) {
|
|
||||||
if size <= 0 {
|
|
||||||
return nil, errors.New("must provide a positive size")
|
|
||||||
}
|
|
||||||
c := &LRU[K, V]{
|
|
||||||
size: size,
|
|
||||||
evictList: NewList[entry[K, V]](),
|
|
||||||
items: make(map[K]*Element[entry[K, V]]),
|
|
||||||
onEvict: onEvict,
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Purge is used to completely clear the cache.
|
|
||||||
func (c *LRU[K, V]) Purge(ctx context.Context) {
|
|
||||||
for k, v := range c.items {
|
|
||||||
if c.onEvict != nil {
|
|
||||||
c.onEvict(ctx, k, v.Value.value)
|
|
||||||
}
|
|
||||||
delete(c.items, k)
|
|
||||||
}
|
|
||||||
c.evictList.Init()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
|
||||||
func (c *LRU[K, V]) Add(ctx context.Context, key K, value V) (evicted bool) {
|
|
||||||
// Check for existing item
|
|
||||||
if ent, ok := c.items[key]; ok {
|
|
||||||
c.evictList.MoveToFront(ent)
|
|
||||||
ent.Value.value = value
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new item
|
|
||||||
entry := c.evictList.PushFront(entry[K, V]{key, value})
|
|
||||||
c.items[key] = entry
|
|
||||||
|
|
||||||
evict := c.evictList.Len() > c.size
|
|
||||||
// Verify size not exceeded
|
|
||||||
if evict {
|
|
||||||
c.removeOldest(ctx)
|
|
||||||
}
|
|
||||||
return evict
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get looks up a key's value from the cache.
|
|
||||||
func (c *LRU[K, V]) Get(key K) (value *V, ok bool) {
|
|
||||||
if ent, ok := c.items[key]; ok {
|
|
||||||
c.evictList.MoveToFront(ent)
|
|
||||||
if ent == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return &ent.Value.value, true
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains checks if a key is in the cache, without updating the recent-ness
|
|
||||||
// or deleting it for being stale.
|
|
||||||
func (c *LRU[K, V]) Contains(key K) (ok bool) {
|
|
||||||
_, ok = c.items[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peek returns the key value (or undefined if not found) without updating
|
|
||||||
// the "recently used"-ness of the key.
|
|
||||||
func (c *LRU[K, V]) Peek(key K) (value *V, ok bool) {
|
|
||||||
if ent, ok := c.items[key]; ok {
|
|
||||||
return &ent.Value.value, true
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove removes the provided key from the cache, returning if the
|
|
||||||
// key was contained.
|
|
||||||
func (c *LRU[K, V]) Remove(ctx context.Context, key K) (present bool) {
|
|
||||||
if ent, ok := c.items[key]; ok {
|
|
||||||
c.removeElement(ctx, ent)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveOldest removes the oldest item from the cache.
|
|
||||||
func (c *LRU[K, V]) RemoveOldest(ctx context.Context) (key *K, value *V, ok bool) {
|
|
||||||
ent := c.evictList.Back()
|
|
||||||
if ent != nil {
|
|
||||||
c.removeElement(ctx, ent)
|
|
||||||
kv := ent.Value
|
|
||||||
return &kv.key, &kv.value, true
|
|
||||||
}
|
|
||||||
return nil, nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOldest returns the oldest entry
|
|
||||||
func (c *LRU[K, V]) GetOldest() (key *K, value *V, ok bool) {
|
|
||||||
ent := c.evictList.Back()
|
|
||||||
if ent != nil {
|
|
||||||
kv := ent.Value
|
|
||||||
return &kv.key, &kv.value, true
|
|
||||||
}
|
|
||||||
return nil, nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
|
||||||
func (c *LRU[K, V]) Keys() []K {
|
|
||||||
keys := make([]K, len(c.items))
|
|
||||||
i := 0
|
|
||||||
for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() {
|
|
||||||
keys[i] = ent.Value.key
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of items in the cache.
|
|
||||||
func (c *LRU[K, V]) Len() int {
|
|
||||||
return c.evictList.Len()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize changes the cache size.
|
|
||||||
func (c *LRU[K, V]) Resize(ctx context.Context, size int) (evicted int) {
|
|
||||||
diff := c.Len() - size
|
|
||||||
if diff < 0 {
|
|
||||||
diff = 0
|
|
||||||
}
|
|
||||||
for i := 0; i < diff; i++ {
|
|
||||||
c.removeOldest(ctx)
|
|
||||||
}
|
|
||||||
c.size = size
|
|
||||||
return diff
|
|
||||||
}
|
|
||||||
|
|
||||||
// removeOldest removes the oldest item from the cache.
|
|
||||||
func (c *LRU[K, V]) removeOldest(ctx context.Context) {
|
|
||||||
ent := c.evictList.Back()
|
|
||||||
if ent != nil {
|
|
||||||
c.removeElement(ctx, ent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// removeElement is used to remove a given list element from the cache
|
|
||||||
func (c *LRU[K, V]) removeElement(ctx context.Context, e *Element[entry[K, V]]) {
|
|
||||||
c.evictList.Remove(e)
|
|
||||||
kv := e.Value
|
|
||||||
delete(c.items, kv.key)
|
|
||||||
if c.onEvict != nil {
|
|
||||||
c.onEvict(ctx, kv.key, kv.value)
|
|
||||||
}
|
|
||||||
}
|
|
160
pkg/cron/cron.go
160
pkg/cron/cron.go
|
@ -1,160 +0,0 @@
|
||||||
package cron
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
"go.sour.is/ev/pkg/locker"
|
|
||||||
"go.sour.is/ev/pkg/set"
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
)
|
|
||||||
|
|
||||||
type task func(context.Context, time.Time) error
|
|
||||||
type job struct {
|
|
||||||
Month, Weekday, Day,
|
|
||||||
Hour, Minute, Second *set.BoundSet[int8]
|
|
||||||
Task task
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultGranularity = time.Minute
|
|
||||||
|
|
||||||
type state struct {
|
|
||||||
queue []task
|
|
||||||
}
|
|
||||||
type cron struct {
|
|
||||||
jobs []job
|
|
||||||
state *locker.Locked[state]
|
|
||||||
granularity time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(granularity time.Duration) *cron {
|
|
||||||
return &cron{granularity: granularity, state: locker.New(&state{})}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseInto(c string, s *set.BoundSet[int8]) *set.BoundSet[int8] {
|
|
||||||
if c == "*" || c == "" {
|
|
||||||
s.AddRange(0, 100)
|
|
||||||
}
|
|
||||||
for _, split := range strings.Split(c, ",") {
|
|
||||||
minmax := strings.SplitN(split, "-", 2)
|
|
||||||
switch len(minmax) {
|
|
||||||
case 2:
|
|
||||||
min, _ := strconv.ParseInt(minmax[0], 10, 8)
|
|
||||||
max, _ := strconv.ParseInt(minmax[1], 10, 8)
|
|
||||||
s.AddRange(int8(min), int8(max))
|
|
||||||
default:
|
|
||||||
min, _ := strconv.ParseInt(minmax[0], 10, 8)
|
|
||||||
s.Add(int8(min))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function creates a new job that occurs at the given day and the given
|
|
||||||
// 24hour time. Any of the values may be -1 as an "any" match, so passing in
|
|
||||||
// a day of -1, the event occurs every day; passing in a second value of -1, the
|
|
||||||
// event will fire every second that the other parameters match.
|
|
||||||
func (c *cron) NewCron(expr string, task func(context.Context, time.Time) error) {
|
|
||||||
sp := append(strings.Fields(expr), make([]string, 5)...)[:5]
|
|
||||||
|
|
||||||
job := job{
|
|
||||||
Month: parseInto(sp[4], set.NewBoundSet[int8](1, 12)),
|
|
||||||
Weekday: parseInto(sp[3], set.NewBoundSet[int8](0, 6)),
|
|
||||||
Day: parseInto(sp[2], set.NewBoundSet[int8](1, 31)),
|
|
||||||
Hour: parseInto(sp[1], set.NewBoundSet[int8](0, 23)),
|
|
||||||
Minute: parseInto(sp[0], set.NewBoundSet[int8](0, 59)),
|
|
||||||
Task: task,
|
|
||||||
}
|
|
||||||
c.jobs = append(c.jobs, job)
|
|
||||||
}
|
|
||||||
func (c *cron) RunOnce(ctx context.Context, once func(context.Context, time.Time) error) {
|
|
||||||
c.state.Use(ctx, func(ctx context.Context, state *state) error {
|
|
||||||
state.queue = append(state.queue, once)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cj job) Matches(t time.Time) (ok bool) {
|
|
||||||
return cj.Month.Has(int8(t.Month())) &&
|
|
||||||
cj.Day.Has(int8(t.Day())) &&
|
|
||||||
cj.Weekday.Has(int8(t.Weekday()%7)) &&
|
|
||||||
cj.Hour.Has(int8(t.Hour())) &&
|
|
||||||
cj.Minute.Has(int8(t.Minute()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cj job) String() string {
|
|
||||||
return fmt.Sprintf("job[\n m:%s\n h:%s\n d:%s\n w:%s\n M:%s\n]", cj.Minute, cj.Hour, cj.Day, cj.Weekday, cj.Month)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cron) Run(ctx context.Context) error {
|
|
||||||
tick := time.NewTicker(c.granularity)
|
|
||||||
defer tick.Stop()
|
|
||||||
|
|
||||||
go c.run(ctx, time.Now())
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil
|
|
||||||
case now := <-tick.C:
|
|
||||||
// fmt.Println(now.Second(), now.Hour(), now.Day(), int8(now.Weekday()), uint8(now.Month()))
|
|
||||||
go c.run(ctx, now)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cron) run(ctx context.Context, now time.Time) {
|
|
||||||
var run []task
|
|
||||||
ctx, span := lg.Span(ctx)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Add Jitter
|
|
||||||
timer := time.NewTimer(time.Duration(rand.Intn(300)) * time.Millisecond)
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
timer.Stop()
|
|
||||||
return
|
|
||||||
case <-timer.C:
|
|
||||||
}
|
|
||||||
|
|
||||||
span.AddEvent("Cron Run: " + now.Format(time.RFC822))
|
|
||||||
// fmt.Println("Cron Run: ", now.Format(time.RFC822))
|
|
||||||
|
|
||||||
c.state.Use(ctx, func(ctx context.Context, state *state) error {
|
|
||||||
run = append(run, state.queue...)
|
|
||||||
state.queue = state.queue[:0]
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, j := range c.jobs {
|
|
||||||
if j.Matches(now) {
|
|
||||||
span.AddEvent(j.String())
|
|
||||||
run = append(run, j.Task)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(run) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wg, _ := errgroup.WithContext(ctx)
|
|
||||||
|
|
||||||
for i := range run {
|
|
||||||
fn := run[i]
|
|
||||||
wg.Go(func() error { return fn(ctx, now) })
|
|
||||||
}
|
|
||||||
span.SetAttributes(
|
|
||||||
attribute.String("tick", now.String()),
|
|
||||||
attribute.Int("count", len(run)),
|
|
||||||
)
|
|
||||||
|
|
||||||
err := wg.Wait()
|
|
||||||
span.RecordError(err)
|
|
||||||
}
|
|
|
@ -13,16 +13,17 @@ import (
|
||||||
|
|
||||||
"github.com/tidwall/wal"
|
"github.com/tidwall/wal"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric/instrument/syncint64"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/cache"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
"go.sour.is/pkg/locker"
|
||||||
|
"go.sour.is/pkg/math"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/cache"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/locker"
|
|
||||||
"go.sour.is/ev/pkg/math"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const CachSize = 1000
|
const CachSize = 1000
|
||||||
|
@ -35,10 +36,10 @@ type diskStore struct {
|
||||||
path string
|
path string
|
||||||
openlogs *locker.Locked[openlogs]
|
openlogs *locker.Locked[openlogs]
|
||||||
|
|
||||||
m_disk_open syncint64.Counter
|
m_disk_open metric.Int64Counter
|
||||||
m_disk_evict syncint64.Counter
|
m_disk_evict metric.Int64Counter
|
||||||
m_disk_read syncint64.Counter
|
m_disk_read metric.Int64Counter
|
||||||
m_disk_write syncint64.Counter
|
m_disk_write metric.Int64Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppendOnly = ev.AppendOnly
|
const AppendOnly = ev.AppendOnly
|
||||||
|
@ -53,16 +54,16 @@ func Init(ctx context.Context) error {
|
||||||
m := lg.Meter(ctx)
|
m := lg.Meter(ctx)
|
||||||
var err, errs error
|
var err, errs error
|
||||||
|
|
||||||
d.m_disk_open, err = m.SyncInt64().Counter("disk_open")
|
d.m_disk_open, err = m.Int64Counter("disk_open")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
d.m_disk_evict, err = m.SyncInt64().Counter("disk_evict")
|
d.m_disk_evict, err = m.Int64Counter("disk_evict")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
d.m_disk_read, err = m.SyncInt64().Counter("disk_read")
|
d.m_disk_read, err = m.Int64Counter("disk_read")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
d.m_disk_write, err = m.SyncInt64().Counter("disk_write")
|
d.m_disk_write, err = m.Int64Counter("disk_write")
|
||||||
errs = multierr.Append(errs, err)
|
errs = multierr.Append(errs, err)
|
||||||
|
|
||||||
ev.Register(ctx, "file", d)
|
ev.Register(ctx, "file", d)
|
|
@ -4,7 +4,7 @@ package driver
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Driver interface {
|
type Driver interface {
|
|
@ -5,12 +5,13 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
"go.sour.is/pkg/locker"
|
||||||
|
"go.sour.is/pkg/math"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/locker"
|
|
||||||
"go.sour.is/ev/pkg/math"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type state struct {
|
type state struct {
|
|
@ -5,10 +5,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type projector struct {
|
type projector struct {
|
|
@ -5,10 +5,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/matryer/is"
|
"github.com/matryer/is"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver/projecter"
|
"go.sour.is/ev/pkg/driver/projecter"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockDriver struct {
|
type mockDriver struct {
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/lg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type resolvelinks struct {
|
type resolvelinks struct {
|
|
@ -10,10 +10,10 @@ import (
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/driver"
|
||||||
"go.sour.is/ev/pkg/es/driver"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/locker"
|
"go.sour.is/pkg/locker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type state struct {
|
type state struct {
|
40
pkg/env/env.go
vendored
40
pkg/env/env.go
vendored
|
@ -1,40 +0,0 @@
|
||||||
package env
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Default(name, defaultValue string) string {
|
|
||||||
name = strings.TrimSpace(name)
|
|
||||||
defaultValue = strings.TrimSpace(defaultValue)
|
|
||||||
if v := strings.TrimSpace(os.Getenv(name)); v != "" {
|
|
||||||
log.Println("# ", name, "=", v)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
log.Println("# ", name, "=", defaultValue, "(default)")
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
type secret string
|
|
||||||
|
|
||||||
func (s secret) String() string {
|
|
||||||
if s == "" {
|
|
||||||
return "(nil)"
|
|
||||||
}
|
|
||||||
return "***"
|
|
||||||
}
|
|
||||||
func (s secret) Secret() string {
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
func Secret(name, defaultValue string) secret {
|
|
||||||
name = strings.TrimSpace(name)
|
|
||||||
defaultValue = strings.TrimSpace(defaultValue)
|
|
||||||
if v := strings.TrimSpace(os.Getenv(name)); v != "" {
|
|
||||||
log.Println("# ", name, "=", secret(v))
|
|
||||||
return secret(v)
|
|
||||||
}
|
|
||||||
log.Println("# ", name, "=", secret(defaultValue), "(default)")
|
|
||||||
return secret(defaultValue)
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
type Meta @goModel(model: "go.sour.is/ev/pkg/es/event.Meta") {
|
type Meta @goModel(model: "go.sour.is/ev/pkg/event.Meta") {
|
||||||
eventID: String! @goField(name: "getEventID")
|
eventID: String! @goField(name: "getEventID")
|
||||||
streamID: String! @goField(name: "ActualStreamID")
|
streamID: String! @goField(name: "ActualStreamID")
|
||||||
position: Int! @goField(name: "ActualPosition")
|
position: Int! @goField(name: "ActualPosition")
|
||||||
|
|
|
@ -9,10 +9,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/gql"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
|
||||||
"go.sour.is/ev"
|
"go.sour.is/ev"
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/ev/pkg/event"
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
"go.sour.is/ev/pkg/gql"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type EventResolver interface {
|
type EventResolver interface {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package event_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Agg struct {
|
type Agg struct {
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/matryer/is"
|
"github.com/matryer/is"
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
"go.sour.is/ev/pkg/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DummyEvent struct {
|
type DummyEvent struct {
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/ev/pkg/locker"
|
"go.sour.is/pkg/locker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
|
@ -1,67 +0,0 @@
|
||||||
package gql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/es/event"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Edge interface {
|
|
||||||
IsEdge()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Connection struct {
|
|
||||||
Paging *PageInfo `json:"paging"`
|
|
||||||
Edges []Edge `json:"edges"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostEvent struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Payload string `json:"payload"`
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
Meta *event.Meta `json:"meta"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (PostEvent) IsEdge() {}
|
|
||||||
|
|
||||||
func (e *PostEvent) PayloadJSON(ctx context.Context) (m map[string]interface{}, err error) {
|
|
||||||
err = json.Unmarshal([]byte(e.Payload), &m)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type PageInfo struct {
|
|
||||||
Next bool `json:"next"`
|
|
||||||
Prev bool `json:"prev"`
|
|
||||||
Begin uint64 `json:"begin"`
|
|
||||||
End uint64 `json:"end"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PageInput struct {
|
|
||||||
After *int64 `json:"after"`
|
|
||||||
Before *int64 `json:"before"`
|
|
||||||
Count *int64 `json:"count"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PageInput) GetIdx(v int64) int64 {
|
|
||||||
if p == nil {
|
|
||||||
// pass
|
|
||||||
} else if p.Before != nil {
|
|
||||||
return (*p.Before)
|
|
||||||
} else if p.After != nil {
|
|
||||||
return *p.After
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
func (p *PageInput) GetCount(v int64) int64 {
|
|
||||||
if p == nil || p.Count == nil {
|
|
||||||
return v
|
|
||||||
} else if p.Before != nil {
|
|
||||||
return -(*p.Count)
|
|
||||||
} else if p.After != nil {
|
|
||||||
return *p.Count
|
|
||||||
}
|
|
||||||
|
|
||||||
return *p.Count
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package gql
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
func ToContext[K comparable, V any](ctx context.Context, key K, value V) context.Context {
|
|
||||||
return context.WithValue(ctx, key, value)
|
|
||||||
}
|
|
||||||
func FromContext[K comparable, V any](ctx context.Context, key K) V {
|
|
||||||
var empty V
|
|
||||||
if v, ok := ctx.Value(key).(V); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return empty
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
package graphiql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>{{.title}}</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#graphiql {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script
|
|
||||||
src="https://cdn.jsdelivr.net/npm/react@{{.reactVersion}}/umd/react.production.min.js"
|
|
||||||
integrity="{{.reactSRI}}"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
src="https://cdn.jsdelivr.net/npm/react-dom@{{.reactVersion}}/umd/react-dom.production.min.js"
|
|
||||||
integrity="{{.reactDOMSRI}}"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
></script>
|
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
|
||||||
href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
|
|
||||||
x-integrity="{{.cssSRI}}"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="graphiql">Loading...</div>
|
|
||||||
|
|
||||||
<script
|
|
||||||
src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
|
|
||||||
x-integrity="{{.jsSRI}}"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
{{- if .endpointIsAbsolute}}
|
|
||||||
const url = {{.endpoint}};
|
|
||||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
|
||||||
{{- else}}
|
|
||||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
|
||||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
|
||||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
|
||||||
{{- end}}
|
|
||||||
|
|
||||||
const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl });
|
|
||||||
ReactDOM.render(
|
|
||||||
React.createElement(GraphiQL, {
|
|
||||||
fetcher: fetcher,
|
|
||||||
isHeadersEditorEnabled: true,
|
|
||||||
shouldPersistHeaders: true
|
|
||||||
}),
|
|
||||||
document.getElementById('graphiql'),
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`))
|
|
||||||
|
|
||||||
// Handler responsible for setting up the playground
|
|
||||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
|
|
||||||
err := page.Execute(w, map[string]interface{}{
|
|
||||||
"title": title,
|
|
||||||
"endpoint": endpoint,
|
|
||||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
|
||||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
|
||||||
"version": "2.4.1",
|
|
||||||
"reactVersion": "17.0.2",
|
|
||||||
"cssSRI": "sha256-bGeEsMhcAqeXBjh2w0eQzBTFAxwlxhM0PKIKqMshlnk=",
|
|
||||||
"jsSRI": "sha256-s+f7CFAPSUIygFnRC2nfoiEKd3liCUy+snSdYFAoLUc=",
|
|
||||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
|
||||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// endpointHasScheme checks if the endpoint has a scheme.
|
|
||||||
func endpointHasScheme(endpoint string) bool {
|
|
||||||
u, err := url.Parse(endpoint)
|
|
||||||
return err == nil && u.Scheme != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSubscriptionEndpoint returns the subscription endpoint for the given
|
|
||||||
// endpoint if it is parsable as a URL, or an empty string.
|
|
||||||
func getSubscriptionEndpoint(endpoint string) string {
|
|
||||||
u, err := url.Parse(endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
switch u.Scheme {
|
|
||||||
case "https":
|
|
||||||
u.Scheme = "wss"
|
|
||||||
default:
|
|
||||||
u.Scheme = "ws"
|
|
||||||
}
|
|
||||||
|
|
||||||
return u.String()
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package playground
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset=utf-8/>
|
|
||||||
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
|
||||||
<link rel="shortcut icon" href="https://graphcool-playground.netlify.com/favicon.png">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/css/index.css"
|
|
||||||
integrity="{{ .cssSRI }}" crossorigin="anonymous"/>
|
|
||||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/favicon.png"
|
|
||||||
integrity="{{ .faviconSRI }}" crossorigin="anonymous"/>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/js/middleware.js"
|
|
||||||
integrity="{{ .jsSRI }}" crossorigin="anonymous"></script>
|
|
||||||
<title>{{.title}}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<style type="text/css">
|
|
||||||
html { font-family: "Open Sans", sans-serif; overflow: hidden; }
|
|
||||||
body { margin: 0; background: #172a3a; }
|
|
||||||
</style>
|
|
||||||
<div id="root"/>
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener('load', function (event) {
|
|
||||||
const root = document.getElementById('root');
|
|
||||||
root.classList.add('playgroundIn');
|
|
||||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:'
|
|
||||||
GraphQLPlayground.init(root, {
|
|
||||||
endpoint: location.protocol + '//' + location.host + '{{.endpoint}}',
|
|
||||||
subscriptionsEndpoint: wsProto + '//' + location.host + '{{.endpoint }}',
|
|
||||||
shareEnabled: true,
|
|
||||||
settings: {
|
|
||||||
'request.credentials': 'same-origin'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`))
|
|
||||||
|
|
||||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Add("Content-Type", "text/html")
|
|
||||||
err := page.Execute(w, map[string]string{
|
|
||||||
"title": title,
|
|
||||||
"endpoint": endpoint,
|
|
||||||
"version": "1.7.28",
|
|
||||||
"cssSRI": "sha256-dKnNLEFwKSVFpkpjRWe+o/jQDM6n/JsvQ0J3l5Dk3fc=",
|
|
||||||
"faviconSRI": "sha256-GhTyE+McTU79R4+pRO6ih+4TfsTOrpPwD8ReKFzb3PM=",
|
|
||||||
"jsSRI": "sha256-VVwEZwxs4qS5W7E+/9nXINYgr/BJRWKOi/rTMUdmmWg=",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"runtime/debug"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
|
||||||
"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/vektah/gqlparser/v2/gqlerror"
|
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"github.com/ravilushqa/otelgqlgen"
|
|
||||||
|
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
"go.sour.is/ev/pkg/gql/graphiql"
|
|
||||||
"go.sour.is/ev/pkg/gql/playground"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BaseResolver interface {
|
|
||||||
ExecutableSchema() graphql.ExecutableSchema
|
|
||||||
BaseResolver() IsResolver
|
|
||||||
}
|
|
||||||
|
|
||||||
type Resolver[T BaseResolver] struct {
|
|
||||||
res T
|
|
||||||
CheckOrigin func(r *http.Request) bool
|
|
||||||
}
|
|
||||||
type IsResolver interface {
|
|
||||||
IsResolver()
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultCheckOrign = func(r *http.Request) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func New[T BaseResolver](ctx context.Context, base T, resolvers ...IsResolver) (*Resolver[T], error) {
|
|
||||||
_, span := lg.Span(ctx)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
noop := reflect.ValueOf(base.BaseResolver())
|
|
||||||
|
|
||||||
v := reflect.ValueOf(base)
|
|
||||||
v = reflect.Indirect(v)
|
|
||||||
|
|
||||||
outer:
|
|
||||||
for _, idx := range reflect.VisibleFields(v.Type()) {
|
|
||||||
field := v.FieldByIndex(idx.Index)
|
|
||||||
|
|
||||||
for i := range resolvers {
|
|
||||||
rs := reflect.ValueOf(resolvers[i])
|
|
||||||
|
|
||||||
if field.IsNil() && rs.Type().Implements(field.Type()) {
|
|
||||||
// log.Print("found ", field.Type().Name())
|
|
||||||
span.AddEvent(fmt.Sprint("found ", field.Type().Name()))
|
|
||||||
field.Set(rs)
|
|
||||||
continue outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.Print(fmt.Sprint("default ", field.Type().Name()))
|
|
||||||
span.AddEvent(fmt.Sprint("default ", field.Type().Name()))
|
|
||||||
field.Set(noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Resolver[T]{res: base, CheckOrigin: defaultCheckOrign}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver[T]) Resolver() T {
|
|
||||||
return r.res
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainMiddlewares will check all embeded resolvers for a GetMiddleware func and add to handler.
|
|
||||||
func (r *Resolver[T]) ChainMiddlewares(h http.Handler) http.Handler {
|
|
||||||
v := reflect.ValueOf(r.Resolver()) // Get reflected value of *Resolver
|
|
||||||
v = reflect.Indirect(v) // Get the pointed value (returns a zero value on nil)
|
|
||||||
for _, idx := range reflect.VisibleFields(v.Type()) {
|
|
||||||
field := v.FieldByIndex(idx.Index)
|
|
||||||
// log.Print("middleware ", field.Type().Name())
|
|
||||||
|
|
||||||
if !field.CanInterface() { // Skip non-interface types.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if iface, ok := field.Interface().(interface {
|
|
||||||
GetMiddleware() func(http.Handler) http.Handler
|
|
||||||
}); ok {
|
|
||||||
h = iface.GetMiddleware()(h) // Append only items that fulfill the interface.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver[T]) RegisterHTTP(mux *http.ServeMux) {
|
|
||||||
gql := NewServer(r.Resolver().ExecutableSchema(), r.CheckOrigin)
|
|
||||||
gql.SetRecoverFunc(NoopRecover)
|
|
||||||
gql.Use(otelgqlgen.Middleware())
|
|
||||||
mux.Handle("/gql", lg.Htrace(r.ChainMiddlewares(gql), "gql"))
|
|
||||||
mux.Handle("/graphiql", graphiql.Handler("GraphiQL playground", "/gql"))
|
|
||||||
mux.Handle("/playground", playground.Handler("GraphQL playground", "/gql"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NoopRecover(ctx context.Context, err interface{}) error {
|
|
||||||
if err, ok := err.(string); ok && err == "not implemented" {
|
|
||||||
return gqlerror.Errorf("not implemented")
|
|
||||||
}
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
fmt.Fprintln(os.Stderr)
|
|
||||||
debug.PrintStack()
|
|
||||||
|
|
||||||
return gqlerror.Errorf("internal system error")
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServer(es graphql.ExecutableSchema, checkOrigin func(*http.Request) bool) *handler.Server {
|
|
||||||
srv := handler.New(es)
|
|
||||||
|
|
||||||
srv.AddTransport(transport.Websocket{
|
|
||||||
Upgrader: websocket.Upgrader{
|
|
||||||
CheckOrigin: checkOrigin,
|
|
||||||
},
|
|
||||||
KeepAlivePingInterval: 10 * time.Second,
|
|
||||||
})
|
|
||||||
srv.AddTransport(transport.Options{})
|
|
||||||
srv.AddTransport(transport.GET{})
|
|
||||||
srv.AddTransport(transport.POST{})
|
|
||||||
srv.AddTransport(transport.MultipartForm{})
|
|
||||||
|
|
||||||
srv.SetQueryCache(lru.New(1000))
|
|
||||||
|
|
||||||
srv.Use(extension.Introspection{})
|
|
||||||
srv.Use(extension.AutomaticPersistedQuery{
|
|
||||||
Cache: lru.New(100),
|
|
||||||
})
|
|
||||||
|
|
||||||
return srv
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package locker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Locked[T any] struct {
|
|
||||||
state chan *T
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new locker for the given value.
|
|
||||||
func New[T any](initial *T) *Locked[T] {
|
|
||||||
s := &Locked[T]{}
|
|
||||||
s.state = make(chan *T, 1)
|
|
||||||
s.state <- initial
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
type ctxKey struct{ name string }
|
|
||||||
|
|
||||||
// Use will call the function with the locked value
|
|
||||||
func (s *Locked[T]) Use(ctx context.Context, fn func(context.Context, *T) error) error {
|
|
||||||
if s == nil {
|
|
||||||
return fmt.Errorf("locker not initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := ctxKey{fmt.Sprintf("%p", s)}
|
|
||||||
|
|
||||||
if value := ctx.Value(key); value != nil {
|
|
||||||
return fmt.Errorf("%w: %T", ErrNested, s)
|
|
||||||
}
|
|
||||||
ctx = context.WithValue(ctx, key, key)
|
|
||||||
|
|
||||||
ctx, span := lg.Span(ctx)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
var t T
|
|
||||||
span.SetAttributes(
|
|
||||||
attribute.String("typeOf", fmt.Sprintf("%T", t)),
|
|
||||||
)
|
|
||||||
|
|
||||||
if ctx.Err() != nil {
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case state := <-s.state:
|
|
||||||
defer func() { s.state <- state }()
|
|
||||||
return fn(ctx, state)
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy will return a shallow copy of the locked object.
|
|
||||||
func (s *Locked[T]) Copy(ctx context.Context) (T, error) {
|
|
||||||
var t T
|
|
||||||
|
|
||||||
err := s.Use(ctx, func(ctx context.Context, c *T) error {
|
|
||||||
if c != nil {
|
|
||||||
t = *c
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return t, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrNested = errors.New("nested locker call")
|
|
|
@ -1,96 +0,0 @@
|
||||||
package locker_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/locker"
|
|
||||||
)
|
|
||||||
|
|
||||||
type config struct {
|
|
||||||
Value string
|
|
||||||
Counter int
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLocker(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
value := locker.New(&config{})
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
err := value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
c.Value = "one"
|
|
||||||
c.Counter++
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
c, err := value.Copy(context.Background())
|
|
||||||
|
|
||||||
is.NoErr(err)
|
|
||||||
is.Equal(c.Value, "one")
|
|
||||||
is.Equal(c.Counter, 1)
|
|
||||||
|
|
||||||
wait := make(chan struct{})
|
|
||||||
|
|
||||||
go value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
c.Value = "two"
|
|
||||||
c.Counter++
|
|
||||||
close(wait)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
<-wait
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
err = value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
c.Value = "three"
|
|
||||||
c.Counter++
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
is.True(err != nil)
|
|
||||||
|
|
||||||
c, err = value.Copy(context.Background())
|
|
||||||
|
|
||||||
is.NoErr(err)
|
|
||||||
is.Equal(c.Value, "two")
|
|
||||||
is.Equal(c.Counter, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNestedLocker(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
value := locker.New(&config{})
|
|
||||||
other := locker.New(&config{})
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
err := value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
return value.Use(ctx, func(ctx context.Context, t *config) error {
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
is.True(errors.Is(err, locker.ErrNested))
|
|
||||||
|
|
||||||
err = value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
return other.Use(ctx, func(ctx context.Context, t *config) error {
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
err = value.Use(ctx, func(ctx context.Context, c *config) error {
|
|
||||||
return other.Use(ctx, func(ctx context.Context, t *config) error {
|
|
||||||
return value.Use(ctx, func(ctx context.Context, x *config) error {
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
is.True(errors.Is(err, locker.ErrNested))
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package math
|
|
||||||
|
|
||||||
type signed interface {
|
|
||||||
~int | ~int8 | ~int16 | ~int32 | ~int64
|
|
||||||
}
|
|
||||||
type unsigned interface {
|
|
||||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
|
|
||||||
}
|
|
||||||
type integer interface {
|
|
||||||
signed | unsigned
|
|
||||||
}
|
|
||||||
type float interface {
|
|
||||||
~float32 | ~float64
|
|
||||||
}
|
|
||||||
type ordered interface {
|
|
||||||
integer | float | ~string
|
|
||||||
}
|
|
||||||
|
|
||||||
func Abs[T signed](i T) T {
|
|
||||||
if i > 0 {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
return -i
|
|
||||||
}
|
|
||||||
func Max[T ordered](i T, candidates ...T) T {
|
|
||||||
for _, j := range candidates {
|
|
||||||
if i < j {
|
|
||||||
i = j
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
func Min[T ordered](i T, candidates ...T) T {
|
|
||||||
for _, j := range candidates {
|
|
||||||
if i > j {
|
|
||||||
i = j
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
func PagerBox(first, last uint64, pos, count int64) (uint64, int64) {
|
|
||||||
var start uint64
|
|
||||||
|
|
||||||
if pos >= 0 {
|
|
||||||
if int64(first) > pos {
|
|
||||||
start = first
|
|
||||||
} else {
|
|
||||||
start = uint64(pos) + 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
start = uint64(int64(last) + pos + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case count > 0:
|
|
||||||
count = Min(count, int64(last-start)+1)
|
|
||||||
|
|
||||||
case pos >= 0 && count < 0:
|
|
||||||
count = Max(count, int64(first-start))
|
|
||||||
|
|
||||||
case pos < 0 && count < 0:
|
|
||||||
count = Max(count, int64(first-start)-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if count == 0 || (start < first && count <= 0) || (start > last && count >= 0) {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return start, count
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package math_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev"
|
|
||||||
"go.sour.is/ev/pkg/math"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMath(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
is.Equal(5, math.Abs(-5))
|
|
||||||
is.Equal(math.Abs(5), math.Abs(-5))
|
|
||||||
|
|
||||||
is.Equal(10, math.Max(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
|
|
||||||
is.Equal(1, math.Min(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
|
|
||||||
|
|
||||||
is.Equal(1, math.Min(89, 71, 54, 48, 49, 1, 72, 88, 25, 69))
|
|
||||||
is.Equal(89, math.Max(89, 71, 54, 48, 49, 1, 72, 88, 25, 69))
|
|
||||||
|
|
||||||
is.Equal(0.9348207729, math.Max(
|
|
||||||
0.3943310720,
|
|
||||||
0.1090868377,
|
|
||||||
0.9348207729,
|
|
||||||
0.3525527584,
|
|
||||||
0.4359833682,
|
|
||||||
0.7958538081,
|
|
||||||
0.1439352569,
|
|
||||||
0.1547311967,
|
|
||||||
0.6403818871,
|
|
||||||
0.8618832818,
|
|
||||||
))
|
|
||||||
|
|
||||||
is.Equal(0.1090868377, math.Min(
|
|
||||||
0.3943310720,
|
|
||||||
0.1090868377,
|
|
||||||
0.9348207729,
|
|
||||||
0.3525527584,
|
|
||||||
0.4359833682,
|
|
||||||
0.7958538081,
|
|
||||||
0.1439352569,
|
|
||||||
0.1547311967,
|
|
||||||
0.6403818871,
|
|
||||||
0.8618832818,
|
|
||||||
))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPagerBox(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
first uint64
|
|
||||||
last uint64
|
|
||||||
pos int64
|
|
||||||
n int64
|
|
||||||
|
|
||||||
start uint64
|
|
||||||
count int64
|
|
||||||
}{
|
|
||||||
{1, 10, 0, 10, 1, 10},
|
|
||||||
{1, 10, 0, 11, 1, 10},
|
|
||||||
{1, 5, 0, 10, 1, 5},
|
|
||||||
{1, 10, 4, 10, 5, 6},
|
|
||||||
{1, 10, 5, 10, 6, 5},
|
|
||||||
{1, 10, 0, -10, 0, 0},
|
|
||||||
{1, 10, 1, -1, 2, -1},
|
|
||||||
{1, 10, 1, -10, 2, -1},
|
|
||||||
{1, 10, -1, 1, 10, 1},
|
|
||||||
{1, 10, -2, 10, 9, 2},
|
|
||||||
{1, 10, -1, -1, 10, -1},
|
|
||||||
{1, 10, -2, -10, 9, -9},
|
|
||||||
{1, 10, 0, -10, 0, 0},
|
|
||||||
{1, 10, 10, 10, 0, 0},
|
|
||||||
{1, 10, 0, ev.AllEvents, 1, 10},
|
|
||||||
{1, 10, -1, -ev.AllEvents, 10, -10},
|
|
||||||
|
|
||||||
{5, 10, 0, 1, 5, 1},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
start, count := math.PagerBox(tt.first, tt.last, tt.pos, tt.n)
|
|
||||||
if count > 0 {
|
|
||||||
t.Log(tt, "|", start, count, int64(start)+count-1)
|
|
||||||
} else {
|
|
||||||
t.Log(tt, "|", start, count, int64(start)+count+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
is.Equal(start, tt.start)
|
|
||||||
is.Equal(count, tt.count)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package mux
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mux struct {
|
|
||||||
*http.ServeMux
|
|
||||||
api *http.ServeMux
|
|
||||||
wellknown *http.ServeMux
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mux *mux) Add(fns ...interface{ RegisterHTTP(*http.ServeMux) }) {
|
|
||||||
for _, fn := range fns {
|
|
||||||
// log.Printf("HTTP: %T", fn)
|
|
||||||
fn.RegisterHTTP(mux.ServeMux)
|
|
||||||
|
|
||||||
if fn, ok := fn.(interface{ RegisterAPIv1(*http.ServeMux) }); ok {
|
|
||||||
// log.Printf("APIv1: %T", fn)
|
|
||||||
fn.RegisterAPIv1(mux.api)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fn, ok := fn.(interface{ RegisterWellKnown(*http.ServeMux) }); ok {
|
|
||||||
// log.Printf("WellKnown: %T", fn)
|
|
||||||
fn.RegisterWellKnown(mux.wellknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func New() *mux {
|
|
||||||
mux := &mux{
|
|
||||||
api: http.NewServeMux(),
|
|
||||||
wellknown: http.NewServeMux(),
|
|
||||||
ServeMux: http.NewServeMux(),
|
|
||||||
}
|
|
||||||
mux.Handle("/api/v1/", http.StripPrefix("/api/v1", mux.api))
|
|
||||||
mux.Handle("/.well-known/", http.StripPrefix("/.well-known", mux.wellknown))
|
|
||||||
|
|
||||||
return mux
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterHTTP func(*http.ServeMux)
|
|
||||||
|
|
||||||
func (fn RegisterHTTP) RegisterHTTP(mux *http.ServeMux) { fn(mux) }
|
|
|
@ -1,104 +0,0 @@
|
||||||
package mux_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev/pkg/mux"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mockHTTP struct {
|
|
||||||
onServeHTTP func()
|
|
||||||
onServeAPIv1 func()
|
|
||||||
onServeWellKnown func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*mockHTTP) ServeFn(fn func()) func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) { fn() }
|
|
||||||
}
|
|
||||||
func (h *mockHTTP) RegisterHTTP(mux *http.ServeMux) {
|
|
||||||
mux.HandleFunc("/", h.ServeFn(h.onServeHTTP))
|
|
||||||
}
|
|
||||||
func (h *mockHTTP) RegisterAPIv1(mux *http.ServeMux) {
|
|
||||||
mux.HandleFunc("/ping", h.ServeFn(h.onServeAPIv1))
|
|
||||||
}
|
|
||||||
func (h *mockHTTP) RegisterWellKnown(mux *http.ServeMux) {
|
|
||||||
mux.HandleFunc("/echo", h.ServeFn(h.onServeWellKnown))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHttp(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
calledAPIv1 := false
|
|
||||||
calledWellKnown := false
|
|
||||||
|
|
||||||
mux := mux.New()
|
|
||||||
mux.Add(&mockHTTP{
|
|
||||||
func() { called = true },
|
|
||||||
func() { calledAPIv1 = true },
|
|
||||||
func() { calledWellKnown = true },
|
|
||||||
})
|
|
||||||
|
|
||||||
is.True(mux != nil)
|
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
||||||
mux.ServeHTTP(w, r)
|
|
||||||
|
|
||||||
is.True(called)
|
|
||||||
is.True(!calledAPIv1)
|
|
||||||
is.True(!calledWellKnown)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHttpAPIv1(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
calledAPIv1 := false
|
|
||||||
calledWellKnown := false
|
|
||||||
|
|
||||||
mux := mux.New()
|
|
||||||
mux.Add(&mockHTTP{
|
|
||||||
func() { called = true },
|
|
||||||
func() { calledAPIv1 = true },
|
|
||||||
func() { calledWellKnown = true },
|
|
||||||
})
|
|
||||||
|
|
||||||
is.True(mux != nil)
|
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
r := httptest.NewRequest(http.MethodGet, "/api/v1/ping", nil)
|
|
||||||
mux.ServeHTTP(w, r)
|
|
||||||
|
|
||||||
is.True(!called)
|
|
||||||
is.True(calledAPIv1)
|
|
||||||
is.True(!calledWellKnown)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHttpWellKnown(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
calledAPIv1 := false
|
|
||||||
calledWellKnown := false
|
|
||||||
|
|
||||||
mux := mux.New()
|
|
||||||
mux.Add(&mockHTTP{
|
|
||||||
func() { called = true },
|
|
||||||
func() { calledAPIv1 = true },
|
|
||||||
func() { calledWellKnown = true },
|
|
||||||
})
|
|
||||||
|
|
||||||
is.True(mux != nil)
|
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
r := httptest.NewRequest(http.MethodGet, "/.well-known/echo", nil)
|
|
||||||
mux.ServeHTTP(w, r)
|
|
||||||
|
|
||||||
is.True(!called)
|
|
||||||
is.True(!calledAPIv1)
|
|
||||||
is.True(calledWellKnown)
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"runtime/debug"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.sour.is/ev/internal/lg"
|
|
||||||
"go.sour.is/ev/pkg/cron"
|
|
||||||
"go.uber.org/multierr"
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
)
|
|
||||||
|
|
||||||
type crontab interface {
|
|
||||||
NewCron(expr string, task func(context.Context, time.Time) error)
|
|
||||||
RunOnce(ctx context.Context, once func(context.Context, time.Time) error)
|
|
||||||
}
|
|
||||||
type Harness struct {
|
|
||||||
crontab
|
|
||||||
|
|
||||||
Services []any
|
|
||||||
|
|
||||||
onStart []func(context.Context) error
|
|
||||||
onRunning chan struct{}
|
|
||||||
onStop []func(context.Context) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Harness) Setup(ctx context.Context, apps ...application) error {
|
|
||||||
ctx, span := lg.Span(ctx)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// setup crontab
|
|
||||||
c := cron.New(cron.DefaultGranularity)
|
|
||||||
s.OnStart(c.Run)
|
|
||||||
s.onRunning = make(chan struct{})
|
|
||||||
s.crontab = c
|
|
||||||
|
|
||||||
var err error
|
|
||||||
for _, app := range apps {
|
|
||||||
err = multierr.Append(err, app(ctx, s))
|
|
||||||
}
|
|
||||||
|
|
||||||
span.RecordError(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
func (s *Harness) OnStart(fn func(context.Context) error) {
|
|
||||||
s.onStart = append(s.onStart, fn)
|
|
||||||
}
|
|
||||||
func (s *Harness) OnRunning() <-chan struct{} {
|
|
||||||
return s.onRunning
|
|
||||||
}
|
|
||||||
func (s *Harness) OnStop(fn func(context.Context) error) {
|
|
||||||
s.onStop = append(s.onStop, fn)
|
|
||||||
}
|
|
||||||
func (s *Harness) Add(svcs ...any) {
|
|
||||||
s.Services = append(s.Services, svcs...)
|
|
||||||
}
|
|
||||||
func (s *Harness) stop(ctx context.Context) error {
|
|
||||||
g, _ := errgroup.WithContext(ctx)
|
|
||||||
for i := range s.onStop {
|
|
||||||
fn := s.onStop[i]
|
|
||||||
g.Go(func() error {
|
|
||||||
if err := fn(ctx); err != nil && err != http.ErrServerClosed {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return g.Wait()
|
|
||||||
}
|
|
||||||
func (s *Harness) Run(ctx context.Context, appName, version string) error {
|
|
||||||
{
|
|
||||||
ctx, span := lg.Span(ctx)
|
|
||||||
|
|
||||||
log.Println(appName, version)
|
|
||||||
span.SetAttributes(
|
|
||||||
attribute.String("app", appName),
|
|
||||||
attribute.String("version", version),
|
|
||||||
)
|
|
||||||
|
|
||||||
Mup, err := lg.Meter(ctx).SyncInt64().UpDownCounter("up")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
Mup.Add(ctx, 1)
|
|
||||||
|
|
||||||
span.End()
|
|
||||||
}
|
|
||||||
|
|
||||||
g, _ := errgroup.WithContext(ctx)
|
|
||||||
g.Go(func() error {
|
|
||||||
<-ctx.Done()
|
|
||||||
// shutdown jobs
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
return s.stop(ctx)
|
|
||||||
})
|
|
||||||
|
|
||||||
for i := range s.onStart {
|
|
||||||
fn := s.onStart[i]
|
|
||||||
g.Go(func() error { return fn(ctx) })
|
|
||||||
}
|
|
||||||
|
|
||||||
close(s.onRunning)
|
|
||||||
|
|
||||||
err := g.Wait()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type application func(context.Context, *Harness) error // Len is the number of elements in the collection.
|
|
||||||
|
|
||||||
type appscore struct {
|
|
||||||
score int
|
|
||||||
application
|
|
||||||
}
|
|
||||||
type Apps []appscore
|
|
||||||
|
|
||||||
func (a *Apps) Apps() []application {
|
|
||||||
sort.Sort(a)
|
|
||||||
lis := make([]application, len(*a))
|
|
||||||
for i, app := range *a {
|
|
||||||
lis[i] = app.application
|
|
||||||
}
|
|
||||||
return lis
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len is the number of elements in the collection.
|
|
||||||
func (a *Apps) Len() int {
|
|
||||||
if a == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return len(*a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less reports whether the element with index i
|
|
||||||
func (a *Apps) Less(i int, j int) bool {
|
|
||||||
if a == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*a)[i].score < (*a)[j].score
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps the elements with indexes i and j.
|
|
||||||
func (a *Apps) Swap(i int, j int) {
|
|
||||||
if a == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
(*a)[i], (*a)[j] = (*a)[j], (*a)[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Apps) Register(score int, app application) (none struct{}) {
|
|
||||||
if a == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
*a = append(*a, appscore{score, app})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func AppName() (string, string) {
|
|
||||||
if info, ok := debug.ReadBuildInfo(); ok {
|
|
||||||
_, name, _ := strings.Cut(info.Main.Path, "/")
|
|
||||||
name = strings.Replace(name, "-", ".", -1)
|
|
||||||
name = strings.Replace(name, "/", "-", -1)
|
|
||||||
return name, info.Main.Version
|
|
||||||
}
|
|
||||||
|
|
||||||
return "sour.is-app", "(devel)"
|
|
||||||
}
|
|
137
pkg/set/set.go
137
pkg/set/set.go
|
@ -1,137 +0,0 @@
|
||||||
package set
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.sour.is/ev/pkg/math"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Set[T comparable] map[T]struct{}
|
|
||||||
|
|
||||||
func New[T comparable](items ...T) Set[T] {
|
|
||||||
s := make(map[T]struct{}, len(items))
|
|
||||||
for i := range items {
|
|
||||||
s[items[i]] = struct{}{}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
func (s Set[T]) Has(v T) bool {
|
|
||||||
_, ok := (s)[v]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
func (s Set[T]) Add(items ...T) Set[T] {
|
|
||||||
for _, i := range items {
|
|
||||||
s[i] = struct{}{}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
func (s Set[T]) Delete(items ...T) Set[T] {
|
|
||||||
for _, i := range items {
|
|
||||||
delete(s, i)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Set[T]) Equal(e Set[T]) bool {
|
|
||||||
for k := range s {
|
|
||||||
if _, ok := e[k]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for k := range e {
|
|
||||||
if _, ok := s[k]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Set[T]) String() string {
|
|
||||||
if s == nil {
|
|
||||||
return "set(<nil>)"
|
|
||||||
}
|
|
||||||
lis := make([]string, 0, len(s))
|
|
||||||
for k := range s {
|
|
||||||
lis = append(lis, fmt.Sprint(k))
|
|
||||||
}
|
|
||||||
|
|
||||||
var b strings.Builder
|
|
||||||
b.WriteString("set(")
|
|
||||||
b.WriteString(strings.Join(lis, ","))
|
|
||||||
b.WriteString(")")
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type ordered interface {
|
|
||||||
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
|
||||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
|
||||||
~float32 | ~float64
|
|
||||||
}
|
|
||||||
|
|
||||||
type BoundSet[T ordered] struct {
|
|
||||||
min, max T
|
|
||||||
s Set[T]
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBoundSet[T ordered](min, max T, items ...T) *BoundSet[T] {
|
|
||||||
b := &BoundSet[T]{
|
|
||||||
min: min,
|
|
||||||
max: max,
|
|
||||||
s: New[T](),
|
|
||||||
}
|
|
||||||
b.Add(items...)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
func (l *BoundSet[T]) Add(items ...T) *BoundSet[T] {
|
|
||||||
n := 0
|
|
||||||
for i := range items {
|
|
||||||
if items[i] >= l.min && items[i] <= l.max {
|
|
||||||
items[n] = items[i]
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
l.s.Add(items[:n]...)
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
func (l *BoundSet[T]) AddRange(min, max T) {
|
|
||||||
min = math.Max(min, l.min)
|
|
||||||
max = math.Min(max, l.max)
|
|
||||||
var lis []T
|
|
||||||
for ; min <= max; min++ {
|
|
||||||
lis = append(lis, min)
|
|
||||||
}
|
|
||||||
l.s.Add(lis...)
|
|
||||||
}
|
|
||||||
func (l *BoundSet[T]) Delete(items ...T) *BoundSet[T] {
|
|
||||||
n := 0
|
|
||||||
for i := range items {
|
|
||||||
if items[i] >= l.min && items[i] <= l.max {
|
|
||||||
items[n] = items[i]
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
l.s.Delete(items[:n]...)
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
func (l *BoundSet[T]) Has(v T) bool {
|
|
||||||
return l.s.Has(v)
|
|
||||||
}
|
|
||||||
func (l *BoundSet[T]) String() string {
|
|
||||||
lis := make([]string, len(l.s))
|
|
||||||
n := 0
|
|
||||||
for k := range l.s {
|
|
||||||
lis[n] = fmt.Sprint(k)
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
sort.Strings(lis)
|
|
||||||
|
|
||||||
var b strings.Builder
|
|
||||||
b.WriteString("set(")
|
|
||||||
b.WriteString(strings.Join(lis, ","))
|
|
||||||
b.WriteString(")")
|
|
||||||
return b.String()
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package set_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev/pkg/set"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStringSet(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
s := set.New(strings.Fields("one two three")...)
|
|
||||||
|
|
||||||
is.True(s.Has("one"))
|
|
||||||
is.True(s.Has("two"))
|
|
||||||
is.True(s.Has("three"))
|
|
||||||
is.True(!s.Has("four"))
|
|
||||||
|
|
||||||
is.Equal(set.New("one").String(), "set(one)")
|
|
||||||
|
|
||||||
var n set.Set[string]
|
|
||||||
is.Equal(n.String(), "set(<nil>)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBoundSet(t *testing.T) {
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
s := set.NewBoundSet(1, 100, 1, 2, 3, 100, 1001)
|
|
||||||
|
|
||||||
is.True(s.Has(1))
|
|
||||||
is.True(s.Has(2))
|
|
||||||
is.True(s.Has(3))
|
|
||||||
is.True(!s.Has(1001))
|
|
||||||
|
|
||||||
is.Equal(set.NewBoundSet(1, 100, 1).String(), "set(1)")
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
package slice
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.sour.is/ev/pkg/math"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FilterType returns a subset that matches the type.
|
|
||||||
func FilterType[T any](in ...any) []T {
|
|
||||||
lis := make([]T, 0, len(in))
|
|
||||||
for _, u := range in {
|
|
||||||
if t, ok := u.(T); ok {
|
|
||||||
lis = append(lis, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lis
|
|
||||||
}
|
|
||||||
|
|
||||||
func FilterFn[T any](fn func(T) bool, in ...T) []T {
|
|
||||||
lis := make([]T, 0, len(in))
|
|
||||||
for _, t := range in {
|
|
||||||
if fn(t) {
|
|
||||||
lis = append(lis, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lis
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find returns the first of type found. or false if not found.
|
|
||||||
func Find[T any](in ...any) (T, bool) {
|
|
||||||
return First(FilterType[T](in...)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindFn[T any](fn func(T) bool, in ...T) (T, bool) {
|
|
||||||
return First(FilterFn(fn, in...)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// First returns the first element in a slice.
|
|
||||||
func First[T any](in ...T) (T, bool) {
|
|
||||||
if len(in) == 0 {
|
|
||||||
var zero T
|
|
||||||
return zero, false
|
|
||||||
}
|
|
||||||
return in[0], true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map applys func to each element s and returns results as slice.
|
|
||||||
func Map[T, U any](f func(int, T) U) func(...T) []U {
|
|
||||||
return func(lis ...T) []U {
|
|
||||||
r := make([]U, len(lis))
|
|
||||||
for i, v := range lis {
|
|
||||||
r[i] = f(i, v)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Reduce[T, R any](r R, fn func(T, R, int) R) func(...T) R {
|
|
||||||
return func(lis ...T) R {
|
|
||||||
for i, t := range lis {
|
|
||||||
r = fn(t, r, i)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pair[K comparable, V any] struct {
|
|
||||||
Key K
|
|
||||||
Value V
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromMap[K comparable, V any](m map[K]V) (keys []K, values []V) {
|
|
||||||
if m == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = FromMapKeys(m)
|
|
||||||
return keys, FromMapValues(m, keys)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromMapKeys[K comparable, V any](m map[K]V) (keys []K) {
|
|
||||||
if m == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = make([]K, 0, len(m))
|
|
||||||
|
|
||||||
for k := range m {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromMapValues[K comparable, V any](m map[K]V, keys []K) (values []V) {
|
|
||||||
if m == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
values = make([]V, 0, len(keys))
|
|
||||||
for _, k := range keys {
|
|
||||||
values = append(values, m[k])
|
|
||||||
}
|
|
||||||
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func ToMap[K comparable, V any](keys []K, values []V) (m map[K]V) {
|
|
||||||
m = make(map[K]V, len(keys))
|
|
||||||
|
|
||||||
for i := range keys {
|
|
||||||
if len(values) < i {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
m[keys[i]] = values[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func Zip[K comparable, V any](k []K, v []V) []Pair[K, V] {
|
|
||||||
lis := make([]Pair[K, V], math.Max(len(k), len(v)))
|
|
||||||
for i := range lis {
|
|
||||||
if k != nil && len(k) > i {
|
|
||||||
lis[i].Key = k[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil && len(v) > i {
|
|
||||||
lis[i].Value = v[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lis
|
|
||||||
}
|
|
||||||
|
|
||||||
func Align[T any](k []T, v []T, less func(T, T) bool) []Pair[*T, *T] {
|
|
||||||
lis := make([]Pair[*T, *T], 0, math.Max(len(k), len(v)))
|
|
||||||
|
|
||||||
var j int
|
|
||||||
|
|
||||||
for i := 0; i < len(k); {
|
|
||||||
if j >= len(v) || less(k[i], v[j]) {
|
|
||||||
lis = append(lis, Pair[*T, *T]{&k[i], nil})
|
|
||||||
i++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if less(v[j], k[i]) {
|
|
||||||
lis = append(lis, Pair[*T, *T]{nil, &v[j]})
|
|
||||||
j++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
lis = append(lis, Pair[*T, *T]{&k[i], &v[j]})
|
|
||||||
i++
|
|
||||||
j++
|
|
||||||
}
|
|
||||||
for ; j < len(v); j++ {
|
|
||||||
lis = append(lis, Pair[*T, *T]{nil, &v[j]})
|
|
||||||
}
|
|
||||||
|
|
||||||
return lis
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package slice_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/matryer/is"
|
|
||||||
"go.sour.is/ev/pkg/slice"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAlign(t *testing.T) {
|
|
||||||
type testCase struct {
|
|
||||||
left, right []string
|
|
||||||
combined []slice.Pair[*string, *string]
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []testCase{
|
|
||||||
{
|
|
||||||
left: []string{"1", "3", "5"},
|
|
||||||
right: []string{"2", "3", "4"},
|
|
||||||
combined: []slice.Pair[*string, *string]{
|
|
||||||
{ptr("1"), nil},
|
|
||||||
{nil, ptr("2")},
|
|
||||||
{ptr("3"), ptr("3")},
|
|
||||||
{nil, ptr("4")},
|
|
||||||
{ptr("5"), nil},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
left: []string{"2", "3", "4"},
|
|
||||||
right: []string{"1", "3", "5"},
|
|
||||||
combined: []slice.Pair[*string, *string]{
|
|
||||||
{nil, ptr("1")},
|
|
||||||
{ptr("2"), nil},
|
|
||||||
{ptr("3"), ptr("3")},
|
|
||||||
{ptr("4"), nil},
|
|
||||||
{nil, ptr("5")},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
is := is.New(t)
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
combined := slice.Align(tt.left, tt.right, func(l, r string) bool { return l < r })
|
|
||||||
is.Equal(len(combined), len(tt.combined))
|
|
||||||
for i := range combined {
|
|
||||||
is.Equal(combined[i], tt.combined[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ptr[T any](v T) *T { return &v }
|
|
Loading…
Reference in New Issue
Block a user