Skip to content

Commit

Permalink
ref: rename package
Browse files Browse the repository at this point in the history
update readme

update test
  • Loading branch information
firminochangani committed Jan 21, 2024
1 parent b278f35 commit 63cccb0
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 90 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# schedule
# recurrent

[![main](https://github.com/flowck/schedule/actions/workflows/main.yml/badge.svg)](https://github.com/flowck/schedule/actions/workflows/main.yml)

Golang job scheduling for humans. Run Go functions periodically using a friendly syntax. - Inspired by Python lib [schedule](https://github.com/dbader/schedule)
A Go package to run tasks recurrently. - Inspired by the Python lib [schedule](https://github.com/dbader/schedule)

## Usage

Expand All @@ -14,20 +14,20 @@ import (
"fmt"
"time"

"github.com/flowck/schedule"
"github.com/flowck/recurrent/recurrent"
)

func main() {
ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

s := schedule.New()
s := recurrent.New()

s.Every(10).Seconds().Do(func(ctx context.Context) {
s.Every(time.Second * 1).Do(func(ctx context.Context) {
fmt.Println("--->", time.Now())
})

s.Every(30).Seconds().Do(func(ctx context.Context) {
s.Every(time.Second * 2).Do(func(ctx context.Context) {
fmt.Println("--->", time.Now())
})

Expand Down
8 changes: 4 additions & 4 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import (
"fmt"
"time"

"github.com/flowck/schedule/schedule"
"github.com/flowck/recurrent/recurrent"
)

func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

s := schedule.New()
s := recurrent.New()

s.Every(1).Seconds().Do(func(ctx context.Context) {
s.Every(time.Second * 1).Do(func(ctx context.Context) {
fmt.Println("--->", time.Now())
})

s.Every(2).Seconds().Do(func(ctx context.Context) {
s.Every(time.Second * 2).Do(func(ctx context.Context) {
fmt.Println("--->", time.Now())
})

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/flowck/schedule
module github.com/flowck/recurrent

go 1.21

Expand Down
53 changes: 12 additions & 41 deletions schedule/job.go → recurrent/job.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package schedule
package recurrent

import (
"context"
Expand All @@ -9,9 +9,10 @@ import (

var ErrJobStopped = errors.New("the job has been stopped")

type JobHandler func(ctx context.Context)

type Job struct {
interval int
ticker *time.Ticker
ticker *time.Ticker

// isRunning is read and written in different places simultaneously thus causing data race issues
// hence the atomic type
Expand All @@ -24,27 +25,16 @@ type Job struct {

id string

// having a reference to the scheduler will allow us to cal
// having a reference to the manager will allow us to cal
// job.Do(func(ctx context.Content) {}) and finally have the job
// appended to the scheduler
scheduler *Schedule
handler JobHandler
}

type JobHandler func(ctx context.Context)

func (j *Job) Second() *Job {
return j
}

func (j *Job) Seconds() *Job {
j.ticker = time.NewTicker(time.Duration(j.interval) * time.Second)
return j
// appended to the manager
manager *Manager
handler JobHandler
}

func (j *Job) Do(handler JobHandler) *Job {
j.handler = handler
j.scheduler.appendJob(j)
j.manager.appendJob(j)

return j
}
Expand Down Expand Up @@ -75,7 +65,7 @@ func (j *Job) runHandler(ctx context.Context) {
}

func (j *Job) stop() {
j.scheduler.logger.Infof("Stopping the job %s", j.id)
j.manager.logger.Infof("Stopping the job %s", j.id)

// send a signal to the job handler to inform it about the stoppage of the job
if j.cancelCtx != nil {
Expand All @@ -89,26 +79,7 @@ func (j *Job) stop() {
for j.isRunning.Load() {
}

j.scheduler.logger.Infof("Job %s has been stopped", j.id)
j.manager.logger.Infof("Job %s has been stopped", j.id)
}

func (j *Job) Minute() {}
func (j *Job) Minutes() {}
func (j *Job) Hour() {}
func (j *Job) Hours() {}
func (j *Job) Day() {}
func (j *Job) Days() {}
func (j *Job) Week() {}
func (j *Job) Weeks() {}
func (j *Job) Monday() {}
func (j *Job) Tuesday() {}
func (j *Job) Wednesday() {}
func (j *Job) Thursday() {}
func (j *Job) Friday() {}
func (j *Job) Saturday() {}
func (j *Job) Sunday() {}
func (j *Job) Tag() {}
func (j *Job) At() {}
func (j *Job) To() {}
func (j *Job) Until() {}
func (j *Job) ShouldRun() {}
func (j *Job) Until() {}
2 changes: 1 addition & 1 deletion schedule/logger.go → recurrent/logger.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package schedule
package recurrent

import (
"fmt"
Expand Down
34 changes: 17 additions & 17 deletions schedule/schedule.go → recurrent/manager.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package schedule
package recurrent

import (
"context"
Expand All @@ -8,21 +8,21 @@ import (
"github.com/oklog/ulid/v2"
)

type Schedule struct {
type Manager struct {
logger Logger
lock *sync.RWMutex
jobs map[string]*Job
}

func New() *Schedule {
return &Schedule{
func New() *Manager {
return &Manager{
lock: &sync.RWMutex{},
logger: NewDefaultLogger(),
jobs: make(map[string]*Job),
}
}

func (s *Schedule) Run(ctx context.Context) {
func (s *Manager) Run(ctx context.Context) {
s.lock.Lock()
for _, job := range s.jobs {
go func(ctx context.Context, job *Job) {
Expand All @@ -36,25 +36,25 @@ func (s *Schedule) Run(ctx context.Context) {
s.cancelAllJobs()
}

func (s *Schedule) Every(interval int) *Job {
func (s *Manager) Every(interval time.Duration) *Job {
return &Job{
scheduler: s,
interval: interval,
id: ulid.Make().String(),
done: make(chan interface{}),
manager: s,
id: ulid.Make().String(),
done: make(chan interface{}),
ticker: time.NewTicker(interval),
}
}

func (s *Schedule) appendJob(job *Job) {
func (s *Manager) appendJob(job *Job) {
s.lock.Lock()
defer s.lock.Unlock()

s.jobs[job.id] = job
s.logger.Infof("Job with id %s has been appended to the scheduler", job.id)
s.logger.Infof("Job with id %s has been appended to the manager", job.id)
}

// RunAll Runs all jobs regardless if they are scheduled to run or not.
func (s *Schedule) RunAll(ctx context.Context, delay time.Duration) {
func (s *Manager) RunAll(ctx context.Context, delay time.Duration) {
s.lock.RLock()
defer s.lock.RUnlock()

Expand All @@ -67,7 +67,7 @@ func (s *Schedule) RunAll(ctx context.Context, delay time.Duration) {
}

// GetJobs Returns all jobs
func (s *Schedule) GetJobs() []*Job {
func (s *Manager) GetJobs() []*Job {
s.lock.RLock()
defer s.lock.RUnlock()

Expand All @@ -82,7 +82,7 @@ func (s *Schedule) GetJobs() []*Job {
}

// Clear Stops all jobs and then delete them from the schedule
func (s *Schedule) Clear() {
func (s *Manager) Clear() {
s.lock.Lock()
defer s.lock.Unlock()

Expand All @@ -93,7 +93,7 @@ func (s *Schedule) Clear() {
}

// CancelJob Stops a job a removes it from the schedule
func (s *Schedule) CancelJob(job *Job) {
func (s *Manager) CancelJob(job *Job) {
job.stop()

s.lock.Lock()
Expand All @@ -102,7 +102,7 @@ func (s *Schedule) CancelJob(job *Job) {
delete(s.jobs, job.id)
}

func (s *Schedule) cancelAllJobs() {
func (s *Manager) cancelAllJobs() {
s.logger.Info("Cancelling all jobs")

s.lock.RLock()
Expand Down
38 changes: 19 additions & 19 deletions schedule/schedule_test.go → recurrent/manager_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package schedule_test
package recurrent_test

import (
"context"
Expand All @@ -8,22 +8,22 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/flowck/schedule/schedule"
"github.com/flowck/recurrent/recurrent"
)

func TestSchedule(t *testing.T) {
func TestManager(t *testing.T) {
testCases := []struct {
name string
expectedNumberOfCallsToHandler int
timeout time.Duration
job func(s *schedule.Schedule) *schedule.Job
job func(s *recurrent.Manager) *recurrent.Job
}{
{
name: "schedule_every_1_seconds_for_5_seconds",
name: "every_1_seconds_for_5_seconds",
expectedNumberOfCallsToHandler: 5,
timeout: time.Second * 5,
job: func(s *schedule.Schedule) *schedule.Job {
return s.Every(1).Seconds()
job: func(s *recurrent.Manager) *recurrent.Job {
return s.Every(time.Second * 1)
},
},
}
Expand All @@ -35,7 +35,7 @@ func TestSchedule(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), tc.timeout)
defer cancel()

s := schedule.New()
s := recurrent.New()
counter := 0

tc.job(s).Do(func(ctx context.Context) {
Expand All @@ -50,12 +50,12 @@ func TestSchedule(t *testing.T) {
}
}

func TestSchedule_Clear(t *testing.T) {
s := schedule.New()
func TestManager_Clear(t *testing.T) {
s := recurrent.New()

// Given x amount of handlers
for i := 0; i < 5; i++ {
s.Every(1).Seconds().Do(func(ctx context.Context) {
s.Every(time.Second * 1).Do(func(ctx context.Context) {
t.Log("Handler ran successfully")
})
}
Expand All @@ -68,11 +68,11 @@ func TestSchedule_Clear(t *testing.T) {
assert.Empty(t, s.GetJobs())
}

func TestSchedule_CancelJob(t *testing.T) {
s := schedule.New()
func TestManager_CancelJob(t *testing.T) {
s := recurrent.New()

// Given
job := s.Every(1).Seconds().Do(func(ctx context.Context) {
job := s.Every(time.Second * 1).Do(func(ctx context.Context) {
t.Log("Handler ran successfully")
})
require.Contains(t, s.GetJobs(), job)
Expand All @@ -84,8 +84,8 @@ func TestSchedule_CancelJob(t *testing.T) {
assert.NotContains(t, s.GetJobs(), job)
}

func TestSchedule_RunAll(t *testing.T) {
s := schedule.New()
func TestManager_RunAll(t *testing.T) {
s := recurrent.New()
result := make([]int, 3)

handler := func(idx int) func(ctx context.Context) {
Expand All @@ -96,9 +96,9 @@ func TestSchedule_RunAll(t *testing.T) {
}

// Given
s.Every(1).Seconds().Do(handler(0))
s.Every(1).Seconds().Do(handler(1))
s.Every(1).Seconds().Do(handler(2))
s.Every(time.Second * 1).Do(handler(0))
s.Every(time.Second * 1).Do(handler(1))
s.Every(time.Second * 1).Do(handler(2))

// Do
s.RunAll(context.Background(), time.Millisecond*10)
Expand Down

0 comments on commit 63cccb0

Please sign in to comment.