Skip to content

Commit

Permalink
feat: superstar player case cache (no parsing)
Browse files Browse the repository at this point in the history
  • Loading branch information
Napolitain committed May 2, 2024
1 parent f17645c commit 310424f
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
uses: actions/checkout@v4

- name: Remove all unnecessary files
run: rm -rf .git .txt .md .yml .gitignore .github .idea .vscode resources/
run: rm -rf .git .txt .md .yml .gitignore .github .idea .vscode resources/ *_test.go

- name: Auth to Google Cloud
uses: 'google-github-actions/auth@v2'
Expand Down
Empty file removed Dockerfile
Empty file.
28 changes: 25 additions & 3 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,39 @@ import (
)

// saveToCache function is used to saveToCache data on Memcached server.
// A cached entry is a game entry valid for 3 hours. Every player is cached at once, and then can be filtered down.
// A cached entry is a game entry valid for 1 hour. The whole entry is a HTML string to be filtered down later on for specific players.
// Reasonably fast, and extremely useful for reducing the load on the third party server Liquipedia.net.
// Likely will save a 100+ms per request.
func saveToCache(ctx context.Context, data string, game string) error {
item := &memcache.Item{
Key: game,
Value: []byte(data),
Expiration: time.Hour * 3,
Expiration: time.Hour * 1,
}
return memcache.Set(ctx, item)
}

// getFromCache function is used to retrieve data from Memcached server.
// getFromCache function is used to retrieve data from Memcached server. It returns HTML to be parsed and filtered down for specific players.
// Reasonably fast, and extremely useful for reducing the load on the third party server Liquipedia.net.
// Likely will save a 100+ms per request.
func getFromCache(ctx context.Context, game string) (*memcache.Item, error) {
return memcache.Get(ctx, game)
}

// saveToCachePlayer function is used to saveToCache data on Memcached server. It is used to saveToCache data for a specific player for a specific game.
// The whole entry is a iCalendar string, ready to be sent to the user as a response directly.
// Super fast, very useful for reducing the load if the same player is queried multiple times (for example a superstar player).
func saveToCachePlayer(ctx context.Context, data string, game string, player string) error {
item := &memcache.Item{
Key: game + "/" + player,
Value: []byte(data),
Expiration: time.Hour * 1,
}
return memcache.Set(ctx, item)
}

// getFromCachePlayer function is used to retrieve data from Memcached server. It returns iCalendar string ready to be sent to the user as a response directly.
// Super fast, very useful for reducing the load if the same player is queried multiple times (for example a superstar player).
func getFromCachePlayer(ctx context.Context, game string, player string) (*memcache.Item, error) {
return memcache.Get(ctx, game+"/"+player)
}
Empty file removed deployment.hcl
Empty file.
29 changes: 25 additions & 4 deletions liquipedia-calendar.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,25 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
return
}

// Set headers for the response
w.Header().Set("Content-Disposition", "attachment; filename=liquipedia.ics")
w.Header().Set("Content-Type", "text/calendar")

// Get query struct
queries := newQueries(querystring)

// Get data from either cache or scrapping. JSON already parsed and filtered HTML.
// Get from cache the game+player calendar if cached. (Superstar player case).
calendar, err := getFromCachePlayer(r.Context(), queries.data[0].game, queries.data[0].players[0])
if err == nil {
_, err = fmt.Fprintf(w, string(calendar.Value))
if err != nil {
logger.Println("Error while printing serialized calendar.")
return
}
return
}

// Get data from either cache (game generic case) or scrapping. JSON already parsed and filtered HTML.
data, err := getData(r.Context(), queries.data[0].game) // TODO: Handle multiple games
if err != nil {
logger.Println(err)
Expand All @@ -72,9 +87,15 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
logger.Println(err)
}

w.Header().Set("Content-Disposition", "attachment; filename=liquipedia.ics")
w.Header().Set("Content-Type", "text/calendar")
_, err = fmt.Fprintf(w, cal.Serialize())
serializedCalendar := cal.Serialize()

// If it is for a single player, save to cache the game+player calendar (superstar player case).
err = saveToCachePlayer(r.Context(), serializedCalendar, queries.data[0].game, queries.data[0].players[0])
if err != nil {
logger.Println(err)
}

_, err = fmt.Fprintf(w, serializedCalendar)
if err != nil {
logger.Println("Error while printing serialized calendar.")
return
Expand Down

0 comments on commit 310424f

Please sign in to comment.