Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/ilyakaznacheev/cleanenv v1.5.0
github.com/jmoiron/sqlx v1.4.0
github.com/lib/pq v1.10.9
github.com/robfig/cron/v3 v3.0.1
golang.org/x/oauth2 v0.29.0
google.golang.org/api v0.231.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgm
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
Expand Down
15 changes: 0 additions & 15 deletions internal/app/contribution/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ type handler struct {
}

type Handler interface {
FetchUserLatestContributions(w http.ResponseWriter, r *http.Request)
FetchUsersAllContributions(w http.ResponseWriter, r *http.Request)
}

Expand All @@ -23,20 +22,6 @@ func NewHandler(contributionService Service) Handler {
}
}

func (h *handler) FetchUserLatestContributions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

err := h.contributionService.ProcessFetchedContributions(ctx)
if err != nil {
slog.Error("error fetching latest contributions")
status, errorMessage := apperrors.MapError(err)
response.WriteJson(w, status, errorMessage, nil)
return
}

response.WriteJson(w, http.StatusOK, "contribution fetched successfully", nil)
}

func (h *handler) FetchUsersAllContributions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

Expand Down
26 changes: 26 additions & 0 deletions internal/app/cronJob/cronjob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cronJob

import (
"context"
"log/slog"
"time"
)

type Job interface {
Schedule(c *CronSchedular) error
}

type CronJob struct {
Name string
}

func (c *CronJob) Execute(ctx context.Context, fn func(context.Context)) func() {
return func() {
slog.Info("cron job started at", "time ", time.Now())
defer func() {
slog.Info("cron job completed")
}()

fn(ctx)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you try below

func (c *CronJob) Execute(ctx context.Context, fn func(context.Context)) {
	slog.Info("cron job started at", "time ", time.Now())
	defer func() {
		slog.Info("cron job completed")
	}()

	fn(ctx)
}

and when using it

	_, err := s.cron.AddFunc("0 1 * * *", func() { d.Execute(context.Background(), d.run) })

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay

32 changes: 32 additions & 0 deletions internal/app/cronJob/dailyJob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cronJob

import (
"context"

"github.com/joshsoftware/code-curiosity-2025/internal/app/contribution"
)

type DailyJob struct {
CronJob
contributionService contribution.Service
}

func NewDailyJob(contributionService contribution.Service) *DailyJob {
return &DailyJob{
contributionService: contributionService,
CronJob: CronJob{Name: "Fetch Contributions Daily"},
}
}

func (d *DailyJob) Schedule(s *CronSchedular) error {
_, err := s.cron.AddFunc("0 1 * * *", func() { d.Execute(context.Background(), d.run)() })
if err != nil {
return err
}

return nil
}

func (d *DailyJob) run(ctx context.Context) {
d.contributionService.ProcessFetchedContributions(ctx)
}
38 changes: 38 additions & 0 deletions internal/app/cronJob/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cronJob

import (
"log/slog"
"time"

"github.com/joshsoftware/code-curiosity-2025/internal/app/contribution"
"github.com/robfig/cron/v3"
)

type CronSchedular struct {
cron *cron.Cron
}

func NewCronSchedular() *CronSchedular {
location, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
slog.Error("failed to load IST timezone", "error", err)
}

return &CronSchedular{
cron: cron.New(cron.WithLocation(location)),
}
}

func (c *CronSchedular) InitCronJobs(contributionService contribution.Service) {
jobs := []Job{
NewDailyJob(contributionService),
}

for _, job := range jobs {
if err := job.Schedule(c); err != nil {
slog.Error("failed to execute cron job")
}
}

c.cron.Start()
}
1 change: 0 additions & 1 deletion internal/app/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ func NewRouter(deps Dependencies) http.Handler {

router.HandleFunc("PATCH /api/v1/user/email", middleware.Authentication(deps.UserHandler.UpdateUserEmail, deps.AppCfg))

router.HandleFunc("GET /api/v1/user/contributions/latest", middleware.Authentication(deps.ContributionHandler.FetchUserLatestContributions, deps.AppCfg))
router.HandleFunc("GET /api/v1/user/contributions/all", middleware.Authentication(deps.ContributionHandler.FetchUsersAllContributions, deps.AppCfg))
return middleware.CorsMiddleware(router, deps.AppCfg)
}