diff --git a/api/server.go b/api/server.go index 03f794e3..558b915d 100644 --- a/api/server.go +++ b/api/server.go @@ -158,6 +158,14 @@ func NewApiServer(config config.Config) *ApiServer { panic(err) } + sitemapPageCache, err := otter.MustBuilder[string, []byte](256). + WithTTL(sitemapPageCacheTTL). + CollectStats(). + Build() + if err != nil { + panic(err) + } + privateKey, err := crypto.HexToECDSA(config.DelegatePrivateKey) if err != nil { panic(err) @@ -268,6 +276,7 @@ func NewApiServer(config config.Config) *ApiServer { oauthTokenCache: &oauthTokenCache, qualifiedPlaylistsCache: &qualifiedPlaylistsCache, relatedUsersCache: &relatedUsersCache, + sitemapPageCache: &sitemapPageCache, requestValidator: requestValidator, rewardAttester: rewardAttester, transactionSender: transactionSender, @@ -822,6 +831,7 @@ type ApiServer struct { oauthTokenCache *otter.Cache[string, oauthTokenCacheEntry] qualifiedPlaylistsCache *otter.Cache[string, []int32] relatedUsersCache *otter.Cache[string, []int32] + sitemapPageCache *otter.Cache[string, []byte] requestValidator *RequestValidator rewardManagerClient *reward_manager.RewardManagerClient claimableTokensClient *claimable_tokens.ClaimableTokensClient diff --git a/api/v1_sitemaps.go b/api/v1_sitemaps.go index 0ec6f697..358d3d38 100644 --- a/api/v1_sitemaps.go +++ b/api/v1_sitemaps.go @@ -18,6 +18,7 @@ import ( const sitemapLimit = 40_000 const sitemapCountCacheTTL = 1 * time.Hour +const sitemapPageCacheTTL = 1 * time.Hour var sitemapPageRegex = regexp.MustCompile(`^(\d+)\.xml$`) @@ -266,6 +267,12 @@ func (app *ApiServer) sitemapTypePage(c *fiber.Ctx) error { return fiber.NewError(400, "Page number must be >= 1") } + cacheKey := entityType + ":" + fileName + if data, ok := app.sitemapPageCache.Get(cacheKey); ok { + c.Set("Content-Type", "text/xml") + return c.Send(data) + } + offset := int32((pageNumber - 1) * sitemapLimit) ctx := c.Context() baseURL := app.audiusAppUrl @@ -328,6 +335,7 @@ func (app *ApiServer) sitemapTypePage(c *fiber.Ctx) error { if err != nil { return err } + app.sitemapPageCache.Set(cacheKey, data) c.Set("Content-Type", "text/xml") return c.Send(data) } diff --git a/api/v1_sitemaps_test.go b/api/v1_sitemaps_test.go index c7a27f51..6b04a274 100644 --- a/api/v1_sitemaps_test.go +++ b/api/v1_sitemaps_test.go @@ -112,6 +112,17 @@ func TestSitemapTrackPage(t *testing.T) { assert.NotContains(t, xml, "%2F") } +func TestSitemapTrackPageCache(t *testing.T) { + app := sitemapTestApp(t) + + cached := []byte(`cached-track-page`) + require.True(t, app.sitemapPageCache.Set("track:1.xml", cached)) + + status, body := testGet(t, app, "/sitemaps/track/1.xml") + require.Equal(t, 200, status) + assert.Contains(t, string(body), "cached-track-page") +} + func TestSitemapPlaylistPage(t *testing.T) { app := sitemapTestApp(t) status, body := testGet(t, app, "/sitemaps/playlist/1.xml")