Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring: use fx library #86

Merged
merged 5 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions cmd/api/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package main

import (
"context"
"net/http"

"github.com/celenium-io/astria-indexer/cmd/api/bus"
"github.com/celenium-io/astria-indexer/cmd/api/cache"
"github.com/celenium-io/astria-indexer/cmd/api/handler/websocket"
"github.com/celenium-io/astria-indexer/internal/storage"
"github.com/dipdup-net/indexer-sdk/pkg/storage/postgres"
"github.com/grafana/pyroscope-go"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
"go.uber.org/fx"
)

type App struct {
e *echo.Echo
db *postgres.Storage
wsManager *websocket.Manager
dispatcher *bus.Dispatcher
constantCache *cache.ConstantsCache
endpointCache *cache.Cache
prscp *pyroscope.Profiler
constants storage.IConstant
}

func newApp(
lc fx.Lifecycle,
cfg *Config,
e *echo.Echo,
db *postgres.Storage,
wsManager *websocket.Manager,
dispatcher *bus.Dispatcher,
constantCache *cache.ConstantsCache,
endpointCache *cache.Cache,
prscp *pyroscope.Profiler,
constants storage.IConstant,
) *App {
app := &App{
e: e,
db: db,
wsManager: wsManager,
dispatcher: dispatcher,
constantCache: constantCache,
endpointCache: endpointCache,
prscp: prscp,
constants: constants,
}

lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
dispatcher.Start(ctx)
wsManager.Start(ctx)
endpointCache.Start(ctx)
if err := constantCache.Start(ctx, app.constants); err != nil {
return errors.Wrap(err, "start constant cache")
}

if err := app.e.Start(cfg.ApiConfig.Bind); err != nil && errors.Is(err, http.ErrServerClosed) {
return errors.Wrap(err, "shutting down the server")
}
return nil
},
OnStop: func(ctx context.Context) error {
if app.wsManager != nil {
if err := app.wsManager.Close(); err != nil {
return errors.Wrap(err, "closing websocket manager")
}
}
if app.endpointCache != nil {
if err := app.endpointCache.Close(); err != nil {
return errors.Wrap(err, "closing cache")
}
}
if app.constantCache != nil {
if err := app.constantCache.Close(); err != nil {
return errors.Wrap(err, "closing constant cache")
}
}
if app.dispatcher != nil {
if err := app.dispatcher.Close(); err != nil {
return errors.Wrap(err, "closing bus dispatcher")
}
}

if err := app.e.Shutdown(ctx); err != nil {
return errors.Wrap(err, "closing server")
}

if app.prscp != nil {
if err := app.prscp.Stop(); err != nil {
return errors.Wrap(err, "closing profler")
}
}
if err := app.db.Close(); err != nil {
return errors.Wrap(err, "closing database")
}
return nil
},
})
return app
}
8 changes: 8 additions & 0 deletions cmd/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ type ApiConfig struct {
SentryDsn string `validate:"omitempty" yaml:"sentry_dsn"`
Websocket bool `validate:"omitempty" yaml:"websocket"`
}

func indexerName(cfg *Config) string {
return cfg.Indexer.Name
}

func databaseConfig(cfg *Config) config.Database {
return cfg.Database
}
20 changes: 20 additions & 0 deletions cmd/api/handler/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ func NewAddressHandler(
}
}

var _ Handler = (*AddressHandler)(nil)

func (handler *AddressHandler) InitRoutes(srvr *echo.Group) {
addressesGroup := srvr.Group("/address")
{
addressesGroup.GET("", handler.List)
addressesGroup.GET("/count", handler.Count)
addressGroup := addressesGroup.Group("/:hash")
{
addressGroup.GET("", handler.Get)
addressGroup.GET("/txs", handler.Transactions)
addressGroup.GET("/actions", handler.Actions)
addressGroup.GET("/rollups", handler.Rollups)
addressGroup.GET("/roles", handler.Roles)
addressGroup.GET("/fees", handler.Fees)
addressGroup.GET("/deposits", handler.Deposits)
}
}
}

type getAddressRequest struct {
Hash string `param:"hash" validate:"required,address"`
}
Expand Down
13 changes: 13 additions & 0 deletions cmd/api/handler/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ func NewAppHandler(
}
}

var _ Handler = (*AppHandler)(nil)

func (handler *AppHandler) InitRoutes(srvr *echo.Group) {
apps := srvr.Group("/app")
{
apps.GET("", handler.Leaderboard)
app := apps.Group("/:slug")
{
app.GET("", handler.Get)
}
}
}

