Commit ecbd1896 authored by Kyle Clarke's avatar Kyle Clarke 💬

Added the go report card to the readme file.

parent 98955a52
Pipeline #5142956 passed with stage
in 28 seconds
......@@ -7,12 +7,13 @@ ___
[logo]: http://i3.mirror.co.uk/incoming/article1772857.ece/ALTERNATES/s615b/It's%20Kevin.jpg
[![Build Status](https://gitlab.com/kylehqcom/kevin/badges/master/build.svg)](https://gitlab.com/kylehqcom/kevin/commits/master)
[![Go report card](https://goreportcard.com/badge/gitlab.com/kylehqcom/kevin)](https://goreportcard.com/report/gitlab.com/kylehqcom/kevin)
Kevin is an in memory non persistent scheduler written in Golang that simplifies
handling repeating method calls. Kevin allows you to
- run a job ***n*** number of times
Kevin is an in memory non persistent scheduler written in Golang that simplifies
handling repeating method calls. Kevin allows you to
- run a job ***n*** number of times
- at a predefined start time
- at every ***n*** unit of time (nano, micro, milli seconds, minutes...)
- at every ***n*** unit of time (nano, micro, milli seconds, minutes...)
- with automatic expirations
But Kevin also keeps track of these jobs running asynchronously in go routines
......@@ -54,7 +55,7 @@ For full reference documentation, go to [![GoDoc](https://godoc.org/gitlab.com/k
## Schedules
The ```DefaultSchedule()``` is available to you out of the box and always will be. To
The ```DefaultSchedule()``` is available to you out of the box and always will be. To
create your own custom schedules call
```
......@@ -69,18 +70,18 @@ s, err := kevin.NewSchedule(c)
An error will be returned on an empty name "" or if a schedule of the same name is
found. Names **are** case sensitive.
The optional purge fields help define an auto purger created on your new schedule. If
The optional purge fields help define an auto purger created on your new schedule. If
left to the defaults, on every hour the schedule will be purged, removing all
***completed*** job runners that are older than 24 hours. Alter the ***PurgeAfter***
time.Duration to purge completed runners sooner/later.
Don't want to purge anything? That's no problem! Just pass a zero duration as your
Don't want to purge anything? That's no problem! Just pass a zero duration as your
***PurgePoll*** value.
```
c := kevin.ScheduleConfig{
Name: "custom",
PurgePoll: time.Duration(0),
PurgePoll: time.Duration(0),
})
```
......@@ -90,34 +91,34 @@ Of course you can always just call `purge()` manually on your schedule if you pr
s.Purge(time.Duration(time.Minute))
```
Because Kevin is an in memory scheduler, on load you may need to populate Kevin using
Because Kevin is an in memory scheduler, on load you may need to populate Kevin using
values from an existing store. If you're not sure whether jobs are already loaded and
running, call `IsEmpty()` to confirm
```
// For all schedules in the pool
kevin.IsEmpty()
kevin.IsEmpty()
// For a single schedule
DefaultSchedule().IsEmpty()
```
DefaultSchedule().IsEmpty()
```
Likewise if you want to stop and remove all job runners, call `Reset()`
Likewise if you want to stop and remove all job runners, call `Reset()`
```
// For all schedules in the pool
kevin.Reset()
kevin.Reset()
// For a single schedule
DefaultSchedule().Reset()
```
DefaultSchedule().Reset()
```
A `Reset()` will first mark each job runner as stopped so that ***Every***
iterations will stop on next invocation before removing from the schedule. `Reset()`
**will not** remove the schedule itself.
A `Reset()` will first mark each job runner as stopped so that ***Every***
iterations will stop on next invocation before removing from the schedule. `Reset()`
**will not** remove the schedule itself.
## Jobs
In Kevin, Jobs are a template for runners to execute. They are merely a parameter bag to
In Kevin, Jobs are a template for runners to execute. They are merely a parameter bag to
fulfil a job runner. But you should be aware of the available options you can assign.
```
......@@ -145,15 +146,15 @@ type Job struct {
}
```
Note that when assigning ***Begins*** and ***Expires*** time values, the time given does
**not** ensure that a job begins or expires exactly at the time given. Kevin **does**
Note that when assigning ***Begins*** and ***Expires*** time values, the time given does
**not** ensure that a job begins or expires exactly at the time given. Kevin **does**
guarantee however that a job will not run before or after the times given. The difference
is determined by the ***Every*** duration value and submission of ***Run()***.
is determined by the ***Every*** duration value and submission of ***Run()***.
For example, if you assign an ***Every*** duration of an hour, a ***Begins*** of
For example, if you assign an ***Every*** duration of an hour, a ***Begins*** of
12:00pm and ***Run()*** the job at 10:50am, the first ***Every*** will occur at roughly
11:50am and skip to the next ***Every*** iteration due to the ***Begins*** of 12:00pm.
The next ***Every*** at roughly 12:50pm will call the supplied ***Fn*** value. By default both
The next ***Every*** at roughly 12:50pm will call the supplied ***Fn*** value. By default both
***Begins*** and ***Expires*** are zero valued and therefore ignored. Simply assign `time.Duration(0)`
values to explicitly ignore.
......@@ -165,8 +166,8 @@ params directly to the struct, eg;
FnParams: []interface{}{"www.kylehq.com", "name drop yo", 24}
```
So instead you can use the provided convenience method of `Job.AddFnParams()`. This
allows you mix and match as you please, either assigning params at ***Job*** struct creation
So instead you can use the provided convenience method of `Job.AddFnParams()`. This
allows you mix and match as you please, either assigning params at ***Job*** struct creation
or adding parameter values on the fly. Just be sure you maintain order.
```
......@@ -180,16 +181,16 @@ j := &Job{
}
// Assign 3 more to fulfil ParamLots
j.AddFnParams("yankee", "zebra", 21)
j.AddFnParams("yankee", "zebra", 21)
ID, err := kevin.DefaultSchedule().Run(j)
```
#### JobIDs
By default a `JobID` is returned on `Add()` and `Run()` to enable you to store and
track your job runners progress. A `JobID` is **unique ONLY to each schedule**. If you
are creating numerous schedules, it may be beneficial to provide your own universal ID,
By default a `JobID` is returned on `Add()` and `Run()` to enable you to store and
track your job runners progress. A `JobID` is **unique ONLY to each schedule**. If you
are creating numerous schedules, it may be beneficial to provide your own universal ID,
such as a `user_id`.
For example, imagine you have x3 schedules, one for http requests, one for sms requests
......@@ -222,19 +223,19 @@ UserJobID := kevin.GenerateID("your optional user_id here")
## Caveats / TODO's
**Job Every time.Duration**
You will note that you can assign ***any*** time.Duration value to a
You will note that you can assign ***any*** time.Duration value to a
jobs' Every field. Kevin could limit the Every to a minimum duration of 1 second. But
micro and nano second values are a construct of the Golang language so Kevin should
support them too. However, Kevin **cannot guarantee** the performance of this package
under nano second circumstances. Although some steps have been taken to sync.lock
values, Kevin makes **no guarantees**. Not to mention any lag with ID generation on
job additions. To date Kevin has not been performance profiled so use micro/nano
values, Kevin makes **no guarantees**. Not to mention any lag with ID generation on
job additions. To date Kevin has not been performance profiled so use micro/nano
seconds at your own peril.
**Will a runner run forever?**
***No!*** Internally Kevin has a safety check based on a `uint64` value range. If the runner iterates up to the `uint64`
limit, Kevin will break from the running loop, just to be safe! If this event should occur and you want/need to keep
limit, Kevin will break from the running loop, just to be safe! If this event should occur and you want/need to keep
processing, then simply check the returned Kevin Error of `ErrJobMaximumTickBreach`. Then remove the existing job from
the schedule and re-add as required. But do you really need a job to execute 18446744073709551615 times?
......@@ -244,21 +245,21 @@ Qs: Can the Run() or Info() methods contain return values from my Fn call?
Answer: ***NO!*** (Although possible it's not gonna happen)
Your **Fn** should handle all errors and logging. Kevins' sole purpose is to run
scheduled jobs, not handle errors from the functions it is offloading to. For a start,
Kevin is non persistent and memory based. If you need to act on an error returned and
Your **Fn** should handle all errors and logging. Kevins' sole purpose is to run
scheduled jobs, not handle errors from the functions it is offloading to. For a start,
Kevin is non persistent and memory based. If you need to act on an error returned and
the power goes out, then best you get yourself a lawyer...
**TODO's** - these are only potential and at this point not actively being addressed. I guess you
can always request or become self inspired...
**TODO's** - these are only potential and at this point not actively being addressed. I guess you
can always request or become self inspired...
- Logging
- Profiling
- Persistence
## Why is my name Kevin?
Now I'm all for treating servers like cattle. Spin them up, have them killed and
just spin up some more. But code and servers are in no ways the same. Code can
(and should be) something that you put your thoughts and feelings into. If coding
is an art form, then surely we are artists?
Now I'm all for treating servers like cattle. Spin them up, have them killed and
just spin up some more. But code and servers are in no ways the same. Code can
(and should be) something that you put your thoughts and feelings into. If coding
is an art form, then surely we are artists?
Besides, just wait until you meet the rest of the family including Cindy, Pat and Rick...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment