michaelxavier / cron Goto Github PK
View Code? Open in Web Editor NEWCron data structure and parser for Haskell
License: Other
Cron data structure and parser for Haskell
License: Other
Have you considered adding the @reboot
schedule? Looking at the code it would be a bit intrusive, because it breaks the assumption that all @foo
can be reduced to a timespec.
If I made a pull request, would you be interested in this?
I know this package is just "data structure and parser" by definition, but found the scheduling feature is useful.
So I want to reuse it for one of my applications which parses the schedule specification in a different format.
In such a use case, addJob
, runSchedule
, etc are unnecessary: calling forkJob
directly with Job
s parsed by the application is sufficient and more efficient.
Can you expose System.Cron.Schedule.forkJob
?
test/System/CronSpec.hs:4:8:
Could not find module ‘SpecHelper’
Use -v to see a list of the files searched for.
I use stackage for everything, and I really wanted to use cron, so I forked it and made cron-compat which uses the transformers and mtl compatibility shims to add ExceptT
to older versions. I mostly just wanted to put this here so that if anyone finds themselves in the same boat, they can just reuse my fork instead of redoing that work.
Apparently, the release tarball on Hackage is incomplete:
Preprocessing test suite 'test' for cron-0.3.1...
test/Main.hs:8:18:
Could not find module ‘SpecHelper’
Use -v to see a list of the files searched for.
test/Main.hs:9:18:
Could not find module ‘System.Test.Cron’
Use -v to see a list of the files searched for.
test/Main.hs:10:18:
Could not find module ‘System.Test.Cron.Parser’
Perhaps you meant
System.Cron.Parser (from cron-0.3.1@cron_CFXF91iTeegJXloOfnE9xl)
Use -v to see a list of the files searched for.
test/Main.hs:11:18:
Could not find module ‘System.Test.Cron.Schedule’
Perhaps you meant
System.Cron.Schedule (from cron-0.3.1@cron_CFXF91iTeegJXloOfnE9xl)
Use -v to see a list of the files searched for.
Since upgrading to LTS-15.1 (which ships GHC 8.8.2), I experienced troubles with some scheduled jobs that are triggered every hour.
I get the following exception:
stacktrace-exe: parseTimeOrError: no parse of "2020-02-24 11:60"
CallStack (from HasCallStack):
error, called at libraries/time/lib/Data/Time/Format/Parse.hs:82:12 in time-1.9.3:Data.Time.Format.Parse
The full stacktrace:
*** Exception (reporting due to +RTS -xc): (THUNK_2_0), stack trace:
System.Cron.Schedule.readTime',
called from System.Cron.Schedule.findNextMinuteDelay.next,
called from System.Cron.Schedule.findNextMinuteDelay,
called from System.Cron.Schedule.forkJob,
called from System.Cron.Schedule.execSchedule,
called from Main.main
stacktrace-exe: parseTimeOrError: no parse of "2020-02-24 11:60"
CallStack (from HasCallStack):
error, called at libraries/time/lib/Data/Time/Format/Parse.hs:82:12 in time-1.9.3:Data.Time.Format.Parse
I managed to reproduce the issue starting a project from scratch (with a stack init
) as below:
main :: IO ()
main = do
let Right cs1 = parseCronSchedule everyHour
print $ describe defaultOpts cs1
tids <- execSchedule $ addJob job1 everyHour
print tids
_ <- getLine
pure ()
job1 :: IO ()
job1 = do
currentTime <- getCurrentTime
print currentTime
everyHour :: Text
everyHour = pack "0 * * * *"
For the record, the job ran fine before upgrading to LTS-15.1.
Do you have any idea about it?
Thank you in advance!
... although advertised tested-with
in the cabal file. (And bounds were allowing to build it).
src/System/Cron/Types.hs:153:55:
Not in scope: ‘<$>’
Perhaps you meant ‘<>’ (imported from Data.Monoid)
src/System/Cron/Types.hs:374:63:
Not in scope: ‘<$>’
Perhaps you meant ‘<>’ (imported from Data.Monoid)
Consider using base-compat
.
Current version is no longer available on Stackage nightly (thus high risk of not being available once GHC 8.8 lands there), it would be awesome to fix the build if need be then publish back please.
Thanks in advance of my request for a really useful scheduling library.
Is there any scope to extend cron so that the time it has been scheduled for is passed to the job?
Ie so the Job definition becomes something like:
data Job = Job CronSchedule (UTCTime -> IO ())
This way, systems relying on cron can be tested independently of the current wall clock time...
I realise this would break plenty of code, but maybe there is a way to add it without doing so?
Maybe something like:
data Job = Job CronSchedule (IO ())
| JobWithTime CronSchedule (UTCTime -> IO ())
I'm using a fork at https://github.com/joehealy/cron/tree/pass_time_to_jobs to achieve this, but without the backwards compatibility.
In a web app I'm building, I have the following lines with crontab entries that do not parse correctly:
-- Somwhere far far away in an IO monad
_ <- execSchedule $ do
addJob (heartbeat app) "* * * * *"
addJob (pushCalendarUpdatesToOffice365 app) "*/5 * * * *"
pushLogStr (loggerSet $ appLogger app) $ "All cronjobs have been scheduled"
For some reason (that I'm still looking into), these don't parse correctly. However, my concern is not just about the failure to parse but about what happens after a failure. I see the following stdout when I run this:
ParseError "Failed reading: takeWhile1"
All cronjobs have been scheduled
So, execSchedule
doesn't throw an exception in IO when something goes wrong, and I think that it would be better behavior if it did. This would make it more likely that people (cough cough... me) would discover mistakes at load time. Let me know what you think of this.
Hi,
Thank you for this library, we currently use it in my team and it works like a charm 😄
I was wondering if this library is still maintained? Reasons why I ask:
cron
is not included in the next Stackage release (as is), I suspect because of the repeated build failures caused by MonadFail
changes (which is a shame since I see a commit to fix this very issue in October 2019)I hope this issue/question doesn't appear as rude 😅 I want to know if we need to fork it, or find an alternative (I did not find one yet), in anticipation of the next major GHC release 8.8 on Stack.
Cheers!
returns the first minute in the future that matches: FAIL (8.09s)
*** Failed! (after 19 tests and 1 shrink):
Exception:
test/System/Test/Cron.hs:276:15-92: Irrefutable pattern failed for pattern Just actual
CronSchedule * * * * *
1858-11-17 13:50:59.579131947983 UTC
Exception thrown while printing test case:
test/System/Test/Cron.hs:276:15-92: Irrefutable pattern failed for pattern Just actual
Use --quickcheck-replay '90 TFGenR 00000010C895C77300000000000F4240000000000000E0BC00000001FB8896C0 0 536869888 29 0' to reproduce.
a schedule that produces Just for one t will produce it for any t: OK (0.11s)
+++ OK, passed 100 tests.
Building library for cron-0.7.0.. [282/157179]
[10 of 12] Compiling System.Cron.Schedule
/var/stackage/work/unpack-dir/unpacked/cron-0.7.0-a644a72eef6377a56613b423ddc438ab324361759876a64cec8ed479374a36ff/src/System
/Cron/Schedule.hs:142:30: error: [GHC-88464]
Variable not in scope: forever :: IO b0 -> IO ()
|
142 | forkJob (Job s a) = forkIO $ forever $ do
| ^^^^^^^
/var/stackage/work/unpack-dir/unpacked/cron-0.7.0-a644a72eef6377a56613b423ddc438ab324361759876a64cec8ed479374a36ff/src/System
/Cron/Schedule.hs:145:13: error: [GHC-88464]
Variable not in scope: when :: Bool -> t0 -> IO b0
|
145 | when (scheduleMatches s timeAt) (void $ forkIO a)
| ^^^^
/var/stackage/work/unpack-dir/unpacked/cron-0.7.0-a644a72eef6377a56613b423ddc438ab324361759876a64cec8ed479374a36ff/src/System
/Cron/Schedule.hs:145:46: error: [GHC-88464]
Variable not in scope: void :: IO ThreadId -> t0
|
145 | when (scheduleMatches s timeAt) (void $ forkIO a)
| ^^^^
When you do this:
1-59/2 * * * *
it treats it as though you did this
*/2 * * * *
I'd like to build a tool that checks, whether all my crontabs did run as expected. For this I need to know, when a crontab is actually expected to run after a given timestamp.
I'd like to display the cron description in the local timezone. So,
At 02:00 AM, every 3 days
would be (in my time zone, settable w/ the opts monoid)
At 09:00 PM, every 3 days
Also, being able to remove the leading zeros would be nice (in the hours component)
[3 of 3] Compiling System.Cron.Schedule ( src/System/Cron/Schedule.hs, dist/build/System/Cron/Schedule.o )
src/System/Cron/Schedule.hs:109:32:
Ambiguous occurrence ‘defaultTimeLocale’
It could refer to either ‘Data.Time.defaultTimeLocale’,
imported from ‘Data.Time’ at src/System/Cron/Schedule.hs:53:1-26
(and originally defined in ‘time-1.5.0.1:Data.Time.Format.Locale’)
or ‘System.Locale.defaultTimeLocale’,
imported from ‘System.Locale’ at src/System/Cron/Schedule.hs:56:1-30
src/System/Cron/Schedule.hs:110:39:
Ambiguous occurrence ‘defaultTimeLocale’
It could refer to either ‘Data.Time.defaultTimeLocale’,
imported from ‘Data.Time’ at src/System/Cron/Schedule.hs:53:1-26
(and originally defined in ‘time-1.5.0.1:Data.Time.Format.Locale’)
or ‘System.Locale.defaultTimeLocale’,
imported from ‘System.Locale’ at src/System/Cron/Schedule.hs:56:1-30
src/System/Cron/Schedule.hs:112:30:
Ambiguous occurrence ‘defaultTimeLocale’
It could refer to either ‘Data.Time.defaultTimeLocale’,
imported from ‘Data.Time’ at src/System/Cron/Schedule.hs:53:1-26
(and originally defined in ‘time-1.5.0.1:Data.Time.Format.Locale’)
or ‘System.Locale.defaultTimeLocale’,
imported from ‘System.Locale’ at src/System/Cron/Schedule.hs:56:1-30
I think this is related to https://ghc.haskell.org/trac/ghc/wiki/Migration/7.10?version=9#time-1.5.0.1
See my PR
#19
Hello
First of all, thank you for this very useful library I recently started to work with.
I am experiencing some troubles when scheduling a simple job to start every minutes as it sometimes starts two threads within the same second.
ThreadId 20 at 2019-12-13 13:37:59.999691 UTC
ThreadId 21 at 2019-12-13 13:38:00.001119 UTC
I tried to reproduce in a standalone / simple example which is the following:
module Example where
import Control.Concurrent (myThreadId)
import Data.Time (getCurrentTime)
import System.Cron
runApplication :: IO ()
runApplication = do
threadIds <- execSchedule setupCronJob
putStrLn $ "Scheduling job " <> show threadIds <> " is running"
_ <- getLine
-- to stop only when the user types
pure ()
setupCronJob :: Schedule ()
setupCronJob = addJob runJob "* * * * *"
runJob :: IO ()
runJob = do
threadId <- myThreadId
currentTime <- getCurrentTime
putStrLn $ show threadId <> " at " <> show currentTime
This example triggers a job which prints the threadId with the current execution time and I get the following output:
Scheduling job [ThreadId 12] is running
ThreadId 13 at 2019-12-13 13:31:00.004439 UTC
ThreadId 14 at 2019-12-13 13:32:00.003727 UTC
ThreadId 15 at 2019-12-13 13:33:00.003082 UTC
ThreadId 16 at 2019-12-13 13:34:00.000189 UTC
ThreadId 17 at 2019-12-13 13:35:00.001204 UTC
ThreadId 18 at 2019-12-13 13:36:00.002054 UTC
ThreadId 19 at 2019-12-13 13:37:00.001719 UTC
ThreadId 20 at 2019-12-13 13:37:59.999691 UTC
ThreadId 21 at 2019-12-13 13:38:00.001119 UTC
ThreadId 22 at 2019-12-13 13:39:00.003116 UTC
ThreadId 23 at 2019-12-13 13:40:00.00399 UTC
ThreadId 24 at 2019-12-13 13:41:00.00291 UTC
ThreadId 25 at 2019-12-13 13:42:00.001187 UTC
ThreadId 26 at 2019-12-13 13:43:00.002664 UTC
I sometimes need to wait around 10 minutes to get this error.
I experience this issue in a MacOs Mojave as another colleague of mine but others don't get it in a Linux based OS.
Did anybody experienced the same behavior or do you have any hint to help on this topic?
Thank you in advance!
Would it be possible to get a version of this package that supports recent releases of mtl
: http://packdeps.haskellers.com/feed?needle=cron-compat? Maybe
http://hackage.haskell.org/package/mtl-compat can help achieve that?
I have a job that is scheduled to run at 0 0 1 * *
, i.e. at midnight at the beginning of each month. This worked as expected until this past January 1, when the job ran twice. PostgreSQL reports that the task ran at the following times:
For comparison, the most recent normal run happened at 2016-12-01 00:00:00.006968+00.
I assume that the culprit was the leap second that was inserted at the end of 2016-12-31: there was a 23:59:60 on that day.
This happened under Ubuntu 14.04.5. The machine uses NTP (with, I believe, whatever the default Ubuntu configuration is) to keep its time in sync.
My server is set to UTC. I have a haskell-cron application that should interpret its times in U.S. Eastern Standard Time (UTC-5) instead—for example, 0 0 * * *
would specify a task that should run daily at 5:00 AM UTC. Is there a straightforward way to do this?
(I tried playing around in GHCi with the TZ
environment variable set to US/Eastern
, but the times were still interpreted in UTC.)
Hi!
It would be nice for a library to have a flag for non-overlapping jobs where frequently triggered jobs are not triggered again if one of the previously started jobs hasn't finished yet. This is useful in data processing flows where processing actions take longer than the scheduled "timeout".
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.