- delete triggers: check_daily_growth, check_existence, check_dominance
- precompute more data in workerUpdateServerData.loadPlayers
This commit is contained in:
parent
22c5a20ee8
commit
674f1fe63c
|
@ -56,41 +56,72 @@ type workerUpdateServerData struct {
|
||||||
server *models.Server
|
server *models.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *workerUpdateServerData) loadPlayers(od map[int]*models.OpponentsDefeated) ([]*models.Player, []*models.PlayerToServer, error) {
|
type loadPlayersResult struct {
|
||||||
|
ids []int
|
||||||
|
players []*models.Player
|
||||||
|
playersToServer []*models.PlayerToServer
|
||||||
|
deletedPlayers []int
|
||||||
|
numberOfPlayers int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *workerUpdateServerData) loadPlayers(od map[int]*models.OpponentsDefeated) (loadPlayersResult, error) {
|
||||||
var ennoblements []*models.Ennoblement
|
var ennoblements []*models.Ennoblement
|
||||||
|
result := loadPlayersResult{}
|
||||||
if err := w.db.
|
if err := w.db.
|
||||||
Model(&ennoblements).
|
Model(&ennoblements).
|
||||||
DistinctOn("new_owner_id").
|
DistinctOn("new_owner_id").
|
||||||
Order("new_owner_id ASC", "ennobled_at ASC").
|
Order("new_owner_id ASC", "ennobled_at ASC").
|
||||||
Select(); err != nil {
|
Select(); err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "workerUpdateServerData.loadPlayers: couldn't load ennoblements")
|
return result, errors.Wrap(err, "workerUpdateServerData.loadPlayers: couldn't load ennoblements")
|
||||||
}
|
}
|
||||||
|
|
||||||
players, err := w.dataloader.LoadPlayers()
|
var err error
|
||||||
|
result.players, err = w.dataloader.LoadPlayers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
result.numberOfPlayers = len(result.players)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
playersToServer := make([]*models.PlayerToServer, len(players))
|
result.playersToServer = make([]*models.PlayerToServer, result.numberOfPlayers)
|
||||||
searchableByNewOwnerID := &ennoblementsSearchableByNewOwnerID{ennoblements: ennoblements}
|
result.ids = make([]int, result.numberOfPlayers)
|
||||||
for index, player := range players {
|
searchableByNewOwnerID := &ennoblementsSearchableByNewOwnerID{ennoblements}
|
||||||
|
for index, player := range result.players {
|
||||||
playerOD, ok := od[player.ID]
|
playerOD, ok := od[player.ID]
|
||||||
if ok {
|
if ok {
|
||||||
player.OpponentsDefeated = *playerOD
|
player.OpponentsDefeated = *playerOD
|
||||||
}
|
}
|
||||||
|
|
||||||
firstEnnoblementIndex := searchByID(searchableByNewOwnerID, player.ID)
|
firstEnnoblementIndex := searchByID(searchableByNewOwnerID, player.ID)
|
||||||
if firstEnnoblementIndex != -1 {
|
if firstEnnoblementIndex >= 0 {
|
||||||
firstEnnoblement := ennoblements[firstEnnoblementIndex]
|
firstEnnoblement := ennoblements[firstEnnoblementIndex]
|
||||||
diffInDays := getDateDifferenceInDays(now, firstEnnoblement.EnnobledAt)
|
diffInDays := getDateDifferenceInDays(now, firstEnnoblement.EnnobledAt)
|
||||||
player.DailyGrowth = calcPlayerDailyGrowth(diffInDays, player.Points)
|
player.DailyGrowth = calcPlayerDailyGrowth(diffInDays, player.Points)
|
||||||
}
|
}
|
||||||
playersToServer[index] = &models.PlayerToServer{
|
|
||||||
|
result.playersToServer[index] = &models.PlayerToServer{
|
||||||
PlayerID: player.ID,
|
PlayerID: player.ID,
|
||||||
ServerKey: w.server.Key,
|
ServerKey: w.server.Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.ids[index] = player.ID
|
||||||
}
|
}
|
||||||
return players, nil, nil
|
|
||||||
|
searchableNewPlayers := &playersSearchableByID{result.players}
|
||||||
|
if err := w.db.
|
||||||
|
Model(&models.Player{}).
|
||||||
|
Column("id").
|
||||||
|
Where("exists = true").
|
||||||
|
ForEach(func(player *models.Player) error {
|
||||||
|
if index := searchByID(searchableNewPlayers, player.ID); index < 0 {
|
||||||
|
result.deletedPlayers = append(result.deletedPlayers, player.ID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return result, errors.Wrap(err, "workerUpdateServerData.loadPlayers: Players that have been deleted couldn't be detected")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *workerUpdateServerData) loadTribes(od map[int]*models.OpponentsDefeated, numberOfVillages int) ([]*models.Tribe, error) {
|
func (w *workerUpdateServerData) loadTribes(od map[int]*models.OpponentsDefeated, numberOfVillages int) ([]*models.Tribe, error) {
|
||||||
|
@ -197,11 +228,10 @@ func (w *workerUpdateServerData) update() error {
|
||||||
}
|
}
|
||||||
numberOfTribes := len(tribes)
|
numberOfTribes := len(tribes)
|
||||||
|
|
||||||
players, playersToServer, err := w.loadPlayers(pod)
|
playersResult, err := w.loadPlayers(pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "workerUpdateServerData.update")
|
return errors.Wrap(err, "workerUpdateServerData.update")
|
||||||
}
|
}
|
||||||
numberOfPlayers := len(players)
|
|
||||||
|
|
||||||
cfg, err := w.dataloader.GetConfig()
|
cfg, err := w.dataloader.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -220,9 +250,9 @@ func (w *workerUpdateServerData) update() error {
|
||||||
|
|
||||||
return w.db.RunInTransaction(context.Background(), func(tx *pg.Tx) error {
|
return w.db.RunInTransaction(context.Background(), func(tx *pg.Tx) error {
|
||||||
if len(tribes) > 0 {
|
if len(tribes) > 0 {
|
||||||
var ids []int
|
ids := make([]int, len(tribes))
|
||||||
for _, tribe := range tribes {
|
for index, tribe := range tribes {
|
||||||
ids = append(ids, tribe.ID)
|
ids[index] = tribe.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := tx.Model(&tribes).
|
if _, err := tx.Model(&tribes).
|
||||||
|
@ -236,6 +266,7 @@ func (w *workerUpdateServerData) update() error {
|
||||||
Set("rank = EXCLUDED.rank").
|
Set("rank = EXCLUDED.rank").
|
||||||
Set("exists = EXCLUDED.exists").
|
Set("exists = EXCLUDED.exists").
|
||||||
Set("dominance = EXCLUDED.dominance").
|
Set("dominance = EXCLUDED.dominance").
|
||||||
|
Set("deleted_at = null").
|
||||||
Apply(appendODSetClauses).
|
Apply(appendODSetClauses).
|
||||||
Insert(); err != nil {
|
Insert(); err != nil {
|
||||||
return errors.Wrap(err, "couldn't insert tribes")
|
return errors.Wrap(err, "couldn't insert tribes")
|
||||||
|
@ -243,16 +274,20 @@ func (w *workerUpdateServerData) update() error {
|
||||||
if _, err := tx.Model(&tribes).
|
if _, err := tx.Model(&tribes).
|
||||||
Where("NOT (tribe.id = ANY (?))", pg.Array(ids)).
|
Where("NOT (tribe.id = ANY (?))", pg.Array(ids)).
|
||||||
Set("exists = false").
|
Set("exists = false").
|
||||||
|
Set("deleted_at = now()").
|
||||||
|
Set("dominance = 0").
|
||||||
Update(); err != nil && err != pg.ErrNoRows {
|
Update(); err != nil && err != pg.ErrNoRows {
|
||||||
return errors.Wrap(err, "couldn't update non-existent tribes")
|
return errors.Wrap(err, "couldn't update non-existent tribes")
|
||||||
}
|
}
|
||||||
|
|
||||||
var tribesHistory []*models.TribeHistory
|
var tribesHistory []*models.TribeHistory
|
||||||
if err := w.db.Model(&tribesHistory).
|
if err := tx.
|
||||||
|
Model(&tribesHistory).
|
||||||
DistinctOn("tribe_id").
|
DistinctOn("tribe_id").
|
||||||
Column("*").
|
Column("tribe_history.*").
|
||||||
Where("tribe_id = ANY (?)", pg.Array(ids)).
|
Where("tribe.exists = true").
|
||||||
Order("tribe_id DESC", "create_date DESC").
|
Order("tribe_id DESC", "create_date DESC").
|
||||||
|
Relation("Tribe._").
|
||||||
Select(); err != nil && err != pg.ErrNoRows {
|
Select(); err != nil && err != pg.ErrNoRows {
|
||||||
return errors.Wrap(err, "couldn't select tribe history records")
|
return errors.Wrap(err, "couldn't select tribe history records")
|
||||||
}
|
}
|
||||||
|
@ -274,12 +309,18 @@ func (w *workerUpdateServerData) update() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(players) > 0 {
|
if len(playersResult.deletedPlayers) > 0 {
|
||||||
var ids []int
|
if _, err := tx.Model(&models.Player{}).
|
||||||
for _, player := range players {
|
Where("player.id = ANY (?)", pg.Array(playersResult.deletedPlayers)).
|
||||||
ids = append(ids, player.ID)
|
Set("exists = false").
|
||||||
|
Set("tribe_id = 0").
|
||||||
|
Update(); err != nil && err != pg.ErrNoRows {
|
||||||
|
return errors.Wrap(err, "couldn't mark players as deleted")
|
||||||
}
|
}
|
||||||
if _, err := tx.Model(&players).
|
}
|
||||||
|
|
||||||
|
if playersResult.numberOfPlayers > 0 {
|
||||||
|
if _, err := tx.Model(&playersResult.players).
|
||||||
OnConflict("(id) DO UPDATE").
|
OnConflict("(id) DO UPDATE").
|
||||||
Set("name = EXCLUDED.name").
|
Set("name = EXCLUDED.name").
|
||||||
Set("total_villages = EXCLUDED.total_villages").
|
Set("total_villages = EXCLUDED.total_villages").
|
||||||
|
@ -288,32 +329,22 @@ func (w *workerUpdateServerData) update() error {
|
||||||
Set("exists = EXCLUDED.exists").
|
Set("exists = EXCLUDED.exists").
|
||||||
Set("tribe_id = EXCLUDED.tribe_id").
|
Set("tribe_id = EXCLUDED.tribe_id").
|
||||||
Set("daily_growth = EXCLUDED.daily_growth").
|
Set("daily_growth = EXCLUDED.daily_growth").
|
||||||
|
Set("deleted_at = null").
|
||||||
Apply(appendODSetClauses).
|
Apply(appendODSetClauses).
|
||||||
Insert(); err != nil {
|
Insert(); err != nil {
|
||||||
return errors.Wrap(err, "couldn't insert players")
|
return errors.Wrap(err, "couldn't insert players")
|
||||||
}
|
}
|
||||||
if _, err := tx.Model(&models.Player{}).
|
|
||||||
Where("NOT (player.id = ANY (?))", pg.Array(ids)).
|
|
||||||
Set("exists = false").
|
|
||||||
Set("tribe_id = 0").
|
|
||||||
Update(); err != nil && err != pg.ErrNoRows {
|
|
||||||
return errors.Wrap(err, "couldn't update non-existent players")
|
|
||||||
}
|
|
||||||
if len(playersToServer) > 0 {
|
|
||||||
if _, err := tx.Model(&playersToServer).OnConflict("DO NOTHING").Insert(); err != nil {
|
|
||||||
return errors.Wrap(err, "couldn't associate players with the server")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var playerHistory []*models.PlayerHistory
|
var playerHistory []*models.PlayerHistory
|
||||||
if err := w.db.Model(&playerHistory).
|
if err := tx.Model(&playerHistory).
|
||||||
DistinctOn("player_id").
|
DistinctOn("player_id").
|
||||||
Column("*").
|
Column("player_history.*").
|
||||||
Where("player_id = ANY (?)", pg.Array(ids)).
|
Where("player.exists = true").
|
||||||
|
Relation("Player._").
|
||||||
Order("player_id DESC", "create_date DESC").Select(); err != nil && err != pg.ErrNoRows {
|
Order("player_id DESC", "create_date DESC").Select(); err != nil && err != pg.ErrNoRows {
|
||||||
return errors.Wrap(err, "couldn't select player history records")
|
return errors.Wrap(err, "couldn't select player history records")
|
||||||
}
|
}
|
||||||
todaysPlayerStats := w.calculateDailyPlayerStats(players, playerHistory)
|
todaysPlayerStats := w.calculateDailyPlayerStats(playersResult.players, playerHistory)
|
||||||
if len(todaysPlayerStats) > 0 {
|
if len(todaysPlayerStats) > 0 {
|
||||||
if _, err := tx.
|
if _, err := tx.
|
||||||
Model(&todaysPlayerStats).
|
Model(&todaysPlayerStats).
|
||||||
|
@ -328,8 +359,14 @@ func (w *workerUpdateServerData) update() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(playersResult.playersToServer) > 0 {
|
||||||
|
if _, err := tx.Model(&playersResult.playersToServer).OnConflict("DO NOTHING").Insert(); err != nil {
|
||||||
|
return errors.Wrap(err, "couldn't associate players with the server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(villages) > 0 {
|
if len(villages) > 0 {
|
||||||
if _, err := w.db.Model(&villages).
|
if _, err := tx.Model(&villages).
|
||||||
OnConflict("(id) DO UPDATE").
|
OnConflict("(id) DO UPDATE").
|
||||||
Set("name = EXCLUDED.name").
|
Set("name = EXCLUDED.name").
|
||||||
Set("points = EXCLUDED.points").
|
Set("points = EXCLUDED.points").
|
||||||
|
@ -347,7 +384,7 @@ func (w *workerUpdateServerData) update() error {
|
||||||
Set("unit_config = ?", unitCfg).
|
Set("unit_config = ?", unitCfg).
|
||||||
Set("building_config = ?", buildingCfg).
|
Set("building_config = ?", buildingCfg).
|
||||||
Set("config = ?", cfg).
|
Set("config = ?", cfg).
|
||||||
Set("number_of_players = ?", numberOfPlayers).
|
Set("number_of_players = ?", playersResult.numberOfPlayers).
|
||||||
Set("number_of_tribes = ?", numberOfTribes).
|
Set("number_of_tribes = ?", numberOfTribes).
|
||||||
Set("number_of_villages = ?", numberOfVillages).
|
Set("number_of_villages = ?", numberOfVillages).
|
||||||
Returning("*").
|
Returning("*").
|
||||||
|
|
|
@ -59,48 +59,6 @@ const (
|
||||||
`
|
`
|
||||||
|
|
||||||
pgFunctions = `
|
pgFunctions = `
|
||||||
CREATE OR REPLACE FUNCTION check_daily_growth()
|
|
||||||
RETURNS trigger AS
|
|
||||||
$BODY$
|
|
||||||
BEGIN
|
|
||||||
IF NEW.exists = false THEN
|
|
||||||
NEW.daily_growth = 0;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$BODY$
|
|
||||||
LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION check_existence()
|
|
||||||
RETURNS trigger AS
|
|
||||||
$BODY$
|
|
||||||
BEGIN
|
|
||||||
IF NEW.exists = false AND OLD.exists = true THEN
|
|
||||||
NEW.deleted_at = now();
|
|
||||||
END IF;
|
|
||||||
IF NEW.exists = true THEN
|
|
||||||
NEW.deleted_at = null;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$BODY$
|
|
||||||
LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION check_dominance()
|
|
||||||
RETURNS trigger AS
|
|
||||||
$BODY$
|
|
||||||
BEGIN
|
|
||||||
IF NEW.exists = false THEN
|
|
||||||
NEW.dominance = 0;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$BODY$
|
|
||||||
LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION update_most_points_most_villages_best_rank_last_activity()
|
CREATE OR REPLACE FUNCTION update_most_points_most_villages_best_rank_last_activity()
|
||||||
RETURNS trigger AS
|
RETURNS trigger AS
|
||||||
$BODY$
|
$BODY$
|
||||||
|
@ -230,29 +188,12 @@ const (
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
EXECUTE PROCEDURE ?0.log_player_name_change();
|
EXECUTE PROCEDURE ?0.log_player_name_change();
|
||||||
|
|
||||||
CREATE TRIGGER ?0_check_daily_growth
|
DROP TRIGGER IF EXISTS ?0_check_daily_growth ON ?0.players;
|
||||||
BEFORE UPDATE
|
|
||||||
ON ?0.players
|
|
||||||
FOR EACH ROW
|
|
||||||
EXECUTE PROCEDURE check_daily_growth();
|
|
||||||
|
|
||||||
CREATE TRIGGER ?0_check_player_existence
|
DROP TRIGGER IF EXISTS ?0_check_player_existence ON ?0.players;
|
||||||
BEFORE UPDATE
|
DROP TRIGGER IF EXISTS ?0_check_tribe_existence ON ?0.tribes;
|
||||||
ON ?0.players
|
|
||||||
FOR EACH ROW
|
|
||||||
EXECUTE PROCEDURE check_existence();
|
|
||||||
|
|
||||||
CREATE TRIGGER ?0_check_tribe_existence
|
DROP TRIGGER IF EXISTS ?0_check_dominance ON ?0.tribes;
|
||||||
BEFORE UPDATE
|
|
||||||
ON ?0.tribes
|
|
||||||
FOR EACH ROW
|
|
||||||
EXECUTE PROCEDURE check_existence();
|
|
||||||
|
|
||||||
CREATE TRIGGER ?0_check_dominance
|
|
||||||
BEFORE UPDATE
|
|
||||||
ON ?0.tribes
|
|
||||||
FOR EACH ROW
|
|
||||||
EXECUTE PROCEDURE check_dominance();
|
|
||||||
|
|
||||||
CREATE TRIGGER ?0_update_ennoblement_old_and_new_owner_tribe_id
|
CREATE TRIGGER ?0_update_ennoblement_old_and_new_owner_tribe_id
|
||||||
BEFORE INSERT
|
BEFORE INSERT
|
||||||
|
|
Reference in New Issue
Block a user