type leaderboardRequest struct {
Limit int `query:"limit" validate:"omitempty,min=1,max=100"`
Offset int `query:"offset" validate:"omitempty,min=0"`
Expand Down
9 changes: 9 additions & 0 deletions cmd/api/handler/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ func NewAssetHandler(
}
}

var _ Handler = (*AssetHandler)(nil)

func (handler *AssetHandler) InitRoutes(srvr *echo.Group) {
assets := srvr.Group("/asset")
{
assets.GET("", handler.List)
}
}

type assetListRequest struct {
Limit uint64 `query:"limit" validate:"omitempty,min=1,max=100"`
Offset uint64 `query:"offset" validate:"omitempty,min=0"`
Expand Down
19 changes: 19 additions & 0 deletions cmd/api/handler/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ func NewBlockHandler(
}
}

var _ Handler = (*BlockHandler)(nil)

func (handler *BlockHandler) InitRoutes(srvr *echo.Group) {
blockGroup := srvr.Group("/block")
{
blockGroup.GET("", handler.List)
blockGroup.GET("/count", handler.Count)
heightGroup := blockGroup.Group("/:height")
{
heightGroup.GET("", handler.Get)
heightGroup.GET("/actions", handler.GetActions)
heightGroup.GET("/txs", handler.GetTransactions)
heightGroup.GET("/stats", handler.GetStats)
heightGroup.GET("/rollup_actions", handler.GetRollupActions)
heightGroup.GET("/rollup_actions/count", handler.GetRollupsActionsCount)
}
}
}

type getBlockByHeightRequest struct {
Height types.Level `param:"height" validate:"min=0"`
}
Expand Down
7 changes: 7 additions & 0 deletions cmd/api/handler/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ func NewConstantHandler(constants storage.IConstant) *ConstantHandler {
}
}

var _ Handler = (*ConstantHandler)(nil)

func (handler *ConstantHandler) InitRoutes(srvr *echo.Group) {
srvr.GET("/constants", handler.Get)
srvr.GET("/enums", handler.Enums)
}

// Get godoc
//
// @Summary Get network constants
Expand Down
7 changes: 7 additions & 0 deletions cmd/api/handler/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package handler

import "github.com/labstack/echo/v4"

type Handler interface {
InitRoutes(srvr *echo.Group)
}
20 changes: 20 additions & 0 deletions cmd/api/handler/rollup.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ func NewRollupHandler(
}
}

var _ Handler = (*RollupHandler)(nil)

func (handler *RollupHandler) InitRoutes(srvr *echo.Group) {
rollupsGroup := srvr.Group("/rollup")
{
rollupsGroup.GET("", handler.List)
rollupsGroup.GET("/count", handler.Count)

rollupGroup := rollupsGroup.Group("/:hash")
{
rollupGroup.GET("", handler.Get)
rollupGroup.GET("/actions", handler.Actions)
rollupGroup.GET("/all_actions", handler.AllActions)
rollupGroup.GET("/addresses", handler.Addresses)
rollupGroup.GET("/bridges", handler.Bridges)
rollupGroup.GET("/deposits", handler.Deposits)
}
}
}

type getRollupRequest struct {
Hash string `param:"hash" validate:"required,base64url"`
}
Expand Down
6 changes: 6 additions & 0 deletions cmd/api/handler/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ func NewSearchHandler(
}
}

var _ Handler = (*SearchHandler)(nil)

func (s *SearchHandler) InitRoutes(srvr *echo.Group) {
srvr.GET("/search", s.Search)
}

type searchRequest struct {
Search string `query:"query" validate:"required"`
}
Expand Down
6 changes: 6 additions & 0 deletions cmd/api/handler/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ func NewStateHandler(state storage.IState) *StateHandler {
}
}

var _ Handler = (*StateHandler)(nil)

func (sh *StateHandler) InitRoutes(srvr *echo.Group) {
srvr.GET("/head", sh.Head)
}

// Head godoc
//
// @Summary Get current indexer head
Expand Down
45 changes: 36 additions & 9 deletions cmd/api/handler/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,40 @@ type StatsHandler struct {
rollups storage.IRollup
}

