From 0f665d3484f38cc8b2d984717affba53f463f49e Mon Sep 17 00:00:00 2001 From: xuu Date: Wed, 12 Jul 2023 17:35:02 -0600 Subject: [PATCH] refactor: split go-pkg --- {pkg => app}/gql/common.graphqls | 8 +- app/gql/resolver.go | 5 +- app/msgbus/service.go | 37 +- app/peerfinder/ev-info.go | 2 +- app/peerfinder/ev-peer.go | 5 +- app/peerfinder/ev-request.go | 4 +- app/peerfinder/http.go | 5 +- app/peerfinder/jobs.go | 6 +- app/peerfinder/service.go | 9 +- app/salty/blobs.go | 25 +- app/salty/salty-addr.go | 2 +- app/salty/salty-user.go | 4 +- app/salty/service.go | 54 +- app/webfinger/events.go | 2 +- app/webfinger/jrd.go | 7 +- app/webfinger/jrd_test.go | 10 +- app/webfinger/webfinger.go | 7 +- cmd/ev/app.msgbus.go | 8 +- cmd/ev/app.peerfinder.go | 11 +- cmd/ev/app.salty.go | 8 +- cmd/ev/app.twtxt.go | 4 +- cmd/ev/app.webfinger.go | 9 +- cmd/ev/main.go | 4 +- cmd/ev/svc.es.go | 23 +- cmd/ev/svc.gql.go | 11 +- cmd/ev/svc.http.go | 11 +- cmd/webfinger-cli/main.go | 2 +- cmd/webfinger-cli/xdg/path_darwin.go | 30 - cmd/webfinger-cli/xdg/path_linux.go | 30 - cmd/webfinger-cli/xdg/path_windows.go | 30 - cmd/webfinger-cli/xdg/xdg.go | 52 -- ev.go | 30 +- ev_test.go | 10 +- go.mod | 86 +- go.sum | 243 ++---- internal/graph/generated/generated.go | 761 +++++++++++------- internal/graph/generated/pkg.go | 1 + internal/graph/resolver/resolver.go | 3 +- internal/lg/init.go | 68 -- internal/lg/logger.go | 111 --- internal/lg/metric.go | 103 --- internal/lg/tracer.go | 176 ---- pkg/authreq/authreq.go | 131 --- pkg/authreq/authreq_test.go | 104 --- pkg/cache/cache.go | 238 ------ pkg/cache/cache_test.go | 131 --- pkg/cache/list.go | 235 ------ pkg/cache/lru.go | 175 ---- pkg/cron/cron.go | 160 ---- pkg/{es => }/driver/disk-store/disk-store.go | 31 +- pkg/{es => }/driver/driver.go | 2 +- pkg/{es => }/driver/mem-store/mem-store.go | 11 +- pkg/{es => }/driver/projecter/projecter.go | 7 +- .../driver/projecter/projector_test.go | 7 +- .../driver/resolve-links/resolve-links.go | 6 +- pkg/{es => }/driver/streamer/streamer.go | 8 +- pkg/env/env.go | 40 - pkg/es/es.graphqls | 2 +- pkg/es/graph.go | 7 +- pkg/{es => }/event/aggregate.go | 0 pkg/{es => }/event/aggregate_test.go | 2 +- pkg/{es => }/event/events.go | 0 pkg/{es => }/event/events_test.go | 2 +- pkg/{es => }/event/reflect.go | 4 +- pkg/gql/connection.go | 67 -- pkg/gql/context.go | 14 - pkg/gql/graphiql/playground.go | 120 --- pkg/gql/playground/playground.go | 62 -- pkg/gql/resolver/resolver.go | 143 ---- pkg/locker/locker.go | 74 -- pkg/locker/locker_test.go | 96 --- pkg/math/math.go | 71 -- pkg/math/math_test.go | 94 --- pkg/mux/httpmux.go | 43 - pkg/mux/httpmux_test.go | 104 --- pkg/service/service.go | 178 ---- pkg/set/set.go | 137 ---- pkg/set/set_test.go | 39 - pkg/slice/slice.go | 163 ---- pkg/slice/slice_test.go | 53 -- 80 files changed, 785 insertions(+), 3993 deletions(-) rename {pkg => app}/gql/common.graphqls (66%) delete mode 100644 cmd/webfinger-cli/xdg/path_darwin.go delete mode 100644 cmd/webfinger-cli/xdg/path_linux.go delete mode 100644 cmd/webfinger-cli/xdg/path_windows.go delete mode 100644 cmd/webfinger-cli/xdg/xdg.go create mode 100644 internal/graph/generated/pkg.go delete mode 100644 internal/lg/init.go delete mode 100644 internal/lg/logger.go delete mode 100644 internal/lg/metric.go delete mode 100644 internal/lg/tracer.go delete mode 100644 pkg/authreq/authreq.go delete mode 100644 pkg/authreq/authreq_test.go delete mode 100644 pkg/cache/cache.go delete mode 100644 pkg/cache/cache_test.go delete mode 100644 pkg/cache/list.go delete mode 100644 pkg/cache/lru.go delete mode 100644 pkg/cron/cron.go rename pkg/{es => }/driver/disk-store/disk-store.go (94%) rename pkg/{es => }/driver/driver.go (97%) rename pkg/{es => }/driver/mem-store/mem-store.go (97%) rename pkg/{es => }/driver/projecter/projecter.go (97%) rename pkg/{es => }/driver/projecter/projector_test.go (96%) rename pkg/{es => }/driver/resolve-links/resolve-links.go (97%) rename pkg/{es => }/driver/streamer/streamer.go (98%) delete mode 100644 pkg/env/env.go rename pkg/{es => }/event/aggregate.go (100%) rename pkg/{es => }/event/aggregate_test.go (95%) rename pkg/{es => }/event/events.go (100%) rename pkg/{es => }/event/events_test.go (98%) rename pkg/{es => }/event/reflect.go (99%) delete mode 100644 pkg/gql/connection.go delete mode 100644 pkg/gql/context.go delete mode 100644 pkg/gql/graphiql/playground.go delete mode 100644 pkg/gql/playground/playground.go delete mode 100644 pkg/gql/resolver/resolver.go delete mode 100644 pkg/locker/locker.go delete mode 100644 pkg/locker/locker_test.go delete mode 100644 pkg/math/math.go delete mode 100644 pkg/math/math_test.go delete mode 100644 pkg/mux/httpmux.go delete mode 100644 pkg/mux/httpmux_test.go delete mode 100644 pkg/service/service.go delete mode 100644 pkg/set/set.go delete mode 100644 pkg/set/set_test.go delete mode 100644 pkg/slice/slice.go delete mode 100644 pkg/slice/slice_test.go diff --git a/pkg/gql/common.graphqls b/app/gql/common.graphqls similarity index 66% rename from pkg/gql/common.graphqls rename to app/gql/common.graphqls index 8334319..e5c3fa9 100644 --- a/pkg/gql/common.graphqls +++ b/app/gql/common.graphqls @@ -1,23 +1,23 @@ scalar Time 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! 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 before: Int 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! prev: Boolean! begin: 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! } diff --git a/app/gql/resolver.go b/app/gql/resolver.go index aaa7a84..658e391 100644 --- a/app/gql/resolver.go +++ b/app/gql/resolver.go @@ -4,12 +4,13 @@ import ( "context" "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/salty" "go.sour.is/ev/internal/graph/generated" "go.sour.is/ev/pkg/es" - "go.sour.is/ev/pkg/gql" - "go.sour.is/ev/pkg/gql/resolver" ) type Resolver struct { diff --git a/app/msgbus/service.go b/app/msgbus/service.go index 8303222..a15091a 100644 --- a/app/msgbus/service.go +++ b/app/msgbus/service.go @@ -14,24 +14,23 @@ import ( "time" "github.com/gorilla/websocket" - "go.opentelemetry.io/otel/metric/instrument" - "go.opentelemetry.io/otel/metric/instrument/syncint64" - "go.opentelemetry.io/otel/metric/unit" + "go.opentelemetry.io/otel/metric" "go.uber.org/multierr" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/gql" + "go.sour.is/ev/pkg/event" + + "go.sour.is/pkg/gql" + "go.sour.is/pkg/lg" ) type service struct { es *ev.EventStore - m_gql_posts syncint64.Counter - m_gql_post_added syncint64.Counter - m_gql_post_added_event syncint64.Counter - m_req_time syncint64.Histogram + m_gql_posts metric.Int64Counter + m_gql_post_added metric.Int64Counter + m_gql_post_added_event metric.Int64Counter + m_req_time metric.Int64Histogram } type MsgbusResolver interface { @@ -56,24 +55,24 @@ func New(ctx context.Context, es *ev.EventStore) (*service, error) { svc := &service{es: es} var err, errs error - svc.m_gql_posts, err = m.SyncInt64().Counter("msgbus_posts", - instrument.WithDescription("msgbus graphql posts requests"), + svc.m_gql_posts, err = m.Int64Counter("msgbus_posts", + metric.WithDescription("msgbus graphql posts requests"), ) errs = multierr.Append(errs, err) - svc.m_gql_post_added, err = m.SyncInt64().Counter("msgbus_post_added", - instrument.WithDescription("msgbus graphql post added subcription requests"), + svc.m_gql_post_added, err = m.Int64Counter("msgbus_post_added", + metric.WithDescription("msgbus graphql post added subcription requests"), ) errs = multierr.Append(errs, err) - svc.m_gql_post_added_event, err = m.SyncInt64().Counter("msgbus_post_event", - instrument.WithDescription("msgbus graphql post added subscription events"), + svc.m_gql_post_added_event, err = m.Int64Counter("msgbus_post_event", + metric.WithDescription("msgbus graphql post added subscription events"), ) errs = multierr.Append(errs, err) - svc.m_req_time, err = m.SyncInt64().Histogram("msgbus_request_time", - instrument.WithDescription("msgbus graphql post added subscription events"), - instrument.WithUnit(unit.Unit("ns")), + svc.m_req_time, err = m.Int64Histogram("msgbus_request_time", + metric.WithDescription("msgbus graphql post added subscription events"), + metric.WithUnit("ns"), ) errs = multierr.Append(errs, err) diff --git a/app/peerfinder/ev-info.go b/app/peerfinder/ev-info.go index fc2aa30..acb2c85 100644 --- a/app/peerfinder/ev-info.go +++ b/app/peerfinder/ev-info.go @@ -5,7 +5,7 @@ import ( "github.com/tj/go-semver" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) type Info struct { diff --git a/app/peerfinder/ev-peer.go b/app/peerfinder/ev-peer.go index 9f55572..96dad44 100644 --- a/app/peerfinder/ev-peer.go +++ b/app/peerfinder/ev-peer.go @@ -7,8 +7,9 @@ import ( "time" "github.com/keys-pub/keys/json" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/set" + "go.sour.is/pkg/set" + + "go.sour.is/ev/pkg/event" ) type Time time.Time diff --git a/app/peerfinder/ev-request.go b/app/peerfinder/ev-request.go index 3c878ee..0aec6fd 100644 --- a/app/peerfinder/ev-request.go +++ b/app/peerfinder/ev-request.go @@ -9,8 +9,8 @@ import ( "time" "github.com/oklog/ulid" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/set" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/set" ) type Request struct { diff --git a/app/peerfinder/http.go b/app/peerfinder/http.go index 6dfca6c..ca2b071 100644 --- a/app/peerfinder/http.go +++ b/app/peerfinder/http.go @@ -19,10 +19,10 @@ import ( "github.com/oklog/ulid/v2" contentnegotiation "gitlab.com/jamietanna/content-negotiation-go" "go.opentelemetry.io/otel/attribute" + "go.sour.is/pkg/lg" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) var ( @@ -656,7 +656,6 @@ func fnOrderByPeer(rq *Request) listPeer { v := peers[i] sort.Sort(v.Results) - v.Name = v.Results[0].Name v.Country = v.Results[0].Country v.Latency = v.Results[0].Latency diff --git a/app/peerfinder/jobs.go b/app/peerfinder/jobs.go index fcd7b90..cb2fa72 100644 --- a/app/peerfinder/jobs.go +++ b/app/peerfinder/jobs.go @@ -10,9 +10,9 @@ import ( "time" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/set" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/set" ) // RefreshJob retrieves peer info from the peerdb diff --git a/app/peerfinder/service.go b/app/peerfinder/service.go index 3bf713d..37fa300 100644 --- a/app/peerfinder/service.go +++ b/app/peerfinder/service.go @@ -6,11 +6,12 @@ import ( "sync/atomic" "time" - "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/locker" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/locker" "go.uber.org/multierr" + + "go.sour.is/ev" + "go.sour.is/ev/pkg/event" ) const ( diff --git a/app/salty/blobs.go b/app/salty/blobs.go index 7ab064b..968fb94 100644 --- a/app/salty/blobs.go +++ b/app/salty/blobs.go @@ -11,10 +11,9 @@ import ( "path/filepath" "strings" - "go.opentelemetry.io/otel/metric/instrument" - "go.opentelemetry.io/otel/metric/instrument/syncint64" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/authreq" + "go.opentelemetry.io/otel/metric" + "go.sour.is/pkg/authreq" + "go.sour.is/pkg/lg" "go.uber.org/multierr" ) @@ -30,9 +29,9 @@ func WithBlobStore(path string) *withBlobStore { type withBlobStore struct { path string - m_get_blob syncint64.Counter - m_put_blob syncint64.Counter - m_delete_blob syncint64.Counter + m_get_blob metric.Int64Counter + m_put_blob metric.Int64Counter + m_delete_blob metric.Int64Counter } func (o *withBlobStore) ApplySalty(s *service) {} @@ -49,18 +48,18 @@ func (o *withBlobStore) Setup(ctx context.Context) error { } m := lg.Meter(ctx) - o.m_get_blob, err = m.SyncInt64().Counter("salty_get_blob", - instrument.WithDescription("salty get blob called"), + o.m_get_blob, err = m.Int64Counter("salty_get_blob", + metric.WithDescription("salty get blob called"), ) errs = multierr.Append(errs, err) - o.m_put_blob, err = m.SyncInt64().Counter("salty_put_blob", - instrument.WithDescription("salty put blob called"), + o.m_put_blob, err = m.Int64Counter("salty_put_blob", + metric.WithDescription("salty put blob called"), ) errs = multierr.Append(errs, err) - o.m_delete_blob, err = m.SyncInt64().Counter("salty_delete_blob", - instrument.WithDescription("salty delete blob called"), + o.m_delete_blob, err = m.Int64Counter("salty_delete_blob", + metric.WithDescription("salty delete blob called"), ) errs = multierr.Append(errs, err) diff --git a/app/salty/salty-addr.go b/app/salty/salty-addr.go index e6e3b06..1d55769 100644 --- a/app/salty/salty-addr.go +++ b/app/salty/salty-addr.go @@ -11,7 +11,7 @@ import ( "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 diff --git a/app/salty/salty-user.go b/app/salty/salty-user.go index 7b35659..3422fcc 100644 --- a/app/salty/salty-user.go +++ b/app/salty/salty-user.go @@ -12,8 +12,8 @@ import ( "github.com/keys-pub/keys" "github.com/oklog/ulid/v2" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/gql" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/gql" ) type SaltyUser struct { diff --git a/app/salty/service.go b/app/salty/service.go index 8657619..c75d9e9 100644 --- a/app/salty/service.go +++ b/app/salty/service.go @@ -14,15 +14,13 @@ import ( "github.com/keys-pub/keys" "go.mills.io/saltyim" - "go.opentelemetry.io/otel/metric/instrument" - "go.opentelemetry.io/otel/metric/instrument/syncint64" - "go.opentelemetry.io/otel/metric/unit" + "go.opentelemetry.io/otel/metric" "go.uber.org/multierr" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/gql" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/gql" + "go.sour.is/pkg/lg" ) type DNSResolver interface { @@ -34,13 +32,13 @@ type service struct { es *ev.EventStore dns DNSResolver - m_create_user syncint64.Counter - m_get_user syncint64.Counter - m_api_ping syncint64.Counter - m_api_register syncint64.Counter - m_api_lookup syncint64.Counter - m_api_send syncint64.Counter - m_req_time syncint64.Histogram + m_create_user metric.Int64Counter + m_get_user metric.Int64Counter + m_api_ping metric.Int64Counter + m_api_register metric.Int64Counter + m_api_lookup metric.Int64Counter + m_api_send metric.Int64Counter + m_req_time metric.Int64Histogram opts []Option } @@ -93,39 +91,39 @@ func New(ctx context.Context, es *ev.EventStore, opts ...Option) (*service, erro } var err, errs error - svc.m_create_user, err = m.SyncInt64().Counter("salty_create_user", - instrument.WithDescription("salty create user graphql called"), + svc.m_create_user, err = m.Int64Counter("salty_create_user", + metric.WithDescription("salty create user graphql called"), ) errs = multierr.Append(errs, err) - svc.m_get_user, err = m.SyncInt64().Counter("salty_get_user", - instrument.WithDescription("salty get user graphql called"), + svc.m_get_user, err = m.Int64Counter("salty_get_user", + metric.WithDescription("salty get user graphql called"), ) errs = multierr.Append(errs, err) - svc.m_api_ping, err = m.SyncInt64().Counter("salty_api_ping", - instrument.WithDescription("salty api ping called"), + svc.m_api_ping, err = m.Int64Counter("salty_api_ping", + metric.WithDescription("salty api ping called"), ) errs = multierr.Append(errs, err) - svc.m_api_register, err = m.SyncInt64().Counter("salty_api_register", - instrument.WithDescription("salty api register"), + svc.m_api_register, err = m.Int64Counter("salty_api_register", + metric.WithDescription("salty api register"), ) errs = multierr.Append(errs, err) - svc.m_api_lookup, err = m.SyncInt64().Counter("salty_api_lookup", - instrument.WithDescription("salty api ping lookup"), + svc.m_api_lookup, err = m.Int64Counter("salty_api_lookup", + metric.WithDescription("salty api ping lookup"), ) errs = multierr.Append(errs, err) - svc.m_api_send, err = m.SyncInt64().Counter("salty_api_send", - instrument.WithDescription("salty api ping send"), + svc.m_api_send, err = m.Int64Counter("salty_api_send", + metric.WithDescription("salty api ping send"), ) errs = multierr.Append(errs, err) - svc.m_req_time, err = m.SyncInt64().Histogram("salty_request_time", - instrument.WithDescription("histogram of requests"), - instrument.WithUnit(unit.Unit("ns")), + svc.m_req_time, err = m.Int64Histogram("salty_request_time", + metric.WithDescription("histogram of requests"), + metric.WithUnit("ns"), ) errs = multierr.Append(errs, err) diff --git a/app/webfinger/events.go b/app/webfinger/events.go index afcfb84..e0daf15 100644 --- a/app/webfinger/events.go +++ b/app/webfinger/events.go @@ -1,7 +1,7 @@ package webfinger import ( - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) type SubjectSet struct { diff --git a/app/webfinger/jrd.go b/app/webfinger/jrd.go index 368810c..aaf45f9 100644 --- a/app/webfinger/jrd.go +++ b/app/webfinger/jrd.go @@ -8,10 +8,11 @@ import ( "hash/fnv" "sort" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/set" - "go.sour.is/ev/pkg/slice" + "go.sour.is/pkg/set" + "go.sour.is/pkg/slice" "gopkg.in/yaml.v3" + + "go.sour.is/ev/pkg/event" ) func StreamID(subject string) string { diff --git a/app/webfinger/jrd_test.go b/app/webfinger/jrd_test.go index 07037d0..70b3c0f 100644 --- a/app/webfinger/jrd_test.go +++ b/app/webfinger/jrd_test.go @@ -12,14 +12,14 @@ import ( jwt "github.com/golang-jwt/jwt/v4" "github.com/matryer/is" + "go.sour.is/ev" "go.uber.org/multierr" - "go.sour.is/ev" "go.sour.is/ev/app/webfinger" - memstore "go.sour.is/ev/pkg/es/driver/mem-store" - "go.sour.is/ev/pkg/es/driver/projecter" - "go.sour.is/ev/pkg/es/driver/streamer" - "go.sour.is/ev/pkg/es/event" + memstore "go.sour.is/ev/pkg/driver/mem-store" + "go.sour.is/ev/pkg/driver/projecter" + "go.sour.is/ev/pkg/driver/streamer" + "go.sour.is/ev/pkg/event" ) func TestParseJRD(t *testing.T) { diff --git a/app/webfinger/webfinger.go b/app/webfinger/webfinger.go index 1cc6e3c..b5cbb57 100644 --- a/app/webfinger/webfinger.go +++ b/app/webfinger/webfinger.go @@ -20,10 +20,11 @@ import ( "strings" "github.com/golang-jwt/jwt/v4" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/set" + "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/set" + "go.sour.is/ev/pkg/event" ) var ( diff --git a/cmd/ev/app.msgbus.go b/cmd/ev/app.msgbus.go index 76cb205..033054e 100644 --- a/cmd/ev/app.msgbus.go +++ b/cmd/ev/app.msgbus.go @@ -6,10 +6,10 @@ import ( "go.sour.is/ev" "go.sour.is/ev/app/msgbus" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/service" - "go.sour.is/ev/pkg/es/driver/projecter" - "go.sour.is/ev/pkg/slice" + "go.sour.is/ev/pkg/driver/projecter" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" + "go.sour.is/pkg/slice" ) var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error { diff --git a/cmd/ev/app.peerfinder.go b/cmd/ev/app.peerfinder.go index 6a03e51..6f960d1 100644 --- a/cmd/ev/app.peerfinder.go +++ b/cmd/ev/app.peerfinder.go @@ -4,13 +4,14 @@ import ( "context" "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/app/peerfinder" - "go.sour.is/ev/internal/lg" - "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" + "go.sour.is/ev/pkg/driver/projecter" ) var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error { diff --git a/cmd/ev/app.salty.go b/cmd/ev/app.salty.go index 4a2d266..4b2e688 100644 --- a/cmd/ev/app.salty.go +++ b/cmd/ev/app.salty.go @@ -11,10 +11,10 @@ import ( "go.sour.is/ev" "go.sour.is/ev/app/salty" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/env" - "go.sour.is/ev/pkg/service" - "go.sour.is/ev/pkg/slice" + "go.sour.is/pkg/env" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" + "go.sour.is/pkg/slice" ) var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error { diff --git a/cmd/ev/app.twtxt.go b/cmd/ev/app.twtxt.go index 36bf42c..f3f9b6d 100644 --- a/cmd/ev/app.twtxt.go +++ b/cmd/ev/app.twtxt.go @@ -3,8 +3,8 @@ package main import ( "context" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/service" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" ) var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error { diff --git a/cmd/ev/app.webfinger.go b/cmd/ev/app.webfinger.go index 9a4b966..4ca6a91 100644 --- a/cmd/ev/app.webfinger.go +++ b/cmd/ev/app.webfinger.go @@ -7,12 +7,13 @@ import ( "time" "github.com/patrickmn/go-cache" + "go.sour.is/ev" "go.sour.is/ev/app/webfinger" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/env" - "go.sour.is/ev/pkg/service" - "go.sour.is/ev/pkg/slice" + "go.sour.is/pkg/env" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" + "go.sour.is/pkg/slice" ) var ( diff --git a/cmd/ev/main.go b/cmd/ev/main.go index 99e5d88..b1117e8 100644 --- a/cmd/ev/main.go +++ b/cmd/ev/main.go @@ -8,8 +8,8 @@ import ( "os" "os/signal" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/service" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" ) var apps service.Apps diff --git a/cmd/ev/svc.es.go b/cmd/ev/svc.es.go index 1ade46d..19d0101 100644 --- a/cmd/ev/svc.es.go +++ b/cmd/ev/svc.es.go @@ -3,18 +3,19 @@ package main import ( "context" - "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/env" - "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.sour.is/pkg/env" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/service" "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 { diff --git a/cmd/ev/svc.gql.go b/cmd/ev/svc.gql.go index 27fad66..71ef0b6 100644 --- a/cmd/ev/svc.gql.go +++ b/cmd/ev/svc.gql.go @@ -4,12 +4,13 @@ import ( "context" "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/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 { diff --git a/cmd/ev/svc.http.go b/cmd/ev/svc.http.go index 8fb5a93..871ba45 100644 --- a/cmd/ev/svc.http.go +++ b/cmd/ev/svc.http.go @@ -7,11 +7,12 @@ import ( "strings" "github.com/rs/cors" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/env" - "go.sour.is/ev/pkg/mux" - "go.sour.is/ev/pkg/service" - "go.sour.is/ev/pkg/slice" + + "go.sour.is/pkg/env" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/mux" + "go.sour.is/pkg/service" + "go.sour.is/pkg/slice" ) var _ = apps.Register(20, func(ctx context.Context, svc *service.Harness) error { diff --git a/cmd/webfinger-cli/main.go b/cmd/webfinger-cli/main.go index a70991e..ad4d8dd 100644 --- a/cmd/webfinger-cli/main.go +++ b/cmd/webfinger-cli/main.go @@ -16,10 +16,10 @@ import ( "strings" "github.com/docopt/docopt-go" + "go.sour.is/pkg/xdg" "gopkg.in/yaml.v3" "go.sour.is/ev/app/webfinger" - "go.sour.is/ev/cmd/webfinger-cli/xdg" ) var usage = `Webfinger CLI. diff --git a/cmd/webfinger-cli/xdg/path_darwin.go b/cmd/webfinger-cli/xdg/path_darwin.go deleted file mode 100644 index 10c2ba1..0000000 --- a/cmd/webfinger-cli/xdg/path_darwin.go +++ /dev/null @@ -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" -) diff --git a/cmd/webfinger-cli/xdg/path_linux.go b/cmd/webfinger-cli/xdg/path_linux.go deleted file mode 100644 index ca8cffe..0000000 --- a/cmd/webfinger-cli/xdg/path_linux.go +++ /dev/null @@ -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" -) diff --git a/cmd/webfinger-cli/xdg/path_windows.go b/cmd/webfinger-cli/xdg/path_windows.go deleted file mode 100644 index 6886bf0..0000000 --- a/cmd/webfinger-cli/xdg/path_windows.go +++ /dev/null @@ -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` -) diff --git a/cmd/webfinger-cli/xdg/xdg.go b/cmd/webfinger-cli/xdg/xdg.go deleted file mode 100644 index 8f2f709..0000000 --- a/cmd/webfinger-cli/xdg/xdg.go +++ /dev/null @@ -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 -} diff --git a/ev.go b/ev.go index f704277..27e61b5 100644 --- a/ev.go +++ b/ev.go @@ -8,13 +8,13 @@ import ( "strings" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/instrument/syncint64" + "go.opentelemetry.io/otel/metric" "go.uber.org/multierr" - "go.sour.is/ev/internal/lg" - "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/driver" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/locker" ) type config struct { @@ -32,19 +32,19 @@ func Init(ctx context.Context) error { m := lg.Meter(ctx) var err, errs error - Mes_open, err = m.SyncInt64().Counter("es_open") + Mes_open, err = m.Int64Counter("es_open") 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) - Mes_load, err = m.SyncInt64().Counter("es_load") + Mes_load, err = m.Int64Counter("es_load") 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) - Mes_append, err = m.SyncInt64().Counter("es_append") + Mes_append, err = m.Int64Counter("es_append") errs = multierr.Append(errs, err) return errs @@ -68,11 +68,11 @@ type EventStore struct { } var ( - Mes_open syncint64.Counter - Mes_read syncint64.Counter - Mes_load syncint64.Counter - Mes_save syncint64.Counter - Mes_append syncint64.Counter + Mes_open metric.Int64Counter + Mes_read metric.Int64Counter + Mes_load metric.Int64Counter + Mes_save metric.Int64Counter + Mes_append metric.Int64Counter ) func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, error) { diff --git a/ev_test.go b/ev_test.go index 95a051e..d059038 100644 --- a/ev_test.go +++ b/ev_test.go @@ -12,11 +12,11 @@ import ( "go.sour.is/ev" "go.sour.is/ev/app/peerfinder" - 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" + 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/event" ) var ( diff --git a/go.mod b/go.mod index 67a3359..f0909d1 100644 --- a/go.mod +++ b/go.mod @@ -3,30 +3,33 @@ module go.sour.is/ev go 1.19 require ( - github.com/99designs/gqlgen v0.17.13 - github.com/go-logr/stdr v1.2.2 + github.com/99designs/gqlgen v0.17.34 + github.com/go-logr/stdr v1.2.2 // indirect github.com/gorilla/websocket v1.5.0 - github.com/logzio/logzio-go v1.0.6 - github.com/ravilushqa/otelgqlgen v0.9.0 + github.com/ravilushqa/otelgqlgen v0.13.1 // indirect github.com/rs/cors v1.8.2 github.com/tidwall/wal v1.1.7 - github.com/vektah/gqlparser/v2 v2.4.7 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0 - go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0 - go.opentelemetry.io/otel v1.9.0 - go.opentelemetry.io/otel/exporters/prometheus v0.31.0 - go.opentelemetry.io/otel/metric v0.31.0 - go.opentelemetry.io/otel/sdk v1.9.0 - go.opentelemetry.io/otel/sdk/metric v0.31.0 - go.opentelemetry.io/otel/trace v1.9.0 - golang.org/x/sync v0.1.0 + github.com/vektah/gqlparser/v2 v2.5.6 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect + go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 + go.opentelemetry.io/otel/exporters/prometheus v0.39.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 + golang.org/x/sync v0.3.0 // indirect ) 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 ( + github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/julienschmidt/httprouter v1.3.0 // 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/andybalholm/brotli v1.0.4 // 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/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/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect github.com/dchest/blake2b v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/errwrap v1.1.0 // 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/keybase/go-codec v0.0.0-20180928230036-164397562123 // 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/mitchellh/mapstructure v1.5.0 // indirect 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/pkg/errors v0.9.1 // 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.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.10.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/syndtr/goleveldb v1.0.0 // 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/vmihailenco/msgpack/v4 v4.3.12 // indirect @@ -86,31 +80,29 @@ require ( github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // 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.opentelemetry.io/contrib v1.9.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 // indirect - go.opentelemetry.io/proto/otlp v0.18.0 // indirect - go.uber.org/atomic v1.9.0 // indirect + go.opentelemetry.io/contrib v1.16.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.yarn.social/lextwt v0.0.0-20221221200320-31bca76a2587 // indirect go.yarn.social/types v0.0.0-20221027173319-2d00e96a95c1 // indirect golang.org/x/crypto v0.5.0 // indirect - golang.org/x/net v0.5.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect - google.golang.org/grpc v1.46.2 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) require ( 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/matryer/is v1.4.0 + github.com/matryer/is v1.4.1 github.com/oklog/ulid/v2 v2.1.0 github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -118,7 +110,7 @@ require ( github.com/tidwall/tinylru v1.1.0 // indirect gitlab.com/jamietanna/content-negotiation-go v0.2.0 go.mills.io/saltyim v0.0.0-20230128070719-15a64de82829 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0 - go.uber.org/multierr v1.8.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect + go.uber.org/multierr v1.11.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index e0e5808..259cd7d 100644 --- a/go.sum +++ b/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/observe v0.0.0-20210712230028-fc31c7aa2bd1 h1:e6ZyAOFGLZJZYL2galNvfuNMqeQDdilmQ5WRBXCNL5s= 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.13/go.mod h1:w1brbeOdqVyNJI553BGwtwdVcYu1LKeYE1opLWN9RgQ= +github.com/99designs/gqlgen v0.17.34 h1:5cS5/OKFguQt+Ws56uj9FlG2xm1IlcJWNF2jrMIKYFQ= +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 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/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= 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/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o= 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/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= 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/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= 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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 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.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 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-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-20211001041855-01bcc9b48dfe/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/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= 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.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.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/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= 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/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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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-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.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 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/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 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/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= 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.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +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 v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= 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-20191227052852-215e87163ea7/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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 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/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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/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.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.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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/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.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= +github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= 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/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/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 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/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20= 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/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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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/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/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= -github.com/logzio/logzio-go v1.0.6 h1:BIVu5TWDZc0vlEkwSDjoxPlV/aMJV2LdM3k+CjdzFDg= -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/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= 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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 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/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/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 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/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/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= 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/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= 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/posener/formatter v1.0.0 h1:TwXJq26f9ERTjCpZj8xEWj77WPWfX/nBgGx52Ap/gYM= 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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -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_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= 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.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/ravilushqa/otelgqlgen v0.9.0 h1:NgbrU9OHPKB/X6Ja618+SqPNls05M3T8aV1fkUiR9ow= -github.com/ravilushqa/otelgqlgen v0.9.0/go.mod h1:TqSvbt/7E23CHOOgL6G+42kCbhvxUpT/21tMsarq4Hk= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/ravilushqa/otelgqlgen v0.13.1 h1:V+zFE75iDd2/CSzy5kKnb+Fi09SsE5535wv9U2nUEFE= +github.com/ravilushqa/otelgqlgen v0.13.1/go.mod h1:ZIyWykK2paCuNi9k8gk5edcNSwDJuxZaW90vZXpafxw= 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/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.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.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= 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/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -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/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= 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= @@ -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.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.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 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/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/go-semver v1.0.0 h1:vpn6Jmn6Hi3QSmrP1PzYcqScop9IZiGCVOSn18wzu8w= 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/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= 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/unrolled/logger v0.0.0-20201216141554-31a3694fe979 h1:47+K4wN0S8L3fUwgZtPEBIfNqtAE3tUvBfvHVZJAXfg= 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.4.6/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= -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/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= +github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= 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/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/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/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.27/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/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/go.mod h1:n4ZZ8/X5TstnjYRnjEtR/fC7MCTe+aRKM7PQlLBH3PQ= 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.3/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.9.0/go.mod h1:yp0N4+hnpWCpnMzs6T6WbD9Amfg7reEZsS0jAd/5M2Q= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0 h1:9NkMW03wwEzPtP/KciZ4Ozu/Uz5ZA7kfqXJIObnrjGU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.34.0/go.mod h1:548ZsYzmT4PL4zWKRd8q/N4z0Wxzn/ZxUE+lkEpwWQA= -go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0 h1:zt4RDodWkgiHk8tyUmFOjFoOOfyGH7vwIbUzKP6CCh8= -go.opentelemetry.io/contrib/instrumentation/runtime v0.34.0/go.mod h1:5wIoZE96WbcQVU3D6UF/ukRfFQXbB6OYgeWi9CjHa90= -go.opentelemetry.io/otel v1.9.0 h1:8WZNQFIB2a71LnANS9JeyidJKKGOOremcUtb/OtHISw= -go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 h1:ggqApEjDKczicksfvZUCxuvoyDmR6Sbm56LwiK8DVR0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 h1:NN90Cuna0CnBg8YNu1Q0V35i2E8LDByFOwHRCq/ZP9I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0/go.mod h1:0EsCXjZAiiZGnLdEUXM9YjCKuuLZMYyglh2QDXcYKVA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0 h1:FAF9l8Wjxi9Ad2k/vLTfHZyzXYX72C62wBGpV3G6AIo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0/go.mod h1:smUdtylgc0YQiUr2PuifS4hBXhAS5xtR6WQhxP1wiNA= -go.opentelemetry.io/otel/exporters/prometheus v0.31.0 h1:jwtnOGBM8dIty5AVZ+9ZCzZexCea3aVKmUfZAQcHqxs= -go.opentelemetry.io/otel/exporters/prometheus v0.31.0/go.mod h1:QarXIB8L79IwIPoNgG3A6zNvBgVmcppeFogV1d8612s= -go.opentelemetry.io/otel/metric v0.31.0 h1:6SiklT+gfWAwWUR0meEMxQBtihpiEs4c+vL9spDTqUs= -go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= -go.opentelemetry.io/otel/sdk v1.9.0 h1:LNXp1vrr83fNXTHgU8eO89mhzxb/bbWAsHG6fNf3qWo= -go.opentelemetry.io/otel/sdk v1.9.0/go.mod h1:AEZc8nt5bd2F7BC24J5R0mrjYnpEgYHyTcM/vrSple4= -go.opentelemetry.io/otel/sdk/metric v0.31.0 h1:2sZx4R43ZMhJdteKAlKoHvRgrMp53V1aRxvEf5lCq8Q= -go.opentelemetry.io/otel/sdk/metric v0.31.0/go.mod h1:fl0SmNnX9mN9xgU6OLYLMBMrNAsaZQi7qBwprwO3abk= -go.opentelemetry.io/otel/trace v1.9.0 h1:oZaCNJUjWcg60VXWee8lJKlqhPbXAPB51URuR47pQYc= -go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo= +go.opentelemetry.io/contrib v1.16.1 h1:EpASvVyGx6/ZTlmXzxYfTMZxHROelCeXXa2uLiwltcs= +go.opentelemetry.io/contrib v1.16.1/go.mod h1:gIzjwWFoGazJmtCaDgViqOSJPde2mCWzv60o0bWPcZs= +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.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= +go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0 h1:EbmAUG9hEAMXyfWEasIt2kmh/WmXUznUksChApTgBGc= +go.opentelemetry.io/contrib/instrumentation/runtime v0.42.0/go.mod h1:rD9feqRYP24P14t5kmhNMqsqm1jvKmpx2H2rKVw52V8= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 h1:iqjq9LAB8aK++sKVcELezzn655JnBNdsDhghU4G/So8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0/go.mod h1:hGXzO5bhhSHZnKvrDaXB82Y9DRFour0Nz/KrBh7reWw= +go.opentelemetry.io/otel/exporters/prometheus v0.39.0 h1:whAaiHxOatgtKd+w0dOi//1KUxj3KoPINZdtDaDj3IA= +go.opentelemetry.io/otel/exporters/prometheus v0.39.0/go.mod h1:4jo5Q4CROlCpSPsXLhymi+LYrDXd2ObU5wbKayfZs7Y= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +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.18.0 h1:W5hyXNComRa23tGpKwG+FRAc4rfF6ZUg1JReK+QHS80= -go.opentelemetry.io/proto/otlp v0.18.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.sour.is/pkg v0.0.1 h1:wajjul3FNTljfcsNqNHsnelyVvsq8buuKrfxncJDuu0= +go.sour.is/pkg v0.0.1/go.mod h1:jOdxxKILf+kXQmk1cG3sN4Ogxk8C4/14mxhy/QEJjv4= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 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/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.2.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/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-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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-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-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-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-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-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-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.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +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-20190226205417-e64efc72b421/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-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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +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-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-20190312061237-fead79001313/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-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-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-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-20191228213918-04cbcbbfeed8/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-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-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-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-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-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-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-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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +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-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.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.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.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.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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +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-20190308202827-9d24e82272b4/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-20200804011535-6c149bb5ef0d/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/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-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= 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= @@ -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-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-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-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.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 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.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.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 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/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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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-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/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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.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.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/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index fc1b40c..5e2067b 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -21,8 +21,8 @@ import ( "go.sour.is/ev/app/msgbus" "go.sour.is/ev/app/salty" "go.sour.is/ev/pkg/es" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/gql" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/gql" ) // region ************************** generated!.gotpl ************************** @@ -145,7 +145,7 @@ func (e *executableSchema) Schema() *ast.Schema { } func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e} + ec := executionContext{nil, e, 0, 0, nil} _ = ec switch typeName + "." + field { @@ -449,7 +449,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e} + ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} inputUnmarshalMap := graphql.BuildUnmarshalerMap( ec.unmarshalInputPageInput, ) @@ -458,18 +458,33 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { switch rc.Operation.Operation { case ast.Query: return func(ctx context.Context) *graphql.Response { - if !first { - return nil + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, rc.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } } - first = false - ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) - data := ec._Query(ctx, rc.Operation.SelectionSet) var buf bytes.Buffer data.MarshalGQL(&buf) - - return &graphql.Response{ - Data: buf.Bytes(), + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext } + + return &response } case ast.Mutation: return func(ctx context.Context) *graphql.Response { @@ -512,6 +527,28 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { type executionContext struct { *graphql.OperationContext *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() } func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { @@ -530,7 +567,7 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er var sources = []*ast.Source{ {Name: "../../../pkg/es/es.graphqls", Input: ` -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") streamID: String! @goField(name: "ActualStreamID") position: Int! @goField(name: "ActualPosition") @@ -563,26 +600,26 @@ type Event implements Edge @goModel(model: "go.sour.is/ev/pkg/es.GQLEvent") { linked: Event }`, BuiltIn: false}, - {Name: "../../../pkg/gql/common.graphqls", Input: `scalar Time + {Name: "../../../app/gql/common.graphqls", Input: `scalar Time 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! 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 before: Int 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! prev: Boolean! begin: 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! } @@ -638,15 +675,13 @@ type SaltyUser @goModel(model: "go.sour.is/ev/app/salty.SaltyUser"){ endpoint: String! }`, BuiltIn: false}, {Name: "../../../federation/directives.graphql", Input: ` - scalar _Any - scalar _FieldSet - - directive @external on FIELD_DEFINITION + directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION directive @extends on OBJECT | INTERFACE - - directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE + directive @external on FIELD_DEFINITION + scalar _Any + scalar _FieldSet `, BuiltIn: true}, {Name: "../../../federation/entity.graphql", Input: ` type _Service { @@ -742,7 +777,7 @@ func (ec *executionContext) field_Query_events_args(ctx context.Context, rawArgs var arg1 *gql.PageInput if tmp, ok := rawArgs["paging"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("paging")) - arg1, err = ec.unmarshalOPageInput2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐPageInput(ctx, tmp) + arg1, err = ec.unmarshalOPageInput2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐPageInput(ctx, tmp) if err != nil { return nil, err } @@ -775,7 +810,7 @@ func (ec *executionContext) field_Query_posts_args(ctx context.Context, rawArgs var arg2 *gql.PageInput if tmp, ok := rawArgs["paging"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("paging")) - arg2, err = ec.unmarshalOPageInput2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐPageInput(ctx, tmp) + arg2, err = ec.unmarshalOPageInput2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐPageInput(ctx, tmp) if err != nil { return nil, err } @@ -922,7 +957,7 @@ func (ec *executionContext) _Connection_paging(ctx context.Context, field graphq } res := resTmp.(*gql.PageInfo) fc.Result = res - return ec.marshalNPageInfo2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐPageInfo(ctx, field.Selections, res) + return ec.marshalNPageInfo2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐPageInfo(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Connection_paging(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -976,7 +1011,7 @@ func (ec *executionContext) _Connection_edges(ctx context.Context, field graphql } res := resTmp.([]gql.Edge) fc.Result = res - return ec.marshalNEdge2ᚕgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐEdgeᚄ(ctx, field.Selections, res) + return ec.marshalNEdge2ᚕgoᚗsourᚗisᚋpkgᚋgqlᚐEdgeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Connection_edges(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -1372,7 +1407,7 @@ func (ec *executionContext) _Event_meta(ctx context.Context, field graphql.Colle } res := resTmp.(*event.Meta) fc.Result = res - return ec.marshalNMeta2ᚖgoᚗsourᚗisᚋevᚋpkgᚋesᚋeventᚐMeta(ctx, field.Selections, res) + return ec.marshalNMeta2ᚖgoᚗsourᚗisᚋevᚋpkgᚋeventᚐMeta(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_meta(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -1687,7 +1722,7 @@ func (ec *executionContext) fieldContext_Mutation_truncateStream(ctx context.Con ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Mutation_truncateStream_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -1747,7 +1782,7 @@ func (ec *executionContext) fieldContext_Mutation_createSaltyUser(ctx context.Co ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Mutation_createSaltyUser_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2132,7 +2167,7 @@ func (ec *executionContext) _PostEvent_meta(ctx context.Context, field graphql.C } res := resTmp.(event.Meta) fc.Result = res - return ec.marshalNMeta2goᚗsourᚗisᚋevᚋpkgᚋesᚋeventᚐMeta(ctx, field.Selections, res) + return ec.marshalNMeta2goᚗsourᚗisᚋevᚋpkgᚋeventᚐMeta(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_PostEvent_meta(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2186,7 +2221,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col } res := resTmp.(*gql.Connection) fc.Result = res - return ec.marshalNConnection2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐConnection(ctx, field.Selections, res) + return ec.marshalNConnection2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐConnection(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2214,7 +2249,7 @@ func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_events_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2247,7 +2282,7 @@ func (ec *executionContext) _Query_posts(ctx context.Context, field graphql.Coll } res := resTmp.(*gql.Connection) fc.Result = res - return ec.marshalNConnection2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐConnection(ctx, field.Selections, res) + return ec.marshalNConnection2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐConnection(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_posts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2275,7 +2310,7 @@ func (ec *executionContext) fieldContext_Query_posts(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_posts_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2335,7 +2370,7 @@ func (ec *executionContext) fieldContext_Query_saltyUser(ctx context.Context, fi ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query_saltyUser_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2457,7 +2492,7 @@ func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2732,7 +2767,7 @@ func (ec *executionContext) fieldContext_Subscription_eventAdded(ctx context.Con ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Subscription_eventAdded_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -2810,7 +2845,7 @@ func (ec *executionContext) fieldContext_Subscription_postAdded(ctx context.Cont ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field_Subscription_postAdded_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -4277,7 +4312,7 @@ func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, fiel ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -4465,7 +4500,7 @@ func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, ctx = graphql.WithFieldContext(ctx, fc) if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) - return + return fc, err } return fc, nil } @@ -4654,26 +4689,29 @@ func (ec *executionContext) unmarshalInputPageInput(ctx context.Context, obj int var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("after")) - it.After, err = ec.unmarshalOInt2ᚖint64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint64(ctx, v) if err != nil { return it, err } + it.After = data case "before": var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("before")) - it.Before, err = ec.unmarshalOInt2ᚖint64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint64(ctx, v) if err != nil { return it, err } + it.Before = data case "count": var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("count")) - it.Count, err = ec.unmarshalOInt2ᚖint64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint64(ctx, v) if err != nil { return it, err } + it.Count = data } } @@ -4711,34 +4749,43 @@ var connectionImplementors = []string{"Connection"} func (ec *executionContext) _Connection(ctx context.Context, sel ast.SelectionSet, obj *gql.Connection) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, connectionImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Connection") case "paging": - out.Values[i] = ec._Connection_paging(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "edges": - out.Values[i] = ec._Connection_edges(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4746,79 +4793,62 @@ var eventImplementors = []string{"Event", "Edge"} func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, obj *es.GQLEvent) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, eventImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Event") case "id": - out.Values[i] = ec._Event_id(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "eventID": - out.Values[i] = ec._Event_eventID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "streamID": - out.Values[i] = ec._Event_streamID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "position": - out.Values[i] = ec._Event_position(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "values": - out.Values[i] = ec._Event_values(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "bytes": - out.Values[i] = ec._Event_bytes(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "type": - out.Values[i] = ec._Event_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "created": - out.Values[i] = ec._Event_created(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "meta": - out.Values[i] = ec._Event_meta(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "linked": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4828,18 +4858,46 @@ func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, ob return res } - out.Concurrently(i, func() graphql.Marshaler { - return innerFunc(ctx) + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) - }) + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4847,48 +4905,53 @@ var metaImplementors = []string{"Meta"} func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj *event.Meta) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, metaImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Meta") case "eventID": - out.Values[i] = ec._Meta_eventID(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "streamID": - out.Values[i] = ec._Meta_streamID(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "position": - out.Values[i] = ec._Meta_position(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "created": - out.Values[i] = ec._Meta_created(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4901,7 +4964,7 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) }) out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ Object: field.Name, @@ -4912,28 +4975,36 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "truncateStream": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_truncateStream(ctx, field) }) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "createSaltyUser": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createSaltyUser(ctx, field) }) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4941,48 +5012,53 @@ var pageInfoImplementors = []string{"PageInfo"} func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, obj *gql.PageInfo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, pageInfoImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("PageInfo") case "next": - out.Values[i] = ec._PageInfo_next(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "prev": - out.Values[i] = ec._PageInfo_prev(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "begin": - out.Values[i] = ec._PageInfo_begin(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "end": - out.Values[i] = ec._PageInfo_end(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -4990,30 +5066,27 @@ var postEventImplementors = []string{"PostEvent", "Edge"} func (ec *executionContext) _PostEvent(ctx context.Context, sel ast.SelectionSet, obj *msgbus.PostEvent) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, postEventImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("PostEvent") case "id": - out.Values[i] = ec._PostEvent_id(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "payload": - out.Values[i] = ec._PostEvent_payload(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "payloadJSON": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5021,37 +5094,61 @@ func (ec *executionContext) _PostEvent(ctx context.Context, sel ast.SelectionSet }() res = ec._PostEvent_payloadJSON(ctx, field, obj) if res == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&fs.Invalids, 1) } return res } - out.Concurrently(i, func() graphql.Marshaler { - return innerFunc(ctx) + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) - }) + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "tags": - out.Values[i] = ec._PostEvent_tags(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "meta": - out.Values[i] = ec._PostEvent_meta(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5064,7 +5161,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ Object: field.Name, @@ -5077,7 +5174,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "events": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5085,22 +5182,21 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_events(ctx, field) if res == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&fs.Invalids, 1) } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "posts": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5108,22 +5204,21 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_posts(ctx, field) if res == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&fs.Invalids, 1) } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "saltyUser": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5134,16 +5229,15 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "_service": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5151,38 +5245,45 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query__service(ctx, field) if res == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&fs.Invalids, 1) } return res } rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func() graphql.Marshaler { - return rrm(innerCtx) - }) + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "__type": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Query___type(ctx, field) }) - case "__schema": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Query___schema(ctx, field) }) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5190,30 +5291,27 @@ var saltyUserImplementors = []string{"SaltyUser"} func (ec *executionContext) _SaltyUser(ctx context.Context, sel ast.SelectionSet, obj *salty.SaltyUser) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, saltyUserImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("SaltyUser") case "pubkey": - out.Values[i] = ec._SaltyUser_pubkey(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "inbox": - out.Values[i] = ec._SaltyUser_inbox(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&out.Invalids, 1) } case "endpoint": field := field - innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -5221,23 +5319,51 @@ func (ec *executionContext) _SaltyUser(ctx context.Context, sel ast.SelectionSet }() res = ec._SaltyUser_endpoint(ctx, field, obj) if res == graphql.Null { - atomic.AddUint32(&invalids, 1) + atomic.AddUint32(&fs.Invalids, 1) } return res } - out.Concurrently(i, func() graphql.Marshaler { - return innerFunc(ctx) + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) - }) + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5267,24 +5393,35 @@ var _ServiceImplementors = []string{"_Service"} func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("_Service") case "sdl": - out.Values[i] = ec.__Service_sdl(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5292,52 +5429,55 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) - case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5345,42 +5485,47 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) - case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5388,56 +5533,57 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) - case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5445,42 +5591,47 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) - case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5488,53 +5639,54 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "description": - out.Values[i] = ec.___Schema_description(ctx, field, obj) - case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) - case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) - case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5542,63 +5694,56 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + out := graphql.NewFieldSet(fields) - var invalids uint32 + deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ + out.Invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) - case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) - case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) - case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) - case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) - case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) - case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) - case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) - case "specifiedByURL": - out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) - default: panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() - if invalids > 0 { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + return out } @@ -5621,11 +5766,11 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) marshalNConnection2goᚗsourᚗisᚋevᚋpkgᚋgqlᚐConnection(ctx context.Context, sel ast.SelectionSet, v gql.Connection) graphql.Marshaler { +func (ec *executionContext) marshalNConnection2goᚗsourᚗisᚋpkgᚋgqlᚐConnection(ctx context.Context, sel ast.SelectionSet, v gql.Connection) graphql.Marshaler { return ec._Connection(ctx, sel, &v) } -func (ec *executionContext) marshalNConnection2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐConnection(ctx context.Context, sel ast.SelectionSet, v *gql.Connection) graphql.Marshaler { +func (ec *executionContext) marshalNConnection2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐConnection(ctx context.Context, sel ast.SelectionSet, v *gql.Connection) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -5635,7 +5780,7 @@ func (ec *executionContext) marshalNConnection2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgq return ec._Connection(ctx, sel, v) } -func (ec *executionContext) marshalNEdge2goᚗsourᚗisᚋevᚋpkgᚋgqlᚐEdge(ctx context.Context, sel ast.SelectionSet, v gql.Edge) graphql.Marshaler { +func (ec *executionContext) marshalNEdge2goᚗsourᚗisᚋpkgᚋgqlᚐEdge(ctx context.Context, sel ast.SelectionSet, v gql.Edge) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -5645,7 +5790,7 @@ func (ec *executionContext) marshalNEdge2goᚗsourᚗisᚋevᚋpkgᚋgqlᚐEdge( return ec._Edge(ctx, sel, v) } -func (ec *executionContext) marshalNEdge2ᚕgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []gql.Edge) graphql.Marshaler { +func (ec *executionContext) marshalNEdge2ᚕgoᚗsourᚗisᚋpkgᚋgqlᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []gql.Edge) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup isLen1 := len(v) == 1 @@ -5669,7 +5814,7 @@ func (ec *executionContext) marshalNEdge2ᚕgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐEd if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNEdge2goᚗsourᚗisᚋevᚋpkgᚋgqlᚐEdge(ctx, sel, v[i]) + ret[i] = ec.marshalNEdge2goᚗsourᚗisᚋpkgᚋgqlᚐEdge(ctx, sel, v[i]) } if isLen1 { f(i) @@ -5755,11 +5900,11 @@ func (ec *executionContext) marshalNMap2map(ctx context.Context, sel ast.Selecti return res } -func (ec *executionContext) marshalNMeta2goᚗsourᚗisᚋevᚋpkgᚋesᚋeventᚐMeta(ctx context.Context, sel ast.SelectionSet, v event.Meta) graphql.Marshaler { +func (ec *executionContext) marshalNMeta2goᚗsourᚗisᚋevᚋpkgᚋeventᚐMeta(ctx context.Context, sel ast.SelectionSet, v event.Meta) graphql.Marshaler { return ec._Meta(ctx, sel, &v) } -func (ec *executionContext) marshalNMeta2ᚖgoᚗsourᚗisᚋevᚋpkgᚋesᚋeventᚐMeta(ctx context.Context, sel ast.SelectionSet, v *event.Meta) graphql.Marshaler { +func (ec *executionContext) marshalNMeta2ᚖgoᚗsourᚗisᚋevᚋpkgᚋeventᚐMeta(ctx context.Context, sel ast.SelectionSet, v *event.Meta) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -5769,7 +5914,7 @@ func (ec *executionContext) marshalNMeta2ᚖgoᚗsourᚗisᚋevᚋpkgᚋesᚋeve return ec._Meta(ctx, sel, v) } -func (ec *executionContext) marshalNPageInfo2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐPageInfo(ctx context.Context, sel ast.SelectionSet, v *gql.PageInfo) graphql.Marshaler { +func (ec *executionContext) marshalNPageInfo2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐPageInfo(ctx context.Context, sel ast.SelectionSet, v *gql.PageInfo) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -6162,7 +6307,7 @@ func (ec *executionContext) marshalOInt2ᚖint64(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) unmarshalOPageInput2ᚖgoᚗsourᚗisᚋevᚋpkgᚋgqlᚐPageInput(ctx context.Context, v interface{}) (*gql.PageInput, error) { +func (ec *executionContext) unmarshalOPageInput2ᚖgoᚗsourᚗisᚋpkgᚋgqlᚐPageInput(ctx context.Context, v interface{}) (*gql.PageInput, error) { if v == nil { return nil, nil } diff --git a/internal/graph/generated/pkg.go b/internal/graph/generated/pkg.go new file mode 100644 index 0000000..951c880 --- /dev/null +++ b/internal/graph/generated/pkg.go @@ -0,0 +1 @@ +package generated diff --git a/internal/graph/resolver/resolver.go b/internal/graph/resolver/resolver.go index 02d6a16..769ef98 100644 --- a/internal/graph/resolver/resolver.go +++ b/internal/graph/resolver/resolver.go @@ -5,11 +5,12 @@ package resolver import ( "context" + "go.sour.is/pkg/gql" + "go.sour.is/ev/app/msgbus" "go.sour.is/ev/app/salty" "go.sour.is/ev/internal/graph/generated" "go.sour.is/ev/pkg/es" - "go.sour.is/ev/pkg/gql" ) type Resolver struct{} diff --git a/internal/lg/init.go b/internal/lg/init.go deleted file mode 100644 index 3c7ec2d..0000000 --- a/internal/lg/init.go +++ /dev/null @@ -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) -} diff --git a/internal/lg/logger.go b/internal/lg/logger.go deleted file mode 100644 index 80cb813..0000000 --- a/internal/lg/logger.go +++ /dev/null @@ -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 -} diff --git a/internal/lg/metric.go b/internal/lg/metric.go deleted file mode 100644 index d8018ef..0000000 --- a/internal/lg/metric.go +++ /dev/null @@ -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) -} diff --git a/internal/lg/tracer.go b/internal/lg/tracer.go deleted file mode 100644 index d88ff99..0000000 --- a/internal/lg/tracer.go +++ /dev/null @@ -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 -} diff --git a/pkg/authreq/authreq.go b/pkg/authreq/authreq.go deleted file mode 100644 index 045372f..0000000 --- a/pkg/authreq/authreq.go +++ /dev/null @@ -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 -} diff --git a/pkg/authreq/authreq_test.go b/pkg/authreq/authreq_test.go deleted file mode 100644 index f6c5c82..0000000 --- a/pkg/authreq/authreq_test.go +++ /dev/null @@ -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) -} diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go deleted file mode 100644 index 29cf5d9..0000000 --- a/pkg/cache/cache.go +++ /dev/null @@ -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 -} diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go deleted file mode 100644 index 68ee8a0..0000000 --- a/pkg/cache/cache_test.go +++ /dev/null @@ -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) -} diff --git a/pkg/cache/list.go b/pkg/cache/list.go deleted file mode 100644 index dde3a9c..0000000 --- a/pkg/cache/list.go +++ /dev/null @@ -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) - } -} diff --git a/pkg/cache/lru.go b/pkg/cache/lru.go deleted file mode 100644 index 5c5584c..0000000 --- a/pkg/cache/lru.go +++ /dev/null @@ -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) - } -} diff --git a/pkg/cron/cron.go b/pkg/cron/cron.go deleted file mode 100644 index bb5131d..0000000 --- a/pkg/cron/cron.go +++ /dev/null @@ -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) -} diff --git a/pkg/es/driver/disk-store/disk-store.go b/pkg/driver/disk-store/disk-store.go similarity index 94% rename from pkg/es/driver/disk-store/disk-store.go rename to pkg/driver/disk-store/disk-store.go index e4e551f..afc690d 100644 --- a/pkg/es/driver/disk-store/disk-store.go +++ b/pkg/driver/disk-store/disk-store.go @@ -13,16 +13,17 @@ import ( "github.com/tidwall/wal" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/instrument/syncint64" + "go.opentelemetry.io/otel/metric" "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/internal/lg" - "go.sour.is/ev/pkg/cache" - "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" + "go.sour.is/ev/pkg/driver" + "go.sour.is/ev/pkg/event" ) const CachSize = 1000 @@ -35,10 +36,10 @@ type diskStore struct { path string openlogs *locker.Locked[openlogs] - m_disk_open syncint64.Counter - m_disk_evict syncint64.Counter - m_disk_read syncint64.Counter - m_disk_write syncint64.Counter + m_disk_open metric.Int64Counter + m_disk_evict metric.Int64Counter + m_disk_read metric.Int64Counter + m_disk_write metric.Int64Counter } const AppendOnly = ev.AppendOnly @@ -53,16 +54,16 @@ func Init(ctx context.Context) error { m := lg.Meter(ctx) 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) - d.m_disk_evict, err = m.SyncInt64().Counter("disk_evict") + d.m_disk_evict, err = m.Int64Counter("disk_evict") 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) - d.m_disk_write, err = m.SyncInt64().Counter("disk_write") + d.m_disk_write, err = m.Int64Counter("disk_write") errs = multierr.Append(errs, err) ev.Register(ctx, "file", d) diff --git a/pkg/es/driver/driver.go b/pkg/driver/driver.go similarity index 97% rename from pkg/es/driver/driver.go rename to pkg/driver/driver.go index f60b135..b0ba282 100644 --- a/pkg/es/driver/driver.go +++ b/pkg/driver/driver.go @@ -4,7 +4,7 @@ package driver import ( "context" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) type Driver interface { diff --git a/pkg/es/driver/mem-store/mem-store.go b/pkg/driver/mem-store/mem-store.go similarity index 97% rename from pkg/es/driver/mem-store/mem-store.go rename to pkg/driver/mem-store/mem-store.go index 645da9e..cf450de 100644 --- a/pkg/es/driver/mem-store/mem-store.go +++ b/pkg/driver/mem-store/mem-store.go @@ -5,12 +5,13 @@ import ( "context" "fmt" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/locker" + "go.sour.is/pkg/math" + "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "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" + "go.sour.is/ev/pkg/driver" + "go.sour.is/ev/pkg/event" ) type state struct { diff --git a/pkg/es/driver/projecter/projecter.go b/pkg/driver/projecter/projecter.go similarity index 97% rename from pkg/es/driver/projecter/projecter.go rename to pkg/driver/projecter/projecter.go index c537665..4364241 100644 --- a/pkg/es/driver/projecter/projecter.go +++ b/pkg/driver/projecter/projecter.go @@ -5,10 +5,11 @@ import ( "context" "strings" + "go.sour.is/pkg/lg" + "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/driver" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/driver" + "go.sour.is/ev/pkg/event" ) type projector struct { diff --git a/pkg/es/driver/projecter/projector_test.go b/pkg/driver/projecter/projector_test.go similarity index 96% rename from pkg/es/driver/projecter/projector_test.go rename to pkg/driver/projecter/projector_test.go index 3b3af3e..7793462 100644 --- a/pkg/es/driver/projecter/projector_test.go +++ b/pkg/driver/projecter/projector_test.go @@ -5,10 +5,11 @@ import ( "testing" "github.com/matryer/is" + "go.sour.is/ev" - "go.sour.is/ev/pkg/es/driver" - "go.sour.is/ev/pkg/es/driver/projecter" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/driver" + "go.sour.is/ev/pkg/driver/projecter" + "go.sour.is/ev/pkg/event" ) type mockDriver struct { diff --git a/pkg/es/driver/resolve-links/resolve-links.go b/pkg/driver/resolve-links/resolve-links.go similarity index 97% rename from pkg/es/driver/resolve-links/resolve-links.go rename to pkg/driver/resolve-links/resolve-links.go index 3033819..e68addb 100644 --- a/pkg/es/driver/resolve-links/resolve-links.go +++ b/pkg/driver/resolve-links/resolve-links.go @@ -5,9 +5,9 @@ import ( "errors" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/driver" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/driver" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/lg" ) type resolvelinks struct { diff --git a/pkg/es/driver/streamer/streamer.go b/pkg/driver/streamer/streamer.go similarity index 98% rename from pkg/es/driver/streamer/streamer.go rename to pkg/driver/streamer/streamer.go index b37bfb2..4e572b6 100644 --- a/pkg/es/driver/streamer/streamer.go +++ b/pkg/driver/streamer/streamer.go @@ -10,10 +10,10 @@ import ( "go.opentelemetry.io/otel/trace" "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "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/driver" + "go.sour.is/ev/pkg/event" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/locker" ) type state struct { diff --git a/pkg/env/env.go b/pkg/env/env.go deleted file mode 100644 index 305fb15..0000000 --- a/pkg/env/env.go +++ /dev/null @@ -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) -} diff --git a/pkg/es/es.graphqls b/pkg/es/es.graphqls index 86e6207..4f095c3 100644 --- a/pkg/es/es.graphqls +++ b/pkg/es/es.graphqls @@ -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") streamID: String! @goField(name: "ActualStreamID") position: Int! @goField(name: "ActualPosition") diff --git a/pkg/es/graph.go b/pkg/es/graph.go index 4c73746..04bea8d 100644 --- a/pkg/es/graph.go +++ b/pkg/es/graph.go @@ -9,10 +9,11 @@ import ( "net/http" "time" + "go.sour.is/pkg/gql" + "go.sour.is/pkg/lg" + "go.sour.is/ev" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/es/event" - "go.sour.is/ev/pkg/gql" + "go.sour.is/ev/pkg/event" ) type EventResolver interface { diff --git a/pkg/es/event/aggregate.go b/pkg/event/aggregate.go similarity index 100% rename from pkg/es/event/aggregate.go rename to pkg/event/aggregate.go diff --git a/pkg/es/event/aggregate_test.go b/pkg/event/aggregate_test.go similarity index 95% rename from pkg/es/event/aggregate_test.go rename to pkg/event/aggregate_test.go index 4fbfab1..30aa1df 100644 --- a/pkg/es/event/aggregate_test.go +++ b/pkg/event/aggregate_test.go @@ -3,7 +3,7 @@ package event_test import ( "testing" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) type Agg struct { diff --git a/pkg/es/event/events.go b/pkg/event/events.go similarity index 100% rename from pkg/es/event/events.go rename to pkg/event/events.go diff --git a/pkg/es/event/events_test.go b/pkg/event/events_test.go similarity index 98% rename from pkg/es/event/events_test.go rename to pkg/event/events_test.go index fcdc0c3..0c1ba0c 100644 --- a/pkg/es/event/events_test.go +++ b/pkg/event/events_test.go @@ -8,7 +8,7 @@ import ( "github.com/matryer/is" - "go.sour.is/ev/pkg/es/event" + "go.sour.is/ev/pkg/event" ) type DummyEvent struct { diff --git a/pkg/es/event/reflect.go b/pkg/event/reflect.go similarity index 99% rename from pkg/es/event/reflect.go rename to pkg/event/reflect.go index b455fc0..437aea8 100644 --- a/pkg/es/event/reflect.go +++ b/pkg/event/reflect.go @@ -10,8 +10,8 @@ import ( "reflect" "strings" - "go.sour.is/ev/internal/lg" - "go.sour.is/ev/pkg/locker" + "go.sour.is/pkg/lg" + "go.sour.is/pkg/locker" ) type config struct { diff --git a/pkg/gql/connection.go b/pkg/gql/connection.go deleted file mode 100644 index 4ec35e0..0000000 --- a/pkg/gql/connection.go +++ /dev/null @@ -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 -} diff --git a/pkg/gql/context.go b/pkg/gql/context.go deleted file mode 100644 index 072fa7d..0000000 --- a/pkg/gql/context.go +++ /dev/null @@ -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 -} diff --git a/pkg/gql/graphiql/playground.go b/pkg/gql/graphiql/playground.go deleted file mode 100644 index 1c23d36..0000000 --- a/pkg/gql/graphiql/playground.go +++ /dev/null @@ -1,120 +0,0 @@ -package graphiql - -import ( - "html/template" - "net/http" - "net/url" -) - -var page = template.Must(template.New("graphiql").Parse(` - - - - {{.title}} - - - - - - -
Loading...
- - - - - - -`)) - -// 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() -} diff --git a/pkg/gql/playground/playground.go b/pkg/gql/playground/playground.go deleted file mode 100644 index d77c737..0000000 --- a/pkg/gql/playground/playground.go +++ /dev/null @@ -1,62 +0,0 @@ -package playground - -import ( - "html/template" - "net/http" -) - -var page = template.Must(template.New("graphiql").Parse(` - - - - - - - - - {{.title}} - - - -
- - - -`)) - -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) - } - } -} diff --git a/pkg/gql/resolver/resolver.go b/pkg/gql/resolver/resolver.go deleted file mode 100644 index 2881775..0000000 --- a/pkg/gql/resolver/resolver.go +++ /dev/null @@ -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 -} diff --git a/pkg/locker/locker.go b/pkg/locker/locker.go deleted file mode 100644 index be5461e..0000000 --- a/pkg/locker/locker.go +++ /dev/null @@ -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") diff --git a/pkg/locker/locker_test.go b/pkg/locker/locker_test.go deleted file mode 100644 index 9c28dd9..0000000 --- a/pkg/locker/locker_test.go +++ /dev/null @@ -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)) -} diff --git a/pkg/math/math.go b/pkg/math/math.go deleted file mode 100644 index 117b63f..0000000 --- a/pkg/math/math.go +++ /dev/null @@ -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 -} diff --git a/pkg/math/math_test.go b/pkg/math/math_test.go deleted file mode 100644 index 0537d77..0000000 --- a/pkg/math/math_test.go +++ /dev/null @@ -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) - } -} diff --git a/pkg/mux/httpmux.go b/pkg/mux/httpmux.go deleted file mode 100644 index add065f..0000000 --- a/pkg/mux/httpmux.go +++ /dev/null @@ -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) } diff --git a/pkg/mux/httpmux_test.go b/pkg/mux/httpmux_test.go deleted file mode 100644 index 34173d6..0000000 --- a/pkg/mux/httpmux_test.go +++ /dev/null @@ -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) -} diff --git a/pkg/service/service.go b/pkg/service/service.go deleted file mode 100644 index cf6cfd9..0000000 --- a/pkg/service/service.go +++ /dev/null @@ -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)" -} diff --git a/pkg/set/set.go b/pkg/set/set.go deleted file mode 100644 index 6aaf5a7..0000000 --- a/pkg/set/set.go +++ /dev/null @@ -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()" - } - 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() -} diff --git a/pkg/set/set_test.go b/pkg/set/set_test.go deleted file mode 100644 index 13af572..0000000 --- a/pkg/set/set_test.go +++ /dev/null @@ -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()") -} - -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)") - -} diff --git a/pkg/slice/slice.go b/pkg/slice/slice.go deleted file mode 100644 index 48b3f2c..0000000 --- a/pkg/slice/slice.go +++ /dev/null @@ -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 - -} diff --git a/pkg/slice/slice_test.go b/pkg/slice/slice_test.go deleted file mode 100644 index 6293b4f..0000000 --- a/pkg/slice/slice_test.go +++ /dev/null @@ -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 }