mirror of
https://github.com/elyby/chrly.git
synced 2025-05-31 14:11:51 +05:30
Introduce di into the project
This commit is contained in:
14
Gopkg.lock
generated
14
Gopkg.lock
generated
@@ -63,6 +63,19 @@
|
|||||||
pruneopts = ""
|
pruneopts = ""
|
||||||
revision = "919484f041ea21e7e27be291cee1d6af7bc98864"
|
revision = "919484f041ea21e7e27be291cee1d6af7bc98864"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:c17a0163edf9a1b0f5d9e856673413b924939cf433ebf041ec309e8273fd9d2b"
|
||||||
|
name = "github.com/goava/di"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"internal/graph",
|
||||||
|
"internal/reflection",
|
||||||
|
"internal/stacktrace",
|
||||||
|
]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "6dcd92e58bd0fb2ff77cec60557abea1dae46571"
|
||||||
|
version = "v1.1.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:65c7ed49d9f36dd4752e43013323fa9229db60b29aa4f5a75aaecda3130c74e2"
|
digest = "1:65c7ed49d9f36dd4752e43013323fa9229db60b29aa4f5a75aaecda3130c74e2"
|
||||||
name = "github.com/gorilla/mux"
|
name = "github.com/gorilla/mux"
|
||||||
@@ -321,6 +334,7 @@
|
|||||||
"github.com/asaskevich/EventBus",
|
"github.com/asaskevich/EventBus",
|
||||||
"github.com/etherlabsio/healthcheck",
|
"github.com/etherlabsio/healthcheck",
|
||||||
"github.com/getsentry/raven-go",
|
"github.com/getsentry/raven-go",
|
||||||
|
"github.com/goava/di",
|
||||||
"github.com/gorilla/mux",
|
"github.com/gorilla/mux",
|
||||||
"github.com/h2non/gock",
|
"github.com/h2non/gock",
|
||||||
"github.com/mediocregopher/radix.v2/pool",
|
"github.com/mediocregopher/radix.v2/pool",
|
||||||
|
@@ -45,6 +45,10 @@ ignored = ["github.com/elyby/chrly"]
|
|||||||
name = "github.com/etherlabsio/healthcheck"
|
name = "github.com/etherlabsio/healthcheck"
|
||||||
version = "2.0.3"
|
version = "2.0.3"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/goava/di"
|
||||||
|
version = "^1.0.2"
|
||||||
|
|
||||||
# Testing dependencies
|
# Testing dependencies
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/elyby/chrly/http"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/elyby/chrly/http"
|
||||||
"github.com/elyby/chrly/mojangtextures"
|
"github.com/elyby/chrly/mojangtextures"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ type RepositoriesCreator interface {
|
|||||||
CreateMojangUuidsRepository() (mojangtextures.UuidsStorage, error)
|
CreateMojangUuidsRepository() (mojangtextures.UuidsStorage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: redundant
|
||||||
func (factory *StorageFactory) CreateFactory(backend string) RepositoriesCreator {
|
func (factory *StorageFactory) CreateFactory(backend string) RepositoriesCreator {
|
||||||
switch backend {
|
switch backend {
|
||||||
case "redis":
|
case "redis":
|
||||||
|
14
di/config.go
Normal file
14
di/config.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goava/di"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var config = di.Options(
|
||||||
|
di.Provide(newConfig),
|
||||||
|
)
|
||||||
|
|
||||||
|
func newConfig() *viper.Viper {
|
||||||
|
return viper.GetViper()
|
||||||
|
}
|
77
di/db.go
Normal file
77
di/db.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goava/di"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
dbModule "github.com/elyby/chrly/db"
|
||||||
|
"github.com/elyby/chrly/http"
|
||||||
|
"github.com/elyby/chrly/mojangtextures"
|
||||||
|
)
|
||||||
|
|
||||||
|
var db = di.Options(
|
||||||
|
di.Provide(newRedisFactory, di.WithName("redis")),
|
||||||
|
di.Provide(newFSFactory, di.WithName("fs")),
|
||||||
|
di.Provide(newSkinsRepository),
|
||||||
|
di.Provide(newCapesRepository),
|
||||||
|
di.Provide(newMojangUUIDsRepository),
|
||||||
|
di.Provide(newMojangSignedTexturesStorage),
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRedisFactory(config *viper.Viper) dbModule.RepositoriesCreator {
|
||||||
|
return &dbModule.RedisFactory{
|
||||||
|
Host: config.GetString("storage.redis.host"),
|
||||||
|
Port: config.GetInt("storage.redis.port"),
|
||||||
|
PoolSize: config.GetInt("storage.redis.poolSize"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFSFactory(config *viper.Viper) dbModule.RepositoriesCreator {
|
||||||
|
return &dbModule.FilesystemFactory{
|
||||||
|
BasePath: config.GetString("storage.filesystem.basePath"),
|
||||||
|
CapesDirName: config.GetString("storage.filesystem.capesDirName"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// v4 had the idea that it would be possible to separate backends for storing skins and capes.
|
||||||
|
// But in v5 the storage will be unified, so this is just temporary constructors before large reworking.
|
||||||
|
//
|
||||||
|
// Since there are no options for selecting target backends,
|
||||||
|
// all constants in this case point to static specific implementations.
|
||||||
|
|
||||||
|
func newSkinsRepository(container *di.Container) (http.SkinsRepository, error) {
|
||||||
|
var factory dbModule.RepositoriesCreator
|
||||||
|
err := container.Resolve(&factory, di.Name("redis"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory.CreateSkinsRepository()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCapesRepository(container *di.Container) (http.CapesRepository, error) {
|
||||||
|
var factory dbModule.RepositoriesCreator
|
||||||
|
err := container.Resolve(&factory, di.Name("fs"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory.CreateCapesRepository()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangUUIDsRepository(container *di.Container) (mojangtextures.UuidsStorage, error) {
|
||||||
|
var factory dbModule.RepositoriesCreator
|
||||||
|
err := container.Resolve(&factory, di.Name("redis"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory.CreateMojangUuidsRepository()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangSignedTexturesStorage() mojangtextures.TexturesStorage {
|
||||||
|
texturesStorage := mojangtextures.NewInMemoryTexturesStorage()
|
||||||
|
texturesStorage.Start()
|
||||||
|
|
||||||
|
return texturesStorage
|
||||||
|
}
|
33
di/di.go
Normal file
33
di/di.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import "github.com/goava/di"
|
||||||
|
|
||||||
|
func New() (*di.Container, error) {
|
||||||
|
container, err := di.New(
|
||||||
|
di.WithCompile(),
|
||||||
|
config,
|
||||||
|
dispatcher,
|
||||||
|
logger,
|
||||||
|
db,
|
||||||
|
mojangTextures,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject container itself into dependencies graph
|
||||||
|
// See https://github.com/goava/di/issues/8#issuecomment-614227320
|
||||||
|
err = container.Provide(func() *di.Container {
|
||||||
|
return container
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = container.Compile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return container, nil
|
||||||
|
}
|
20
di/dispatcher.go
Normal file
20
di/dispatcher.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goava/di"
|
||||||
|
|
||||||
|
dispatcherModule "github.com/elyby/chrly/dispatcher"
|
||||||
|
"github.com/elyby/chrly/http"
|
||||||
|
"github.com/elyby/chrly/mojangtextures"
|
||||||
|
)
|
||||||
|
|
||||||
|
var dispatcher = di.Options(
|
||||||
|
di.Provide(newDispatcher,
|
||||||
|
di.As(new(http.Emitter)),
|
||||||
|
di.As(new(mojangtextures.Emitter)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDispatcher() dispatcherModule.EventDispatcher {
|
||||||
|
return dispatcherModule.New()
|
||||||
|
}
|
41
di/handlers.go
Normal file
41
di/handlers.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goava/di"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/elyby/chrly/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var handlers = di.Options(
|
||||||
|
di.Provide(newSkinsystemHandler, di.WithName("skinsystem")),
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSkinsystemHandler(
|
||||||
|
config *viper.Viper,
|
||||||
|
emitter http.Emitter,
|
||||||
|
skinsRepository http.SkinsRepository,
|
||||||
|
capesRepository http.CapesRepository,
|
||||||
|
mojangTexturesProvider http.MojangTexturesProvider,
|
||||||
|
) *mux.Router {
|
||||||
|
handlerFactory := &http.Skinsystem{
|
||||||
|
Emitter: emitter,
|
||||||
|
SkinsRepo: skinsRepository,
|
||||||
|
CapesRepo: capesRepository,
|
||||||
|
MojangTexturesProvider: mojangTexturesProvider,
|
||||||
|
TexturesExtraParamName: config.GetString("textures.extra_param_name"),
|
||||||
|
TexturesExtraParamValue: config.GetString("textures.extra_param_value"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return handlerFactory.CreateHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: pin implementation to make it non-configurable
|
||||||
|
func newUUIDsWorkerHandler(mojangUUIDsProvider http.MojangUuidsProvider) *mux.Router {
|
||||||
|
handlerFactory := &http.UUIDsWorker{
|
||||||
|
UUIDsProvider: mojangUUIDsProvider,
|
||||||
|
}
|
||||||
|
|
||||||
|
return handlerFactory.CreateHandler()
|
||||||
|
}
|
96
di/logger.go
Normal file
96
di/logger.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/getsentry/raven-go"
|
||||||
|
"github.com/goava/di"
|
||||||
|
"github.com/mono83/slf"
|
||||||
|
"github.com/mono83/slf/rays"
|
||||||
|
"github.com/mono83/slf/recievers/sentry"
|
||||||
|
"github.com/mono83/slf/recievers/statsd"
|
||||||
|
"github.com/mono83/slf/recievers/writer"
|
||||||
|
"github.com/mono83/slf/wd"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/elyby/chrly/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logger = di.Options(
|
||||||
|
di.Provide(newLogger),
|
||||||
|
di.Provide(newSentry),
|
||||||
|
di.Provide(newStatsReporter),
|
||||||
|
)
|
||||||
|
|
||||||
|
type loggerParams struct {
|
||||||
|
di.Inject
|
||||||
|
|
||||||
|
SentryRaven *raven.Client `di:"" optional:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLogger(params loggerParams) slf.Logger {
|
||||||
|
dispatcher := &slf.Dispatcher{}
|
||||||
|
dispatcher.AddReceiver(writer.New(writer.Options{
|
||||||
|
Marker: false,
|
||||||
|
TimeFormat: "15:04:05.000",
|
||||||
|
}))
|
||||||
|
|
||||||
|
if params.SentryRaven != nil {
|
||||||
|
sentryReceiver, _ := sentry.NewReceiverWithCustomRaven(
|
||||||
|
params.SentryRaven,
|
||||||
|
&sentry.Config{
|
||||||
|
MinLevel: "warn",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
dispatcher.AddReceiver(sentryReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger := wd.Custom("", "", dispatcher)
|
||||||
|
logger.WithParams(rays.Host)
|
||||||
|
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSentry(config *viper.Viper) (*raven.Client, error) {
|
||||||
|
sentryAddr := config.GetString("sentry.dsn")
|
||||||
|
if sentryAddr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ravenClient, err := raven.New(sentryAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ravenClient.SetEnvironment("production")
|
||||||
|
ravenClient.SetDefaultLoggerName("sentry-watchdog-receiver")
|
||||||
|
ravenClient.SetRelease(version.Version())
|
||||||
|
|
||||||
|
return ravenClient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStatsReporter(config *viper.Viper) (slf.StatsReporter, error) {
|
||||||
|
statsdAddr := config.GetString("statsd.addr")
|
||||||
|
if statsdAddr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
statsdReceiver, err := statsd.NewReceiver(statsd.Config{
|
||||||
|
Address: statsdAddr,
|
||||||
|
Prefix: "ely.skinsystem." + hostname + ".app.",
|
||||||
|
FlushEvery: 1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatcher := &slf.Dispatcher{}
|
||||||
|
dispatcher.AddReceiver(statsdReceiver)
|
||||||
|
|
||||||
|
return wd.Custom("", "", dispatcher), nil
|
||||||
|
}
|
91
di/mojang_textures.go
Normal file
91
di/mojang_textures.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package di
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/goava/di"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/elyby/chrly/http"
|
||||||
|
"github.com/elyby/chrly/mojangtextures"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mojangTextures = di.Options(
|
||||||
|
di.Provide(newMojangTexturesProviderFactory),
|
||||||
|
di.Provide(newMojangTexturesProvider),
|
||||||
|
di.Provide(newMojangTexturesUuidsProvider),
|
||||||
|
di.Provide(newMojangSignedTexturesProvider),
|
||||||
|
di.Provide(newMojangTexturesStorageFactory),
|
||||||
|
)
|
||||||
|
|
||||||
|
func newMojangTexturesProviderFactory(
|
||||||
|
container *di.Container,
|
||||||
|
config *viper.Viper,
|
||||||
|
) (http.MojangTexturesProvider, error) {
|
||||||
|
if !config.GetBool("mojang_textures.enabled") {
|
||||||
|
return &mojangtextures.NilProvider{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider *mojangtextures.Provider
|
||||||
|
err := container.Resolve(&provider)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangTexturesProvider(
|
||||||
|
emitter mojangtextures.Emitter,
|
||||||
|
uuidsProvider mojangtextures.UUIDsProvider,
|
||||||
|
texturesProvider mojangtextures.TexturesProvider,
|
||||||
|
storage mojangtextures.Storage,
|
||||||
|
) *mojangtextures.Provider {
|
||||||
|
return &mojangtextures.Provider{
|
||||||
|
Emitter: emitter,
|
||||||
|
UUIDsProvider: uuidsProvider,
|
||||||
|
TexturesProvider: texturesProvider,
|
||||||
|
Storage: storage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangTexturesUuidsProvider(
|
||||||
|
config *viper.Viper,
|
||||||
|
emitter mojangtextures.Emitter,
|
||||||
|
) (mojangtextures.UUIDsProvider, error) {
|
||||||
|
preferredUuidsProvider := config.GetString("mojang_textures.uuids_provider.driver")
|
||||||
|
if preferredUuidsProvider == "remote" {
|
||||||
|
remoteUrl, err := url.Parse(config.GetString("mojang_textures.uuids_provider.url"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to parse remote url: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mojangtextures.RemoteApiUuidsProvider{
|
||||||
|
Emitter: emitter,
|
||||||
|
Url: *remoteUrl,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mojangtextures.BatchUuidsProvider{
|
||||||
|
Emitter: emitter,
|
||||||
|
IterationDelay: config.GetDuration("queue.loop_delay"),
|
||||||
|
IterationSize: config.GetInt("queue.batch_size"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangSignedTexturesProvider(emitter mojangtextures.Emitter) mojangtextures.TexturesProvider {
|
||||||
|
return &mojangtextures.MojangApiTexturesProvider{
|
||||||
|
Emitter: emitter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMojangTexturesStorageFactory(
|
||||||
|
uuidsStorage mojangtextures.UuidsStorage,
|
||||||
|
texturesStorage mojangtextures.TexturesStorage,
|
||||||
|
) mojangtextures.Storage {
|
||||||
|
return &mojangtextures.SeparatedStorage{
|
||||||
|
UuidsStorage: uuidsStorage,
|
||||||
|
TexturesStorage: texturesStorage,
|
||||||
|
}
|
||||||
|
}
|
@@ -7,20 +7,20 @@ type EventDispatcher interface {
|
|||||||
Emit(topic string, args ...interface{})
|
Emit(topic string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocalEventDispatcher struct {
|
type localEventDispatcher struct {
|
||||||
bus EventBus.Bus
|
bus EventBus.Bus
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LocalEventDispatcher) Subscribe(topic string, fn interface{}) {
|
func (d *localEventDispatcher) Subscribe(topic string, fn interface{}) {
|
||||||
_ = d.bus.Subscribe(topic, fn)
|
_ = d.bus.Subscribe(topic, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LocalEventDispatcher) Emit(topic string, args ...interface{}) {
|
func (d *localEventDispatcher) Emit(topic string, args ...interface{}) {
|
||||||
d.bus.Publish(topic, args...)
|
d.bus.Publish(topic, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() EventDispatcher {
|
func New() EventDispatcher {
|
||||||
return &LocalEventDispatcher{
|
return &localEventDispatcher{
|
||||||
bus: EventBus.New(),
|
bus: EventBus.New(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,16 +7,15 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/elyby/chrly/api/mojang"
|
"github.com/elyby/chrly/api/mojang"
|
||||||
"github.com/elyby/chrly/mojangtextures"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type UuidsProvider interface {
|
type MojangUuidsProvider interface {
|
||||||
GetUuid(username string) (*mojang.ProfileInfo, error)
|
GetUuid(username string) (*mojang.ProfileInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UUIDsWorker struct {
|
type UUIDsWorker struct {
|
||||||
Emitter
|
Emitter
|
||||||
UUIDsProvider mojangtextures.UUIDsProvider
|
UUIDsProvider MojangUuidsProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *UUIDsWorker) CreateHandler() *mux.Router {
|
func (ctx *UUIDsWorker) CreateHandler() *mux.Router {
|
||||||
|
Reference in New Issue
Block a user