refactor(entrypoint): move route registry into entrypoint context

Replace global routes registry with entrypoint-scoped pools and
context lookups, and centralize API/metrics startup in config state.
This commit is contained in:
yusing
2026-02-06 00:23:12 +08:00
parent bd49f1b348
commit f9ee33f464
47 changed files with 916 additions and 835 deletions

View File

@@ -10,7 +10,7 @@ import (
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/yusing/godoxy/internal/docker"
"github.com/yusing/godoxy/internal/route/routes"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/types"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
@@ -44,7 +44,7 @@ func Stats(c *gin.Context) {
dockerCfg, ok := docker.GetDockerCfgByContainerID(id)
if !ok {
var route types.Route
route, ok = routes.GetIncludeExcluded(id)
route, ok = entrypoint.FromCtx(c.Request.Context()).GetRoute(id)
if ok {
cont := route.ContainerInfo()
if cont == nil {

View File

@@ -5,9 +5,9 @@ import (
"net/http"
"github.com/gin-gonic/gin"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/homepage/icons"
iconfetch "github.com/yusing/godoxy/internal/homepage/icons/fetch"
"github.com/yusing/godoxy/internal/route/routes"
apitypes "github.com/yusing/goutils/apitypes"
_ "unsafe"
@@ -73,7 +73,8 @@ func FavIcon(c *gin.Context) {
//go:linkname GetFavIconFromAlias v1.GetFavIconFromAlias
func GetFavIconFromAlias(ctx context.Context, alias string, variant icons.Variant) (iconfetch.Result, error) {
// try with route.Icon
r, ok := routes.HTTP.Get(alias)
ep := entrypoint.FromCtx(ctx)
r, ok := ep.HTTPRoutes().Get(alias)
if !ok {
return iconfetch.FetchResultWithErrorf(http.StatusNotFound, "route not found")
}

View File

@@ -5,7 +5,7 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/route/routes"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
@@ -24,11 +24,12 @@ import (
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /health [get]
func Health(c *gin.Context) {
ep := entrypoint.FromCtx(c.Request.Context())
if httpheaders.IsWebsocket(c.Request.Header) {
websocket.PeriodicWrite(c, 1*time.Second, func() (any, error) {
return routes.GetHealthInfoSimple(), nil
return ep.GetHealthInfoSimple(), nil
})
} else {
c.JSON(http.StatusOK, routes.GetHealthInfoSimple())
c.JSON(http.StatusOK, ep.GetHealthInfoSimple())
}
}

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/route/routes"
_ "github.com/yusing/goutils/apitypes"
)
@@ -21,15 +21,16 @@ import (
// @Failure 403 {object} apitypes.ErrorResponse
// @Router /homepage/categories [get]
func Categories(c *gin.Context) {
c.JSON(http.StatusOK, HomepageCategories())
ep := entrypoint.FromCtx(c.Request.Context())
c.JSON(http.StatusOK, HomepageCategories(ep))
}
func HomepageCategories() []string {
func HomepageCategories(ep entrypoint.Entrypoint) []string {
check := make(map[string]struct{})
categories := make([]string, 0)
categories = append(categories, homepage.CategoryAll)
categories = append(categories, homepage.CategoryFavorites)
for _, r := range routes.HTTP.Iter {
for _, r := range ep.HTTPRoutes().Iter {
item := r.HomepageItem()
if item.Category == "" {
continue

View File

@@ -10,8 +10,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/lithammer/fuzzysearch/fuzzy"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/route/routes"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
@@ -53,29 +53,30 @@ func Items(c *gin.Context) {
hostname = host
}
ep := entrypoint.FromCtx(c.Request.Context())
if httpheaders.IsWebsocket(c.Request.Header) {
websocket.PeriodicWrite(c, 2*time.Second, func() (any, error) {
return HomepageItems(proto, hostname, &request), nil
return HomepageItems(ep, proto, hostname, &request), nil
})
} else {
c.JSON(http.StatusOK, HomepageItems(proto, hostname, &request))
c.JSON(http.StatusOK, HomepageItems(ep, proto, hostname, &request))
}
}
func HomepageItems(proto, hostname string, request *HomepageItemsRequest) homepage.Homepage {
func HomepageItems(ep entrypoint.Entrypoint, proto, hostname string, request *HomepageItemsRequest) homepage.Homepage {
switch proto {
case "http", "https":
default:
proto = "http"
}
hp := homepage.NewHomepageMap(routes.HTTP.Size())
hp := homepage.NewHomepageMap(ep.HTTPRoutes().Size())
if strings.Count(hostname, ".") > 1 {
_, hostname, _ = strings.Cut(hostname, ".") // remove the subdomain
}
for _, r := range routes.HTTP.Iter {
for _, r := range ep.HTTPRoutes().Iter {
if request.Provider != "" && r.ProviderName() != request.Provider {
continue
}

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
_ "github.com/yusing/goutils/apitypes"
)
@@ -24,5 +24,6 @@ type RoutesByProvider map[string][]route.Route
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /route/by_provider [get]
func ByProvider(c *gin.Context) {
c.JSON(http.StatusOK, routes.ByProvider())
ep := entrypoint.FromCtx(c.Request.Context())
c.JSON(http.StatusOK, ep.RoutesByProvider())
}

View File

@@ -4,7 +4,7 @@ import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/route/routes"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
apitypes "github.com/yusing/goutils/apitypes"
)
@@ -32,7 +32,8 @@ func Route(c *gin.Context) {
return
}
route, ok := routes.GetIncludeExcluded(request.Which)
ep := entrypoint.FromCtx(c.Request.Context())
route, ok := ep.GetRoute(request.Which)
if ok {
c.JSON(http.StatusOK, route)
return

View File

@@ -6,8 +6,8 @@ import (
"time"
"github.com/gin-gonic/gin"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
@@ -32,14 +32,16 @@ func Routes(c *gin.Context) {
return
}
ep := entrypoint.FromCtx(c.Request.Context())
provider := c.Query("provider")
if provider == "" {
c.JSON(http.StatusOK, slices.Collect(routes.IterAll))
c.JSON(http.StatusOK, slices.Collect(ep.IterRoutes))
return
}
rts := make([]types.Route, 0, routes.NumAllRoutes())
for r := range routes.IterAll {
rts := make([]types.Route, 0, ep.NumRoutes())
for r := range ep.IterRoutes {
if r.ProviderName() == provider {
rts = append(rts, r)
}
@@ -48,17 +50,19 @@ func Routes(c *gin.Context) {
}
func RoutesWS(c *gin.Context) {
ep := entrypoint.FromCtx(c.Request.Context())
provider := c.Query("provider")
if provider == "" {
websocket.PeriodicWrite(c, 3*time.Second, func() (any, error) {
return slices.Collect(routes.IterAll), nil
return slices.Collect(ep.IterRoutes), nil
})
return
}
websocket.PeriodicWrite(c, 3*time.Second, func() (any, error) {
rts := make([]types.Route, 0, routes.NumAllRoutes())
for r := range routes.IterAll {
rts := make([]types.Route, 0, ep.NumRoutes())
for r := range ep.IterRoutes {
if r.ProviderName() == provider {
rts = append(rts, r)
}