codnect / chrono Goto Github PK
View Code? Open in Web Editor NEWChrono is a scheduler library that lets you run your task and code periodically
License: MIT License
Chrono is a scheduler library that lets you run your task and code periodically
License: MIT License
This feature makes it easier to schedule task by using markers and code generation.
The following markers should be added, they will be enough for now.
+chrono:scheduled
. This should have the following arguments.+chrono:enable-scheduling
The simple rule that we need to follow to marker a method with +chrono:scheduled
is:
The method should have the method signature as shown below. (If not, the method will be ignored or an error message will be shown.)
func(ctx context.Context)
Please investigate how to support this feature.
Executor and Scheduler both share similar methods, for example :
Executor
Schedule(task Task, delay time.Duration) (ScheduledTask, error)
ScheduleWithFixedDelay(task Task, initialDelay time.Duration, delay time.Duration) (ScheduledTask, error)
ScheduleAtFixedRate(task Task, initialDelay time.Duration, period time.Duration) (ScheduledTask, error)
and
Scheduler
Schedule(task Task, options ...Option) (ScheduledTask, error)
ScheduleWithFixedDelay(task Task, delay time.Duration, options ...Option) (ScheduledTask, error)
ScheduleAtFixedRate(task Task, period time.Duration, options ...Option) (ScheduledTask, error)
Don't you think this could be confusing considering that both interfaces are exported in the same package?
Scheduled jobs and executions will be persisted optionally to a store like a database.
Tasks will be fetched from a store.
Add a store interface.
the implementation details is not clear. description will be updated later.
WithContext function will be added to be able to pass context to scheduled task.
Executor and Runner don’t have context parameters. When we add WithContext function, we should be aware this change will be breaking backward compability.
I am currently using the one-shot scheduler to end an event. I want to shutdown that scheduler after the event is ended. However, I don't know where to put the shutdown code.
The event ending scheduler look like this:
repo.endScheduler = chrono.NewDefaultTaskScheduler()
endTime := time.Unix(event.EndTime, 0)
if _, err := repo.endScheduler.Schedule(func(ctx context.Context) {
err := repo.end(event.ID)
if err != nil {
log.Fatalf("Failed to end event: %v\n", err)
} else {
log.Println("Event ended.")
}
}, chrono.WithTime(endTime)); err != nil {
log.Fatalf("Failed to schedule event end time: %v\n", err)
return nil, err
}
My question is: Will the fact that I am not shutting down the scheduler affect the performance of my application? If it will, then how should I do it?
Thank you in advance for your attention.
I would like to be able to output something like "Processed data succesfully. Will process again at _____." Could the scheduler support querying when the next task is scheduled for?
The code I use:
task, err = ts.ScheduleWithCron(func(ctx context.Context) {
fmt.Print("Scheduled Task With Cron\n")
ierrors.Println(logTag, "Scheduled Task With Cron\n")
}, "* * * * * *", chrono.WithLocation("Etc/UTC"))
I would expect that the cronjob here will run every second, but in real it runs every "tick"
....
Scheduled Task With Cron
2021-12-10T21:48:15.307977068Z (Fight): Scheduled Task With Cron
Scheduled Task With Cron
2021-12-10T21:48:15.308020282Z (Fight): Scheduled Task With Cron
Scheduled Task With Cron
2021-12-10T21:48:15.30807167Z (Fight): Scheduled Task With Cron
Scheduled Task With Cron
2021-12-10T21:48:15.308107834Z (Fight): Scheduled Task With Cron
....
also its not working to use
styles like:
*/5 * * * * *
0 0-59/5 * * * *
0 */5 * * * *
0 1,6,11,16,21,26,31,36,41,46,51,56 * * * *
....
this will result also in the run in "loop" or also like in while true
loops.
This will result in a very very bad DoS because the CPU load goes into the sky.
CronExpression can be scheduled but never gets executed.
method: ScheduleWithCron(..., ..., chrono.WithLocation("Europe/Berlin"))
expression: does not matter, also */1 * * * * not working
docker-file to build and run:
# The base go-image
FROM golang:1.18-alpine as build
# Create a directory for the app
RUN mkdir /app
# Copy all files from the current directory to the app directory
COPY ./src /app
# Set working directory
WORKDIR /app
# go build will build an executable file named tics in the current directory
RUN go build -o tics
FROM alpine:latest AS bin
# copy from temporary "build"-image to the current
copy --from=build /app/tics /tics
copy ./tics.yml /tics.yml
EXPOSE 3222
RUN /bin/sh
# Run the tics executable
ENTRYPOINT ./tics
running the same source outside docker as an executable works.
do you have any ideas?
I am looking for a task scheduler which can execute tasks in the future. And Chrono seems pretty amazing! and close to my need.
However, I'd like to know if there is a backing store? And does the schedule tasks persist through restarts as well?
Thanks
I tested this Lib to create Timebased Jobs, from our MySQL Entries.
But what I see is that each Job I put to the Schedule, is running right after i add it.
task, err = ts.Schedule(func(ctx context.Context) {
ierrors.Println(logTag, "FightLoad Scheduled Task")
ierrors.Printf(logTag, "Time: %s\n", time.Now().UTC().String())
FightScript(fleet) // Print also the current Time same as the abdove
}, chrono.WithStartTime(
fleet.Timein.Year(),
fleet.Timein.Month(),
fleet.Timein.Day(),
fleet.Timein.Hour(),
fleet.Timein.Minute(),
fleet.Timein.Second(),
), chrono.WithLocation(time.UTC.String()),
)
What I see is the Job is running right after the schedule, but the fleet.Timein is 10 minutes in the future.
EDIT: If we remove chrono.WithLocation(time.UTC.String())
and use fleet.Timein.Local().***
it works as expected.
Maybe this should be better documentated.
Description
Using ScheduleWithCron
with a WithLocation
yield incorrect and unexpected results.
The easiest way to reproduce and understand the issue is to run the Playground POC .
Notice the code works as expected when not using WithLocation
Expected behavior
A cron to run every 2nd second.
Behavior
A cron can depending on location not run at all or run many times in a second.
Playground POC
https://go.dev/play/p/eGP1vQ-oKBE
Notice how test2
is never output.
Try replacing Europe/Copenhagen
with America/New_York
it will now runs many times in a second.
Local POC
package main
import (
"context"
"log"
"time"
"github.com/procyon-projects/chrono"
)
func main() {
r := chrono.NewDefaultTaskScheduler()
task := func(ctx context.Context) {
log.Println("task run")
}
_, err := r.ScheduleWithCron(task, "*/2 * * * * *", chrono.WithLocation("Europe/Copenhagen")) // America/New_York
if err != nil {
log.Fatal(err)
}
}
Temp fix
Remove WithLocation
and calculate the offset yourself.
Related bugs
This could be related to:
#15
According to what I could find in task.go
, within Option.WithTime()
, it appears that the subsecond part of a timestamp is ignored so that scheduling tasks with a granularity better than 1 second is not possible.
My main use case for this would be unit tests, for which scheduling durations around 50-100 ms are usually enough to achieve stable tests while keeping the test execution times small. With the 1 second granularity which is supported at the moment I have several tests that need to run for 5-10 seconds in order to have a stable scheduling order.
Can a task interface return an error?
type Task func(ctx context.Context) error
At startup.
What I see now is that tasks run immediately, regardless of what the delay is. They then run again after the delay.
The tests, showing some problems:
Running tool: /usr/local/go/bin/go test -timeout 1m30s -run ^TestCronExpression_NextTime$ **/chrono -v
=== RUN TestCronExpression_NextTime
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:18 +0100 CET expected: 2021-03-16 15:04:17 +0000 UTC
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:21 +0100 CET expected: 2021-03-16 15:04:20 +0000 UTC
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:24 +0100 CET expected: 2021-03-16 15:04:23 +0000 UTC
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:27 +0100 CET expected: 2021-03-16 15:04:26 +0000 UTC
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:30 +0100 CET expected: 2021-03-16 15:04:29 +0000 UTC
**/chrono/cron_test.go:634: got: 2021-03-16 15:10:33 +0100 CET expected: 2021-03-16 15:04:32 +0000 UTC
--- FAIL: TestCronExpression_NextTime (0.00s)
FAIL
FAIL github.com/Dexus-Forks/chrono 0.005s
is end of month supported? I don't seem to get errors running
0 0 21 L * ? *
I definitely don't see it in the code, just curious if I'm missing something here,
thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.