func NewStatsHandler(repo storage.IStats, rollups storage.IRollup) StatsHandler {
return StatsHandler{
func NewStatsHandler(repo storage.IStats, rollups storage.IRollup) *StatsHandler {
return &StatsHandler{
repo: repo,
rollups: rollups,
}
}

var _ Handler = (*StatsHandler)(nil)

func (sh *StatsHandler) InitRoutes(srvr *echo.Group) {
stats := srvr.Group("/stats")
{
stats.GET("/summary", sh.Summary)
stats.GET("/summary/:timeframe", sh.SummaryTimeframe)
stats.GET("/summary/active_addresses_count", sh.ActiveAddressesCount)
stats.GET("/series/:name/:timeframe", sh.Series)

rollup := stats.Group("/rollup")
{
rollup.GET("/series/:hash/:name/:timeframe", sh.RollupSeries)
}

fee := stats.Group("/fee")
{
fee.GET("/summary", sh.FeeSummary)
}

token := stats.Group("/token")
{
token.GET("/transfer_distribution", sh.TokenTransferDistribution)
}
}
}

// Summary godoc
//
// @Summary Get network summary
Expand All @@ -34,7 +61,7 @@ func NewStatsHandler(repo storage.IStats, rollups storage.IRollup) StatsHandler
// @Success 200 {array} responses.NetworkSummary
// @Failure 500 {object} Error
// @Router /v1/stats/summary [get]
func (sh StatsHandler) Summary(c echo.Context) error {
func (sh *StatsHandler) Summary(c echo.Context) error {
summary, err := sh.repo.Summary(c.Request().Context())
if err != nil {
return handleError(c, err, sh.rollups)
Expand All @@ -58,7 +85,7 @@ type summaryTimeframeRequest struct {
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Router /v1/stats/summary/{timeframe} [get]
func (sh StatsHandler) SummaryTimeframe(c echo.Context) error {
func (sh *StatsHandler) SummaryTimeframe(c echo.Context) error {
req, err := bindAndValidate[summaryTimeframeRequest](c)
if err != nil {
return badRequestError(c, err)
Expand Down Expand Up @@ -93,7 +120,7 @@ type seriesRequest struct {
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Router /v1/stats/series/{name}/{timeframe} [get]
func (sh StatsHandler) Series(c echo.Context) error {
func (sh *StatsHandler) Series(c echo.Context) error {
req, err := bindAndValidate[seriesRequest](c)
if err != nil {
return badRequestError(c, err)
Expand Down Expand Up @@ -140,7 +167,7 @@ type rollupSeriesRequest struct {
// @Failure 400 {object} Error
// @Failure 500 {object} Error
// @Router /v1/stats/rollup/series/{hash}/{name}/{timeframe} [get]
func (sh StatsHandler) RollupSeries(c echo.Context) error {
func (sh *StatsHandler) RollupSeries(c echo.Context) error {
req, err := bindAndValidate[rollupSeriesRequest](c)
if err != nil {
return badRequestError(c, err)
Expand Down Expand Up @@ -184,7 +211,7 @@ func (sh StatsHandler) RollupSeries(c echo.Context) error {
// @Success 200 {array} responses.FeeSummary
// @Failure 500 {object} Error
// @Router /v1/stats/fee/summary [get]
func (sh StatsHandler) FeeSummary(c echo.Context) error {
func (sh *StatsHandler) FeeSummary(c echo.Context) error {
summary, err := sh.repo.FeeSummary(c.Request().Context())
if err != nil {
return handleError(c, err, sh.rollups)
Expand Down Expand Up @@ -217,7 +244,7 @@ func (p *tokenTransferDistributionRequest) SetDefault() {
// @Success 200 {array} responses.TokenTransferDistributionItem
// @Failure 500 {object} Error
// @Router /v1/stats/token/transfer_distribution [get]
func (sh StatsHandler) TokenTransferDistribution(c echo.Context) error {
func (sh *StatsHandler) TokenTransferDistribution(c echo.Context) error {
req, err := bindAndValidate[tokenTransferDistributionRequest](c)
if err != nil {
return badRequestError(c, err)
Expand Down Expand Up @@ -245,7 +272,7 @@ func (sh StatsHandler) TokenTransferDistribution(c echo.Context) error {
// @Success 200 {integer} int64
// @Failure 500 {object} Error
// @Router /v1/stats/summary/active_addresses_count [get]
func (sh StatsHandler) ActiveAddressesCount(c echo.Context) error {
func (sh *StatsHandler) ActiveAddressesCount(c echo.Context) error {
count, err := sh.repo.ActiveAddressesCount(c.Request().Context())
if err != nil {
return handleError(c, err, sh.rollups)
Expand Down
2 changes: 1 addition & 1 deletion cmd/api/handler/stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type StatsTestSuite struct {
stats *mock.MockIStats
rollups *mock.MockIRollup
echo *echo.Echo
handler StatsHandler
handler *StatsHandler
ctrl *gomock.Controller
}

Expand Down
Loading