limiting the crons because of the request limit

This commit is contained in:
Samuel Tariku 2025-04-29 10:35:39 +03:00
parent b5166fa53d
commit 9e4b0d9942
8 changed files with 185 additions and 47 deletions

View File

@ -19,8 +19,8 @@ CREATE TABLE IF NOT EXISTS referral_settings (
CREATE TABLE IF NOT EXISTS referrals (
id BIGSERIAL PRIMARY KEY,
referral_code VARCHAR(10) NOT NULL UNIQUE,
-- referrer_id VARCHAR(255) NOT NULL,
-- referred_id VARCHAR(255) UNIQUE,
referrer_id VARCHAR(255) NOT NULL,
referred_id VARCHAR(255) UNIQUE,
status ReferralStatus NOT NULL DEFAULT 'PENDING',
reward_amount DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
cashback_amount DECIMAL(15, 2) NOT NULL DEFAULT 0.00,
@ -33,7 +33,7 @@ CREATE TABLE IF NOT EXISTS referrals (
CONSTRAINT cashback_amount_positive CHECK (cashback_amount >= 0)
);
CREATE INDEX idx_referrals_referral_code ON referrals (referral_code);
-- CREATE INDEX idx_referrals_referrer_id ON referrals (referrer_id);
CREATE INDEX idx_referrals_referrer_id ON referrals (referrer_id);
CREATE INDEX idx_referrals_status ON referrals (status);
ALTER TABLE users
ADD COLUMN IF NOT EXISTS referral_code VARCHAR(10) UNIQUE,

View File

@ -140,6 +140,28 @@ FROM events
WHERE is_live = false
AND status = 'upcoming'
ORDER BY start_time ASC;
-- name: GetExpiredUpcomingEvents :many
SELECT id,
sport_id,
match_name,
home_team,
away_team,
home_team_id,
away_team_id,
home_kit_image,
away_kit_image,
league_id,
league_name,
league_cc,
start_time,
is_live,
status,
fetched_at
FROM events
WHERE is_live = false
AND status = 'upcoming'
AND start_time < now()
ORDER BY start_time ASC;
-- name: GetTotalEvents :one
SELECT COUNT(*)
FROM events
@ -205,7 +227,6 @@ WHERE id = $1
AND is_live = false
AND status = 'upcoming'
LIMIT 1;
-- name: UpdateMatchResult :exec
UPDATE events
SET score = $1,

View File

@ -90,6 +90,86 @@ func (q *Queries) GetAllUpcomingEvents(ctx context.Context) ([]GetAllUpcomingEve
return items, nil
}
const GetExpiredUpcomingEvents = `-- name: GetExpiredUpcomingEvents :many
SELECT id,
sport_id,
match_name,
home_team,
away_team,
home_team_id,
away_team_id,
home_kit_image,
away_kit_image,
league_id,
league_name,
league_cc,
start_time,
is_live,
status,
fetched_at
FROM events
WHERE is_live = false
AND status = 'upcoming'
AND start_time < now()
ORDER BY start_time ASC
`
type GetExpiredUpcomingEventsRow struct {
ID string `json:"id"`
SportID pgtype.Text `json:"sport_id"`
MatchName pgtype.Text `json:"match_name"`
HomeTeam pgtype.Text `json:"home_team"`
AwayTeam pgtype.Text `json:"away_team"`
HomeTeamID pgtype.Text `json:"home_team_id"`
AwayTeamID pgtype.Text `json:"away_team_id"`
HomeKitImage pgtype.Text `json:"home_kit_image"`
AwayKitImage pgtype.Text `json:"away_kit_image"`
LeagueID pgtype.Text `json:"league_id"`
LeagueName pgtype.Text `json:"league_name"`
LeagueCc pgtype.Text `json:"league_cc"`
StartTime pgtype.Timestamp `json:"start_time"`
IsLive pgtype.Bool `json:"is_live"`
Status pgtype.Text `json:"status"`
FetchedAt pgtype.Timestamp `json:"fetched_at"`
}
func (q *Queries) GetExpiredUpcomingEvents(ctx context.Context) ([]GetExpiredUpcomingEventsRow, error) {
rows, err := q.db.Query(ctx, GetExpiredUpcomingEvents)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetExpiredUpcomingEventsRow
for rows.Next() {
var i GetExpiredUpcomingEventsRow
if err := rows.Scan(
&i.ID,
&i.SportID,
&i.MatchName,
&i.HomeTeam,
&i.AwayTeam,
&i.HomeTeamID,
&i.AwayTeamID,
&i.HomeKitImage,
&i.AwayKitImage,
&i.LeagueID,
&i.LeagueName,
&i.LeagueCc,
&i.StartTime,
&i.IsLive,
&i.Status,
&i.FetchedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetPaginatedUpcomingEvents = `-- name: GetPaginatedUpcomingEvents :many
SELECT id,
sport_id,

View File

@ -89,6 +89,34 @@ func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEven
}
return upcomingEvents, nil
}
func (s *Store) GetExpiredUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
events, err := s.queries.GetExpiredUpcomingEvents(ctx)
if err != nil {
return nil, err
}
upcomingEvents := make([]domain.UpcomingEvent, len(events))
for i, e := range events {
upcomingEvents[i] = domain.UpcomingEvent{
ID: e.ID,
SportID: e.SportID.String,
MatchName: e.MatchName.String,
HomeTeam: e.HomeTeam.String,
AwayTeam: e.AwayTeam.String,
HomeTeamID: e.HomeTeamID.String,
AwayTeamID: e.AwayTeamID.String,
HomeKitImage: e.HomeKitImage.String,
AwayKitImage: e.AwayKitImage.String,
LeagueID: e.LeagueID.String,
LeagueName: e.LeagueName.String,
LeagueCC: e.LeagueCc.String,
StartTime: e.StartTime.Time.UTC(),
}
}
return upcomingEvents, nil
}
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
LeagueID: pgtype.Text{

View File

@ -10,6 +10,7 @@ type Service interface {
FetchLiveEvents(ctx context.Context) error
FetchUpcomingEvents(ctx context.Context) error
GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
GetExpiredUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error)
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
// GetAndStoreMatchResult(ctx context.Context, eventID string) error

View File

@ -101,7 +101,7 @@ func (s *service) FetchUpcomingEvents(ctx context.Context) error {
sportIDs := []int{1}
var totalPages int = 1
var page int = 0
var limit int = 5
var limit int = 100
var count int = 0
for _, sportID := range sportIDs {
for page != totalPages {
@ -199,6 +199,10 @@ func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEv
return s.store.GetAllUpcomingEvents(ctx)
}
func (s *service) GetExpiredUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error) {
return s.store.GetExpiredUpcomingEvents(ctx)
}
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
return s.store.GetPaginatedUpcomingEvents(ctx, limit, offset, leagueID, sportID)
}

View File

@ -1,6 +1,8 @@
package httpserver
import (
// "context"
"context"
"log"
@ -34,34 +36,38 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
// }
// },
// },
{
spec: "0 */15 * * * *", // Every 15 minutes
task: func() {
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
log.Printf("FetchNonLiveOdds error: %v", err)
}
},
},
{
spec: "0 */15 * * * *",
task: func() {
log.Println("Fetching results for upcoming events...")
// {
// // spec: "0 */15 * * * *", // Every 15 minutes
// spec: "0 0 * * * *", // TODO: Every hour because of the 3600 requests per hour limit
// task: func() {
upcomingEvents, err := eventService.GetAllUpcomingEvents(context.Background())
if err != nil {
log.Printf("Failed to fetch upcoming events: %v", err)
return
}
// if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
// log.Printf("FetchNonLiveOdds error: %v", err)
// }
// time.Sleep(2 * time.Second) //This will restrict the fetching to 1800 requests per hour
for _, event := range upcomingEvents {
if err := resultService.FetchAndStoreResult(context.Background(), event.ID); err != nil {
log.Printf(" Failed to fetch/store result for event %s: %v", event.ID, err)
} else {
log.Printf(" Successfully stored result for event %s", event.ID)
}
}
},
},
// },
// },
// {
// spec: "0 */15 * * * *",
// task: func() {
// log.Println("Fetching results for upcoming events...")
// upcomingEvents, err := eventService.GetAllUpcomingEvents(context.Background())
// if err != nil {
// log.Printf("Failed to fetch upcoming events: %v", err)
// return
// }
// for _, event := range upcomingEvents {
// if err := resultService.FetchAndStoreResult(context.Background(), event.ID); err != nil {
// log.Printf(" Failed to fetch/store result for event %s: %v", event.ID, err)
// } else {
// log.Printf(" Successfully stored result for event %s", event.ID)
// }
// }
// },
// },
}
for _, job := range schedule {

View File

@ -1,7 +1,6 @@
package handlers
import (
"fmt"
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
@ -103,7 +102,6 @@ func (h *Handler) GetRawOddsByMarketID(c *fiber.Ctx) error {
// @Failure 500 {object} response.APIResponse
// @Router /prematch/events [get]
func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
page := c.QueryInt("page", 1)
pageSize := c.QueryInt("page_size", 10)
leagueIDQuery := c.Query("league_id")
@ -120,9 +118,9 @@ func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error {
events, total, err := h.eventSvc.GetPaginatedUpcomingEvents(c.Context(), int32(pageSize), int32(page)-1, leagueID, sportID)
fmt.Printf("League ID: %v", leagueID)
// fmt.Printf("League ID: %v", leagueID)
if err != nil {
h.logger.Error("getting error", err)
h.logger.Error("getting error", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil)
}