Skip to content

Commit

Permalink
Redlocked donations
Browse files Browse the repository at this point in the history
  • Loading branch information
heynemann committed Nov 18, 2016
1 parent 38e4660 commit ca2f94b
Show file tree
Hide file tree
Showing 18 changed files with 418 additions and 108 deletions.
15 changes: 3 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ run: services
run-basic: services
@go run main.go start --fast -d -c ./config/basicAuth.yaml

test: update-version mongo-local-shutdown test-services test-migrate test-run test-coverage-func
test: update-version test-services test-migrate test-run test-coverage-func

test-run:
@ginkgo --cover -r .
Expand Down Expand Up @@ -97,14 +97,14 @@ schema-update:
@go generate ./models/*.go
@go generate ./api/payload.go

run-test-donations: docker-services-shutdown mongo-local perf-migrate run-test-ci
run-test-donations: docker-services-shutdown perf-migrate run-test-ci

run-test-ci: build kill-test-donations
@rm -rf /tmp/donations-bench.log
@./bin/donations start -p 8080 -q --fast -c ./config/perf.yaml 2>&1 > /tmp/donations-bench.log &
@sleep 2

run-test-donations-fg: build kill-test-donations mongo-local
run-test-donations-fg: build kill-test-donations
@./bin/donations start -p 8080 -q --fast -c ./config/perf.yaml

kill-test-donations:
Expand Down Expand Up @@ -140,15 +140,6 @@ docker-services-ci-shutdown:
@docker-compose -p donations-ci -f ./docker-compose-ci.yml stop
@docker-compose -p donations-ci -f ./docker-compose-ci.yml rm -f

mongo-local: mongo-local-shutdown
@rm -rf /tmp/donations-db
@mkdir -p /tmp/donations-db
@mongod --port 9999 --bind_ip 0.0.0.0 --fork --logpath /tmp/donations-db/mongo.log --dbpath /tmp/donations-db/

mongo-local-shutdown:
@-mongo --port 9999 --eval "db.shutdownServer()" admin
@sleep 2

rtfd: update-version
@rm -rf docs/_build
@sphinx-build -b html -d ./docs/_build/doctrees ./docs/ docs/_build/html
Expand Down
62 changes: 57 additions & 5 deletions api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import (
"fmt"
"os"
"strings"
"time"

mgo "gopkg.in/mgo.v2"
redsync "gopkg.in/redsync.v1"

"github.com/garyburd/redigo/redis"
raven "github.com/getsentry/raven-go"
"github.com/labstack/echo"
"github.com/labstack/echo/engine"
Expand All @@ -15,8 +18,8 @@ import (
"github.com/labstack/echo/middleware"
newrelic "github.com/newrelic/go-agent"
"github.com/spf13/viper"
"github.com/topfreegames/donations/log"
"github.com/uber-go/zap"
fh "github.com/valyala/fasthttp"
)

// App is a struct that represents a Donations Api APP
Expand All @@ -33,7 +36,7 @@ type App struct {
Logger zap.Logger
Background bool
Fast bool
Client *fh.Client
Redsync *redsync.Redsync
NewRelic newrelic.Application
}

Expand Down Expand Up @@ -73,8 +76,6 @@ func (app *App) Configure() error {
return err
}

app.Client = &fh.Client{}

return nil
}

Expand Down Expand Up @@ -103,7 +104,7 @@ func (app *App) configureNewRelic() error {

config := newrelic.NewConfig(appName, newRelicKey)
if newRelicKey == "" {
l.Info("New Relic is not enabled..")
log.I(l, "New Relic is not enabled..")
config.Enabled = false
}
nr, err := newrelic.NewApplication(config)
Expand Down Expand Up @@ -168,6 +169,56 @@ func (app *App) OnErrorHandler(err error, stack []byte) {
raven.CaptureError(e, tags)
}

func (app *App) configureRedsync() error {
redisURL := app.Config.GetString("redis.url")
maxIdle := app.Config.GetInt("redis.maxIdle")
timeoutSeconds := app.Config.GetInt("redis.idleTimeoutSeconds")
l := app.Logger.With(
zap.String("operation", "configureRedsync"),
zap.String("redis.url", app.Config.GetString("redis.url")),
)

app.Redsync = redsync.New([]redsync.Pool{
&redis.Pool{
MaxIdle: maxIdle,
IdleTimeout: time.Duration(timeoutSeconds) * time.Second,
Dial: func() (redis.Conn, error) {
log.I(l, "Connecting to redis...")
conn, err := redis.DialURL(redisURL)
if err != nil {
log.E(l, "Failed to connect to redis.", func(cm log.CM) {
cm.Write(zap.Error(err))
})
return nil, err
}
return conn, nil
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
log.I(l, "Pinging redis...")
_, err := c.Do("PING")
if err != nil {
log.E(l, "Failed to ping redis.", func(cm log.CM) {
cm.Write(zap.Error(err))
})
return err
}
return nil
},
},
})

return nil
}

func (app *App) GetMutex(name string, retries, timeout int) *redsync.Mutex {
options := []redsync.Option{
redsync.SetTries(retries),
redsync.SetExpiry(time.Duration(timeout) * time.Second),
}
mutex := app.Redsync.NewMutex(name, options...)
return mutex
}

func (app *App) configureMongoDB() error {
l := app.Logger.With(
zap.String("operation", "configureMongoDB"),
Expand Down Expand Up @@ -264,6 +315,7 @@ func (app *App) configureApplication() error {
a.Post("/games/:gameID/donation-requests/:donationRequestID", CreateDonationHandler(app))

app.configureMongoDB()
app.configureRedsync()

l.Debug("Application configured successfully.")

Expand Down
7 changes: 5 additions & 2 deletions api/donation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"fmt"
"net/http"

"github.com/topfreegames/donations/log"
Expand Down Expand Up @@ -54,7 +55,7 @@ func CreateDonationRequestHandler(app *App) func(c echo.Context) error {

err = WithSegment("DonationRequest", c, func() error {
donationRequest = models.NewDonationRequest(
game,
game.ID,
payload.Item,
payload.Player,
payload.Clan,
Expand Down Expand Up @@ -132,7 +133,9 @@ func CreateDonationHandler(app *App) func(c echo.Context) error {
return err
}

err := donationRequest.Donate(app.MongoDb, payload.Player, payload.Amount, app.Logger)
mutex := app.GetMutex("Donate", 32, 8) // Number of retries to get lock and Lock expiration
err := donationRequest.Donate(payload.Player, payload.Amount, app.MongoDb, mutex, app.Logger)
fmt.Println(err)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion api/donation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ var _ = Describe("Game Handler", func() {
Expect(dr.Player).To(Equal(playerID))
Expect(dr.Item).To(Equal(itemID))
Expect(dr.Clan).To(Equal(clanID))
Expect(dr.Game.ID).To(Equal(game.ID))
Expect(dr.GameID).To(Equal(game.ID))
})
})
})
Expand Down
16 changes: 0 additions & 16 deletions config/ci.yaml

This file was deleted.

5 changes: 5 additions & 0 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ mongo:
port: 27017
db: donations

redis:
url: redis://localhost:6379/0
maxIdle: 3
idleTimeoutSeconds: 240

sentry:
url: ""

Expand Down
5 changes: 5 additions & 0 deletions config/local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ mongo:
port: 9999
db: donations

redis:
url: redis://localhost:6379/0
maxIdle: 3
idleTimeoutSeconds: 240

sentry:
url: ""

Expand Down
7 changes: 6 additions & 1 deletion config/perf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ healthcheck:
mongo:
host: localhost
port: 9999
db: ur-perf
db: donations-perf

redis:
url: redis://localhost:6379/1
maxIdle: 3
idleTimeoutSeconds: 240

sentry:
url: ""
Expand Down
5 changes: 5 additions & 0 deletions config/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ mongo:
port: 9999
db: donations-test

redis:
url: redis://localhost:9998/1
maxIdle: 3
idleTimeoutSeconds: 240

sentry:
url: ""

Expand Down
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
version: '2'

services:
redis:
image: redis:3.2
command: redis-server
ports:
- "9998:6379"
mongo:
image: mongo:3.3
ports:
Expand Down
16 changes: 14 additions & 2 deletions errors/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ParameterIsRequiredError struct {

//Error string
func (err ParameterIsRequiredError) Error() string {
return fmt.Sprintf("%s is required to create a new %s", err.Parameter, err.Model)
return fmt.Sprintf("%s is required to create a new %s.", err.Parameter, err.Model)
}

//ItemNotFoundInGameError happens when a donation happens for an item that's not in the game
Expand All @@ -40,5 +40,17 @@ type ItemNotFoundInGameError struct {

//Error string
func (err ItemNotFoundInGameError) Error() string {
return fmt.Sprintf("Item %s was not found in game %s", err.ItemKey, err.GameID)
return fmt.Sprintf("Item %s was not found in game %s.", err.ItemKey, err.GameID)
}

//LimitOfCardsInDonationRequestReachedError happens when a donation happens for an item that's not in the game
type LimitOfCardsInDonationRequestReachedError struct {
GameID string
DonationRequestID string
ItemKey string
}

//Error string
func (err LimitOfCardsInDonationRequestReachedError) Error() string {
return "This donation request is already finished."
}
13 changes: 10 additions & 3 deletions glide.lock

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

6 changes: 6 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ import:
- package: github.com/getsentry/raven-go
- package: github.com/newrelic/go-agent
version: ^1.4.0
- package: gopkg.in/redsync.v1
version: ^1.0.1
- package: github.com/garyburd/redigo
version: ^1.0.0
subpackages:
- redis
Loading

0 comments on commit ca2f94b

Please sign in to comment.