Skip to content

Commit

Permalink
Update worker to use new leaderboard (#65)
Browse files Browse the repository at this point in the history
Co-authored-by: Arthur Nogueira Gonçalves <arthur.nogueira@wildlifestudios.com>
Co-authored-by: Matheus Nogueira <matheus.nogueira2008@gmail.com>
  • Loading branch information
3 people committed May 19, 2021
1 parent 325d736 commit 8089dc5
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 177 deletions.
6 changes: 3 additions & 3 deletions bench/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import (

. "github.com/onsi/gomega"
"github.com/topfreegames/extensions/redis"
"github.com/topfreegames/podium/config"
"github.com/topfreegames/podium/leaderboard"
"github.com/topfreegames/podium/testing"
)

func getRedis() *redis.Client {
config, err := testing.GetDefaultConfig("../config/default.yaml")
config, err := config.GetDefaultConfig("../config/default.yaml")
Expect(err).NotTo(HaveOccurred())

redisHost := config.GetString("redis.host")
Expand Down Expand Up @@ -107,7 +107,7 @@ func validateResp(statusCode int, body string, err error) {
}

func generateNMembers(amount int) string {
config, err := testing.GetDefaultConfig("../config/default.yaml")
config, err := config.GetDefaultConfig("../config/default.yaml")
Expect(err).NotTo(HaveOccurred())

client := leaderboard.NewClient(
Expand Down
4 changes: 2 additions & 2 deletions bench/seed/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (

"github.com/gosuri/uiprogress"
"github.com/gosuri/uiprogress/util/strutil"
"github.com/topfreegames/podium/config"
"github.com/topfreegames/podium/leaderboard/database/redis"
"github.com/topfreegames/podium/testing"
)

var currentStage int
Expand All @@ -32,7 +32,7 @@ func main() {

totalOps := *leaderboardCount * *membersPerLeaderboard

config, err := testing.GetDefaultConfig("../../default.yaml")
config, err := config.GetDefaultConfig("../../default.yaml")
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion testing/config.go → config/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package testing
package config

import (
"strings"
Expand Down
1 change: 1 addition & 0 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ healthcheck:
workingText: WORKING

redis:
clusterEnabled: false
addrs: "localhost:5000"
host: localhost
port: 6379
Expand Down
16 changes: 16 additions & 0 deletions leaderboard/database/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,19 @@ func NewTTLNotFoundError(leaderboard string) *TTLNotFoundError {
func (tnfe *TTLNotFoundError) Error() string {
return fmt.Sprintf("ttl to leaderboard %s not found", tnfe.leaderboard)
}

// LeaderboardWithoutMemberToExpireError is an error throw when leaderboard doesn't have member to expire
type LeaderboardWithoutMemberToExpireError struct {
leaderboard string
}

// NewLeaderboardWithoutMemberToExpireError create a new KeyNotFoundError
func NewLeaderboardWithoutMemberToExpireError(leaderboard string) *LeaderboardWithoutMemberToExpireError {
return &LeaderboardWithoutMemberToExpireError{
leaderboard: leaderboard,
}
}

func (lwmtee *LeaderboardWithoutMemberToExpireError) Error() string {
return fmt.Sprintf("leaderboard %s without member to expire", lwmtee.leaderboard)
}
14 changes: 14 additions & 0 deletions leaderboard/database/expiration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package database

import (
"context"
"time"
)

// Expiration interface standardize expiration database calls
type Expiration interface {
GetExpirationLeaderboards(ctx context.Context) ([]string, error)
GetMembersToExpire(ctx context.Context, leaderboard string, amount int, maxTime time.Time) ([]string, error)
RemoveLeaderboardFromExpireList(ctx context.Context, leaderboard string) error
ExpireMembers(ctx context.Context, leaderboard string, members []string) error
}
94 changes: 94 additions & 0 deletions leaderboard/database/expiration_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions leaderboard/database/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/topfreegames/podium/leaderboard/database/redis"
)

// Redis is a type that implements database interface with redis client
// Redis is a type that implements Database interface with redis client
type Redis struct {
redis.Redis
}
Expand All @@ -29,7 +29,7 @@ type RedisOptions struct {
}

// NewRedisDatabase create a database based on redis
func NewRedisDatabase(options RedisOptions) Database {
func NewRedisDatabase(options RedisOptions) *Redis {
if options.ClusterEnabled {
return &Redis{redis.NewClusterClient(redis.ClusterOptions{
Addrs: options.Addrs,
Expand Down
13 changes: 11 additions & 2 deletions leaderboard/database/redis/cluster_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func (cc *clusterClient) SMembers(ctx context.Context, key string) ([]string, er
}

// SRem call redis SREM function
func (cc *clusterClient) SRem(ctx context.Context, key, member string) error {
err := cc.ClusterClient.SRem(ctx, key, member).Err()
func (cc *clusterClient) SRem(ctx context.Context, key string, members ...string) error {
err := cc.ClusterClient.SRem(ctx, key, members).Err()
if err != nil {
return NewGeneralError(err.Error())
}
Expand Down Expand Up @@ -178,6 +178,15 @@ func (cc *clusterClient) ZRange(ctx context.Context, key string, start, stop int
return members, nil
}

// ZRangeByScore call redis ZREVRANGEBYSCORE command
func (cc *clusterClient) ZRangeByScore(ctx context.Context, key string, min, max string, offset, count int64) ([]string, error) {
result, err := cc.ClusterClient.ZRangeByScore(ctx, key, &goredis.ZRangeBy{Min: min, Max: max, Offset: offset, Count: count}).Result()
if err != nil {
return nil, NewGeneralError(err.Error())
}
return result, nil
}

// ZRank call redis ZRANK function
func (cc *clusterClient) ZRank(ctx context.Context, key, member string) (int64, error) {
result, err := cc.ClusterClient.ZRank(ctx, key, member).Result()
Expand Down
22 changes: 21 additions & 1 deletion leaderboard/database/redis/cluster_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ var _ = Describe("Cluster Client", func() {
err := goRedis.SAdd(context.Background(), testKey, member).Err()
Expect(err).NotTo(HaveOccurred())

err = clusterClient.SRem(context.Background(), testKey, member)
err = goRedis.SAdd(context.Background(), testKey, "member2").Err()
Expect(err).NotTo(HaveOccurred())

err = clusterClient.SRem(context.Background(), testKey, member, "member2")
Expect(err).NotTo(HaveOccurred())

isMember, err := goRedis.SIsMember(context.Background(), testKey, member).Result()
Expand Down Expand Up @@ -264,6 +267,23 @@ var _ = Describe("Cluster Client", func() {
})
})

Describe("ZRangeByScore", func() {
It("Should return members closest members ordered by score", func() {
member2 := "member2"

score := 1.0
score2 := 2.0

err := goRedis.ZAdd(context.Background(), testKey, &goredis.Z{Member: member, Score: score}, &goredis.Z{Member: member2, Score: score2}).Err()
Expect(err).NotTo(HaveOccurred())

members, err := clusterClient.ZRangeByScore(context.Background(), testKey, "-inf", "1", 0, 1)
Expect(err).NotTo(HaveOccurred())

Expect(members[0]).To(Equal(member))
})
})

Describe("ZRank", func() {
It("Should return member rank and nil if no error ocurr", func() {
score := 1.0
Expand Down
28 changes: 24 additions & 4 deletions leaderboard/database/redis/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion leaderboard/database/redis/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ type Redis interface {
Ping(ctx context.Context) (string, error)
SAdd(ctx context.Context, key, member string) error
SMembers(ctx context.Context, key string) ([]string, error)
SRem(ctx context.Context, key, member string) error
SRem(ctx context.Context, key string, members ...string) error
TTL(ctx context.Context, key string) (time.Duration, error)
ZAdd(ctx context.Context, key string, members ...*Member) error
ZCard(ctx context.Context, key string) (int64, error)
ZIncrBy(ctx context.Context, key, member string, increment float64) error
ZRange(ctx context.Context, key string, start, stop int64) ([]*Member, error)
ZRangeByScore(ctx context.Context, key string, min, max string, offset, count int64) ([]string, error)
ZRank(ctx context.Context, key, member string) (int64, error)
ZRem(ctx context.Context, key string, members ...string) error
ZRevRange(ctx context.Context, key string, start, stop int64) ([]*Member, error)
Expand Down
13 changes: 11 additions & 2 deletions leaderboard/database/redis/standalone_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ func (c *standaloneClient) SMembers(ctx context.Context, key string) ([]string,
}

// SRem call redis SREM function
func (c *standaloneClient) SRem(ctx context.Context, key, member string) error {
err := c.Client.SRem(ctx, key, member).Err()
func (c *standaloneClient) SRem(ctx context.Context, key string, members ...string) error {
err := c.Client.SRem(ctx, key, members).Err()
if err != nil {
return NewGeneralError(err.Error())
}
Expand Down Expand Up @@ -180,6 +180,15 @@ func (c *standaloneClient) ZRange(ctx context.Context, key string, start, stop i
return members, nil
}

// ZRangeByScore call redis ZRANGEBYSCORE command
func (c *standaloneClient) ZRangeByScore(ctx context.Context, key string, min, max string, offset, count int64) ([]string, error) {
result, err := c.Client.ZRangeByScore(ctx, key, &goredis.ZRangeBy{Min: min, Max: max, Offset: offset, Count: count}).Result()
if err != nil {
return nil, NewGeneralError(err.Error())
}
return result, nil
}

// ZRank call redis ZRANK function
func (c *standaloneClient) ZRank(ctx context.Context, key, member string) (int64, error) {
result, err := c.Client.ZRank(ctx, key, member).Result()
Expand Down
24 changes: 22 additions & 2 deletions leaderboard/database/redis/standalone_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,14 @@ var _ = Describe("Standalone Client", func() {
})

Describe("SRem", func() {
It("Should return nil if member is removed from set", func() {
It("Should return nil if members is removed from set", func() {
err := goRedis.SAdd(context.Background(), testKey, member).Err()
Expect(err).NotTo(HaveOccurred())

err = standaloneClient.SRem(context.Background(), testKey, member)
err = goRedis.SAdd(context.Background(), testKey, "member2").Err()
Expect(err).NotTo(HaveOccurred())

err = standaloneClient.SRem(context.Background(), testKey, member, "member2")
Expect(err).NotTo(HaveOccurred())

isMember, err := goRedis.SIsMember(context.Background(), testKey, member).Result()
Expand Down Expand Up @@ -267,6 +270,23 @@ var _ = Describe("Standalone Client", func() {
})
})

Describe("ZRangeByScore", func() {
It("Should return members closest members ordered by score", func() {
member2 := "member2"

score := 1.0
score2 := 2.0

err := goRedis.ZAdd(context.Background(), testKey, &goredis.Z{Member: member, Score: score}, &goredis.Z{Member: member2, Score: score2}).Err()
Expect(err).NotTo(HaveOccurred())

members, err := standaloneClient.ZRangeByScore(context.Background(), testKey, "-inf", "1", 0, 1)
Expect(err).NotTo(HaveOccurred())

Expect(members[0]).To(Equal(member))
})
})

Describe("ZRank", func() {
It("Should return member rank and nil if no error ocurr", func() {
score := 1.0
Expand Down
Loading

0 comments on commit 8089dc5

Please sign in to comment.