Skip to content

Commit

Permalink
refactor: Splitting large main func into more tiny pieces
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <[email protected]>
  • Loading branch information
ViBiOh committed Mar 18, 2023
1 parent 057fe8c commit 252ecc0
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 84 deletions.
17 changes: 13 additions & 4 deletions cmd/fibr/background.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ package main

import "context"

type Starter func(context.Context)
type Starter interface {
Start(context.Context)
Done() <-chan struct{}
}

type Starters []Starter

func (s Starters) Do(ctx context.Context) {
for _, start := range s {
go start(ctx)
func (s Starters) Start(ctx context.Context) {
for _, starter := range s {
go starter.Start(ctx)
}
}

func (s Starters) GracefulWait() {
for _, starter := range s {
<-starter.Done()
}
}
1 change: 0 additions & 1 deletion cmd/fibr/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func newClient(ctx context.Context, config configuration) (client, error) {

output.prometheus = prometheus.New(config.prometheus)
output.health = health.New(config.health)

output.redis = redis.New(config.redis, output.tracer.GetTracer("redis"))

output.amqp, err = amqp.New(config.amqp, output.prometheus.Registerer(), output.tracer.GetTracer("amqp"))
Expand Down
98 changes: 19 additions & 79 deletions cmd/fibr/fibr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,12 @@ import (

_ "net/http/pprof"

"github.com/ViBiOh/absto/pkg/absto"
"github.com/ViBiOh/auth/v2/pkg/ident/basic"
authMiddleware "github.com/ViBiOh/auth/v2/pkg/middleware"
basicMemory "github.com/ViBiOh/auth/v2/pkg/store/memory"
"github.com/ViBiOh/fibr/pkg/crud"
"github.com/ViBiOh/fibr/pkg/exclusive"
"github.com/ViBiOh/fibr/pkg/fibr"
"github.com/ViBiOh/fibr/pkg/metadata"
"github.com/ViBiOh/fibr/pkg/provider"
"github.com/ViBiOh/fibr/pkg/sanitizer"
"github.com/ViBiOh/fibr/pkg/search"
"github.com/ViBiOh/fibr/pkg/share"
"github.com/ViBiOh/fibr/pkg/storage"
"github.com/ViBiOh/fibr/pkg/thumbnail"
"github.com/ViBiOh/fibr/pkg/webhook"
"github.com/ViBiOh/httputils/v4/pkg/alcotest"
"github.com/ViBiOh/httputils/v4/pkg/amqphandler"
"github.com/ViBiOh/httputils/v4/pkg/httputils"
"github.com/ViBiOh/httputils/v4/pkg/logger"
"github.com/ViBiOh/httputils/v4/pkg/owasp"
"github.com/ViBiOh/httputils/v4/pkg/recoverer"
"github.com/ViBiOh/httputils/v4/pkg/renderer"
"github.com/ViBiOh/httputils/v4/pkg/server"
"go.opentelemetry.io/otel/trace"
)

Expand All @@ -48,7 +31,7 @@ func newLoginApp(tracer trace.Tracer, basicConfig basicMemory.Config) provider.A
func main() {
config, err := newConfig()
if err != nil {
logger.Fatal(fmt.Errorf("config: %w", err))
logger.Fatal(fmt.Errorf("configuration: %w", err))
}

alcotest.DoAndExit(config.alcotest)
Expand All @@ -59,77 +42,34 @@ func main() {

ctx := context.Background()

client, err := newClient(ctx, config)
clients, err := newClient(ctx, config)
if err != nil {
logger.Fatal(fmt.Errorf("client: %w", err))
logger.Fatal(fmt.Errorf("clients: %w", err))
}

defer client.Close(ctx)
defer clients.Close(ctx)

appServer := server.New(config.appServer)
promServer := server.New(config.promServer)

prometheusRegisterer := client.prometheus.Registerer()

storageApp, err := absto.New(config.absto, client.tracer.GetTracer("storage"))
logger.Fatal(err)

filteredStorage, err := storage.Get(config.storage, storageApp)
logger.Fatal(err)

eventBus, err := provider.NewEventBus(provider.MaxConcurrency, prometheusRegisterer, client.tracer.GetTracer("bus"))
logger.Fatal(err)

thumbnailApp, err := thumbnail.New(config.thumbnail, storageApp, client.redis, prometheusRegisterer, client.tracer, client.amqp)
logger.Fatal(err)

rendererApp, err := renderer.New(config.renderer, content, fibr.FuncMap, client.tracer.GetTracer("renderer"))
logger.Fatal(err)

var exclusiveApp exclusive.App
if client.redis.Enabled() {
exclusiveApp = exclusive.New(client.redis)
services, err := newServices(config, clients)
if err != nil {
logger.Fatal(fmt.Errorf("services: %w", err))
}

metadataApp, err := metadata.New(config.metadata, storageApp, prometheusRegisterer, client.tracer, client.amqp, client.redis, exclusiveApp)
logger.Fatal(err)

webhookApp := webhook.New(config.webhook, storageApp, prometheusRegisterer, client.redis, rendererApp, thumbnailApp, exclusiveApp)

shareApp, err := share.New(config.share, storageApp, client.redis, exclusiveApp)
logger.Fatal(err)

amqpThumbnailApp, err := amqphandler.New(config.amqpThumbnail, client.amqp, client.tracer.GetTracer("amqp_handler_thumbnail"), thumbnailApp.AMQPHandler)
logger.Fatal(err)

amqpExifApp, err := amqphandler.New(config.amqpExif, client.amqp, client.tracer.GetTracer("amqp_handler_exif"), metadataApp.AMQPHandler)
logger.Fatal(err)

searchApp := search.New(filteredStorage, thumbnailApp, metadataApp, exclusiveApp, client.tracer.GetTracer("search"))

crudApp, err := crud.New(config.crud, storageApp, filteredStorage, rendererApp, shareApp, webhookApp, thumbnailApp, metadataApp, searchApp, eventBus.Push, client.tracer.GetTracer("crud"))
logger.Fatal(err)

sanitizerApp := sanitizer.New(config.sanitizer, filteredStorage, exclusiveApp, crudApp, eventBus.Push)

var middlewareApp provider.Auth
if !*config.disableAuth {
middlewareApp = newLoginApp(client.tracer.GetTracer("auth"), config.basic)
}
ports := newPorts(config, clients, services)

fibrApp := fibr.New(&crudApp, rendererApp, shareApp, webhookApp, middlewareApp)
handler := rendererApp.Handler(fibrApp.TemplateFunc)
endCtx := clients.health.End(ctx)

endCtx := client.health.End(ctx)
stopOnDone := Starters{services.amqpThumbnailApp, services.amqpExifApp, services.sanitizerApp}
stopOnDone.Start(clients.health.Done(ctx))
defer stopOnDone.GracefulWait()

Starters{amqpThumbnailApp.Start, amqpExifApp.Start}.Do(client.health.Done(ctx))
Starters{webhookApp.Start, shareApp.Start, sanitizerApp.Start}.Do(endCtx)
stopOnEnd := Starters{services.webhookApp, services.shareApp}
stopOnEnd.Start(endCtx)
defer stopOnEnd.GracefulWait()

go eventBus.Start(endCtx, storageApp, []provider.Renamer{thumbnailApp.Rename, metadataApp.Rename}, shareApp.EventConsumer, thumbnailApp.EventConsumer, metadataApp.EventConsumer, webhookApp.EventConsumer)
ports.Start(endCtx)
defer ports.GracefulWait()

go promServer.Start(endCtx, "prometheus", client.prometheus.Handler())
go appServer.Start(endCtx, "http", httputils.Handler(handler, client.health, recoverer.Middleware, client.prometheus.Middleware, client.tracer.Middleware, owasp.New(config.owasp).Middleware))
go services.eventBus.Start(endCtx, services.storageApp, []provider.Renamer{services.thumbnailApp.Rename, services.metadataApp.Rename}, services.shareApp.EventConsumer, services.thumbnailApp.EventConsumer, services.metadataApp.EventConsumer, services.webhookApp.EventConsumer)

client.health.WaitForTermination(appServer.Done())
server.GracefulWait(appServer.Done(), promServer.Done(), amqpExifApp.Done(), eventBus.Done(), webhookApp.Done(), shareApp.Done())
clients.health.WaitForTermination(ports.TerminateOnDone())
}
53 changes: 53 additions & 0 deletions cmd/fibr/port.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"context"
"net/http"

"github.com/ViBiOh/httputils/v4/pkg/httputils"
"github.com/ViBiOh/httputils/v4/pkg/owasp"
"github.com/ViBiOh/httputils/v4/pkg/recoverer"
"github.com/ViBiOh/httputils/v4/pkg/server"
)

type port struct {
handler http.Handler
name string
serverApp server.App
}

type ports []port

func newPorts(config configuration, clients client, services services) ports {
return ports{
{
serverApp: server.New(config.appServer),
name: "http",
handler: httputils.Handler(
services.rendererApp.Handler(services.fibrApp.TemplateFunc),
clients.health, recoverer.Middleware, clients.prometheus.Middleware, clients.tracer.Middleware, owasp.New(config.owasp).Middleware,
),
},
{
serverApp: server.New(config.promServer),
name: "prometheus",
handler: clients.prometheus.Handler(),
},
}
}

func (p ports) Start(ctx context.Context) {
for _, instance := range p {
go instance.serverApp.Start(ctx, instance.name, instance.handler)
}
}

func (p ports) TerminateOnDone() <-chan struct{} {
return p[0].serverApp.Done()
}

func (p ports) GracefulWait() {
for _, instance := range p {
<-instance.serverApp.Done()
}
}
119 changes: 119 additions & 0 deletions cmd/fibr/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package main

import (
"github.com/ViBiOh/absto/pkg/absto"
model "github.com/ViBiOh/absto/pkg/model"
"github.com/ViBiOh/fibr/pkg/crud"
"github.com/ViBiOh/fibr/pkg/exclusive"
"github.com/ViBiOh/fibr/pkg/fibr"
"github.com/ViBiOh/fibr/pkg/metadata"
"github.com/ViBiOh/fibr/pkg/provider"
"github.com/ViBiOh/fibr/pkg/sanitizer"
"github.com/ViBiOh/fibr/pkg/search"
"github.com/ViBiOh/fibr/pkg/share"
"github.com/ViBiOh/fibr/pkg/storage"
"github.com/ViBiOh/fibr/pkg/thumbnail"
"github.com/ViBiOh/fibr/pkg/webhook"
"github.com/ViBiOh/httputils/v4/pkg/amqphandler"
"github.com/ViBiOh/httputils/v4/pkg/renderer"
)

type services struct {
eventBus provider.EventBus
storageApp model.Storage
webhookApp *webhook.App
shareApp *share.App
sanitizerApp sanitizer.App
fibrApp fibr.App
rendererApp renderer.App
amqpThumbnailApp amqphandler.App
amqpExifApp amqphandler.App
metadataApp metadata.App
thumbnailApp thumbnail.App
}

func newServices(config configuration, clients client) (services, error) {
prometheusRegisterer := clients.prometheus.Registerer()

storageApp, err := absto.New(config.absto, clients.tracer.GetTracer("storage"))
if err != nil {
return services{}, err
}

filteredStorage, err := storage.Get(config.storage, storageApp)
if err != nil {
return services{}, err
}

eventBus, err := provider.NewEventBus(provider.MaxConcurrency, prometheusRegisterer, clients.tracer.GetTracer("bus"))
if err != nil {
return services{}, err
}

thumbnailApp, err := thumbnail.New(config.thumbnail, storageApp, clients.redis, prometheusRegisterer, clients.tracer, clients.amqp)
if err != nil {
return services{}, err
}

rendererApp, err := renderer.New(config.renderer, content, fibr.FuncMap, clients.tracer.GetTracer("renderer"))
if err != nil {
return services{}, err
}

var exclusiveApp exclusive.App
if clients.redis.Enabled() {
exclusiveApp = exclusive.New(clients.redis)
}

metadataApp, err := metadata.New(config.metadata, storageApp, prometheusRegisterer, clients.tracer, clients.amqp, clients.redis, exclusiveApp)
if err != nil {
return services{}, err
}

webhookApp := webhook.New(config.webhook, storageApp, prometheusRegisterer, clients.redis, rendererApp, thumbnailApp, exclusiveApp)

shareApp, err := share.New(config.share, storageApp, clients.redis, exclusiveApp)
if err != nil {
return services{}, err
}

amqpThumbnailApp, err := amqphandler.New(config.amqpThumbnail, clients.amqp, clients.tracer.GetTracer("amqp_handler_thumbnail"), thumbnailApp.AMQPHandler)
if err != nil {
return services{}, err
}

amqpExifApp, err := amqphandler.New(config.amqpExif, clients.amqp, clients.tracer.GetTracer("amqp_handler_exif"), metadataApp.AMQPHandler)
if err != nil {
return services{}, err
}

searchApp := search.New(filteredStorage, thumbnailApp, metadataApp, exclusiveApp, clients.tracer.GetTracer("search"))

crudApp, err := crud.New(config.crud, storageApp, filteredStorage, rendererApp, shareApp, webhookApp, thumbnailApp, metadataApp, searchApp, eventBus.Push, clients.tracer.GetTracer("crud"))
if err != nil {
return services{}, err
}

sanitizerApp := sanitizer.New(config.sanitizer, filteredStorage, exclusiveApp, crudApp, eventBus.Push)

var middlewareApp provider.Auth
if !*config.disableAuth {
middlewareApp = newLoginApp(clients.tracer.GetTracer("auth"), config.basic)
}

fibrApp := fibr.New(&crudApp, rendererApp, shareApp, webhookApp, middlewareApp)

return services{
storageApp: storageApp,
amqpThumbnailApp: amqpThumbnailApp,
amqpExifApp: amqpExifApp,
fibrApp: fibrApp,
sanitizerApp: sanitizerApp,
rendererApp: rendererApp,
eventBus: eventBus,
webhookApp: webhookApp,
shareApp: shareApp,
thumbnailApp: thumbnailApp,
metadataApp: metadataApp,
}, nil
}
8 changes: 8 additions & 0 deletions pkg/sanitizer/sanitizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Renamer interface {
}

type App struct {
done chan struct{}
storageApp absto.Storage
exclusiveApp exclusive.App
pushEvent provider.EventProducer
Expand Down Expand Up @@ -49,6 +50,7 @@ func Flags(fs *flag.FlagSet, prefix string, overrides ...flags.Override) Config

func New(config Config, storageApp absto.Storage, exclusiveApp exclusive.App, renamer Renamer, pushEvent provider.EventProducer) App {
return App{
done: make(chan struct{}),
storageApp: storageApp,
exclusiveApp: exclusiveApp,
renamer: renamer,
Expand All @@ -57,7 +59,13 @@ func New(config Config, storageApp absto.Storage, exclusiveApp exclusive.App, re
}
}

func (a App) Done() <-chan struct{} {
return a.done
}

func (a App) Start(ctx context.Context) {
defer close(a.done)

if err := a.exclusiveApp.Execute(ctx, "fibr:mutex:start", time.Hour, func(ctx context.Context) error {
a.start(ctx)
return nil
Expand Down

0 comments on commit 252ecc0

Please sign in to comment.