[ANN] Schejulure 0.1.1

2013-01-17 Thread Adam Clements
So there are a few scheduling libraries around, I wanted one for cron-like 
job scheduling and my options were quite limited, there are things like 
clj-cronlike and quartzite but I found the syntax quite clunky and didn't 
like the central stateful scheduler idea. There are also things like at-at, 
but that's more for events recurring over seconds/minutes or one-shot 
events, so that was out too.

In the end I wrote my own library. It's tiny (~60 lines) and does one task 
quite well. It's modelled after futures, and in fact returns a future, so 
use it in the same places/way you might use a future, but for recurring 
events.

To schedule things, it's like a cron setup (so by default fires every 
minute of every hour of every day...) but you can pass a map of times when 
it should fire, so for example {:minute [0 15 30 45] :day :tue} will fire 
every 15 minutes on a tuesday where {:hour 9} will fire every minute from 
9-10am every day. Beyond that you simply call schedule with pairs of 
schedule maps to functions which should fire.

Example:
=> (def my-running-scheduler
 (schedule {:hour 12 :minute [0 15 30 45]} my-function
   {:hour (range 0 24 6) :minute 0 :day [:sat :sun]} batch-job))

...
=> (future-cancel my-running-scheduler)

Simple as that.

Like I say, this was to scratch my own itch, but if anyone else finds it 
useful, great. If it nearly does what you want but not quite... hey, it's 
only 60 lines, fork it/fix it. If anyone has suggestions for features, 
bugfixes or other libraries I should be contributing this code to instead, 
that would be useful knowledge too.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-17 Thread Adam Clements
A URL would probably help: https://github.com/AdamClements/schejulure

On Thursday, January 17, 2013 5:56:40 PM UTC, Adam Clements wrote:
>
> So there are a few scheduling libraries around, I wanted one for cron-like 
> job scheduling and my options were quite limited, there are things like 
> clj-cronlike and quartzite but I found the syntax quite clunky and didn't 
> like the central stateful scheduler idea. There are also things like at-at, 
> but that's more for events recurring over seconds/minutes or one-shot 
> events, so that was out too.
>
> In the end I wrote my own library. It's tiny (~60 lines) and does one task 
> quite well. It's modelled after futures, and in fact returns a future, so 
> use it in the same places/way you might use a future, but for recurring 
> events.
>
> To schedule things, it's like a cron setup (so by default fires every 
> minute of every hour of every day...) but you can pass a map of times when 
> it should fire, so for example {:minute [0 15 30 45] :day :tue} will fire 
> every 15 minutes on a tuesday where {:hour 9} will fire every minute from 
> 9-10am every day. Beyond that you simply call schedule with pairs of 
> schedule maps to functions which should fire.
>
> Example:
> => (def my-running-scheduler
>  (schedule {:hour 12 :minute [0 15 30 45]} my-function
>{:hour (range 0 24 6) :minute 0 :day [:sat :sun]} 
> batch-job))
>
> ...
> => (future-cancel my-running-scheduler)
>
> Simple as that.
>
> Like I say, this was to scratch my own itch, but if anyone else finds it 
> useful, great. If it nearly does what you want but not quite... hey, it's 
> only 60 lines, fork it/fix it. If anyone has suggestions for features, 
> bugfixes or other libraries I should be contributing this code to instead, 
> that would be useful knowledge too.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-18 Thread Paulo Suzart
Hello Adam,

I knew about https://github.com/overtone/at-at. Your lib is pretty straight
forward and promising.

Cheers

On 17 January 2013 16:05, Adam Clements  wrote:

> A URL would probably help: https://github.com/AdamClements/schejulure
>
>
> On Thursday, January 17, 2013 5:56:40 PM UTC, Adam Clements wrote:
>>
>> So there are a few scheduling libraries around, I wanted one for
>> cron-like job scheduling and my options were quite limited, there are
>> things like clj-cronlike and quartzite but I found the syntax quite clunky
>> and didn't like the central stateful scheduler idea. There are also things
>> like at-at, but that's more for events recurring over seconds/minutes or
>> one-shot events, so that was out too.
>>
>> In the end I wrote my own library. It's tiny (~60 lines) and does one
>> task quite well. It's modelled after futures, and in fact returns a future,
>> so use it in the same places/way you might use a future, but for recurring
>> events.
>>
>> To schedule things, it's like a cron setup (so by default fires every
>> minute of every hour of every day...) but you can pass a map of times when
>> it should fire, so for example {:minute [0 15 30 45] :day :tue} will fire
>> every 15 minutes on a tuesday where {:hour 9} will fire every minute from
>> 9-10am every day. Beyond that you simply call schedule with pairs of
>> schedule maps to functions which should fire.
>>
>> Example:
>> => (def my-running-scheduler
>>  (schedule {:hour 12 :minute [0 15 30 45]} my-function
>>{:hour (range 0 24 6) :minute 0 :day [:sat :sun]}
>> batch-job))
>>
>> ...
>> => (future-cancel my-running-scheduler)
>>
>> Simple as that.
>>
>> Like I say, this was to scratch my own itch, but if anyone else finds it
>> useful, great. If it nearly does what you want but not quite... hey, it's
>> only 60 lines, fork it/fix it. If anyone has suggestions for features,
>> bugfixes or other libraries I should be contributing this code to instead,
>> that would be useful knowledge too.
>>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>



-- 
Paulo Suzart
@paulosuzart

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-18 Thread Jason Lewis
Adam,

This looks great. I was building a couple of applications that run periodic
tasks/services on top of quartzite, but I'll definitely play with this.
Much nicer scheduling syntax, and the lack of a single stateful scheduler
feels much more Clojurian (and cleaner, too).

Thanks!

Jason Lewis

Email  jasonlewi...@gmail.com

Twitter@canweriotnow 

About http://about.me/jason.lewis


On Fri, Jan 18, 2013 at 12:14 PM, Paulo Suzart wrote:

> Hello Adam,
>
> I knew about https://github.com/overtone/at-at. Your lib is pretty
> straight forward and promising.
>
> Cheers
>
>
> On 17 January 2013 16:05, Adam Clements  wrote:
>
>> A URL would probably help: https://github.com/AdamClements/schejulure
>>
>>
>> On Thursday, January 17, 2013 5:56:40 PM UTC, Adam Clements wrote:
>>>
>>> So there are a few scheduling libraries around, I wanted one for
>>> cron-like job scheduling and my options were quite limited, there are
>>> things like clj-cronlike and quartzite but I found the syntax quite clunky
>>> and didn't like the central stateful scheduler idea. There are also things
>>> like at-at, but that's more for events recurring over seconds/minutes or
>>> one-shot events, so that was out too.
>>>
>>> In the end I wrote my own library. It's tiny (~60 lines) and does one
>>> task quite well. It's modelled after futures, and in fact returns a future,
>>> so use it in the same places/way you might use a future, but for recurring
>>> events.
>>>
>>> To schedule things, it's like a cron setup (so by default fires every
>>> minute of every hour of every day...) but you can pass a map of times when
>>> it should fire, so for example {:minute [0 15 30 45] :day :tue} will fire
>>> every 15 minutes on a tuesday where {:hour 9} will fire every minute from
>>> 9-10am every day. Beyond that you simply call schedule with pairs of
>>> schedule maps to functions which should fire.
>>>
>>> Example:
>>> => (def my-running-scheduler
>>>  (schedule {:hour 12 :minute [0 15 30 45]} my-function
>>>{:hour (range 0 24 6) :minute 0 :day [:sat :sun]}
>>> batch-job))
>>>
>>> ...
>>> => (future-cancel my-running-scheduler)
>>>
>>> Simple as that.
>>>
>>> Like I say, this was to scratch my own itch, but if anyone else finds it
>>> useful, great. If it nearly does what you want but not quite... hey, it's
>>> only 60 lines, fork it/fix it. If anyone has suggestions for features,
>>> bugfixes or other libraries I should be contributing this code to instead,
>>> that would be useful knowledge too.
>>>
>>  --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>
>
> --
> Paulo Suzart
> @paulosuzart
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-18 Thread Marko Topolnik


> This looks great. I was building a couple of applications that run 
> periodic tasks/services on top of quartzite, but I'll definitely play with 
> this. Much nicer scheduling syntax, and the lack of a single stateful 
> scheduler feels much more Clojurian (and cleaner, too).
>

Behind the apparent elegance is a design that could be wasteful with system 
resources, starting another thread with each invocation of *schedule* and 
leaving 
the executor service running after the future is cancelled.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-18 Thread Adam Clements
Hi Marko,

I've addressed some of your concerns by re-using a single thread pool for
multiple schedule calls in the current master. The original use case was
one set of scheduled tasks running for the lifetime of my application. If
you can suggest improvements to cover other use cases with more
stopping/starting scheduled tasks and automatically cleaning up the
executor service if it's no longer needed that would be great.

Adam Clements

On Fri, Jan 18, 2013 at 9:50 PM, Marko Topolnik wrote:

>
> This looks great. I was building a couple of applications that run
>> periodic tasks/services on top of quartzite, but I'll definitely play with
>> this. Much nicer scheduling syntax, and the lack of a single stateful
>> scheduler feels much more Clojurian (and cleaner, too).
>>
>
> Behind the apparent elegance is a design that could be wasteful with
> system resources, starting another thread with each invocation of *
> schedule* and leaving the executor service running after the future is
> cancelled.
>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-19 Thread Marko Topolnik
There is no need to wrap the Executor Service in a* delay* because it 
already implements lazy-start semantics. From the *ThreadPoolExecutor*
 Javadoc:
On-demand constructionBy default, even core threads are initially created 
and started only when new tasks arrive, but this can be overridden 
dynamically using 
methodprestartCoreThread()
 or 
prestartAllCoreThreads().
 
You probably want to prestart threads if you construct the pool with a 
non-empty queue.

Also, if you constrain the design to a singleton scheduled thread pool, 
there is no pressing need to shut it down after all schedules are 
cancelled: a total of a few idle threads is deemed acceptable, especially 
because scheduling is either needed for the entire runtime, or not needed 
at all. The major issue were the abandoned schedulers, which you have 
solved.

A more pressing concern is the size of the thread pool: with just one 
thread, only one task can run at a time. In practice many tasks are very 
short-lived and a single thread can take care of dozens of them, but some 
are quite long-lived, going for 10 minutes and more. Combining such tasks 
with the short-lived ones will result in the short-lived tasks executing on 
a very irregular schedule. This leads towards a configurable stateful 
implementation, which is against the first goal of your design. 
Regrettably, no obvious solutions come to mind.

On Saturday, January 19, 2013 1:00:26 AM UTC+1, Adam Clements wrote:
>
> Hi Marko,
>
> I've addressed some of your concerns by re-using a single thread pool for 
> multiple schedule calls in the current master. The original use case was 
> one set of scheduled tasks running for the lifetime of my application. If 
> you can suggest improvements to cover other use cases with more 
> stopping/starting scheduled tasks and automatically cleaning up the 
> executor service if it's no longer needed that would be great. 
>
> Adam Clements
>
> On Fri, Jan 18, 2013 at 9:50 PM, Marko Topolnik 
> 
> > wrote:
>
>>
>> This looks great. I was building a couple of applications that run 
>>> periodic tasks/services on top of quartzite, but I'll definitely play with 
>>> this. Much nicer scheduling syntax, and the lack of a single stateful 
>>> scheduler feels much more Clojurian (and cleaner, too).
>>>
>>
>> Behind the apparent elegance is a design that could be wasteful with 
>> system resources, starting another thread with each invocation of *
>> schedule* and leaving the executor service running after the future is 
>> cancelled.
>>
>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-19 Thread Adam Clements
Ah, thanks for the tip. I have now released 0.1.2 which is unchanged apart
from this fix (not leaking ExecutorServices) and improved documentation.

For the single threaded point, I have added in to the documentation that
tasks with a non-trivial running time should fire futures in order to avoid
affecting subsequent scheduled tasks, which I think is a reasonable
restriction to make given the resulting simplicity.

Thanks again for the useful feedback.

Adam
On 19 Jan 2013 09:53, "Marko Topolnik"  wrote:

> There is no need to wrap the Executor Service in a* delay* because it
> already implements lazy-start semantics. From the *ThreadPoolExecutor*
>  Javadoc:
> On-demand constructionBy default, even core threads are initially created
> and started only when new tasks arrive, but this can be overridden
> dynamically using 
> methodprestartCoreThread()
>  or 
> prestartAllCoreThreads().
> You probably want to prestart threads if you construct the pool with a
> non-empty queue.
>
> Also, if you constrain the design to a singleton scheduled thread pool,
> there is no pressing need to shut it down after all schedules are
> cancelled: a total of a few idle threads is deemed acceptable, especially
> because scheduling is either needed for the entire runtime, or not needed
> at all. The major issue were the abandoned schedulers, which you have
> solved.
>
> A more pressing concern is the size of the thread pool: with just one
> thread, only one task can run at a time. In practice many tasks are very
> short-lived and a single thread can take care of dozens of them, but some
> are quite long-lived, going for 10 minutes and more. Combining such tasks
> with the short-lived ones will result in the short-lived tasks executing on
> a very irregular schedule. This leads towards a configurable stateful
> implementation, which is against the first goal of your design.
> Regrettably, no obvious solutions come to mind.
>
> On Saturday, January 19, 2013 1:00:26 AM UTC+1, Adam Clements wrote:
>>
>> Hi Marko,
>>
>> I've addressed some of your concerns by re-using a single thread pool for
>> multiple schedule calls in the current master. The original use case was
>> one set of scheduled tasks running for the lifetime of my application. If
>> you can suggest improvements to cover other use cases with more
>> stopping/starting scheduled tasks and automatically cleaning up the
>> executor service if it's no longer needed that would be great.
>>
>> Adam Clements
>>
>> On Fri, Jan 18, 2013 at 9:50 PM, Marko Topolnik wrote:
>>
>>>
>>> This looks great. I was building a couple of applications that run
 periodic tasks/services on top of quartzite, but I'll definitely play with
 this. Much nicer scheduling syntax, and the lack of a single stateful
 scheduler feels much more Clojurian (and cleaner, too).

>>>
>>> Behind the apparent elegance is a design that could be wasteful with
>>> system resources, starting another thread with each invocation of *
>>> schedule* and leaving the executor service running after the future is
>>> cancelled.
>>>
>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@**googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/**group/clojure?hl=en
>>>
>>
>>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: [ANN] Schejulure 0.1.1

2013-01-19 Thread Marko Topolnik


> For the single threaded point, I have added in to the documentation that 
> tasks with a non-trivial running time should fire futures in order to avoid 
> affecting subsequent scheduled tasks, which I think is a reasonable 
> restriction to make given the resulting simplicity.
>
I agree, this is a great decision. It allows your library to keep the focus 
on rendering its key value-adding service without involving separate 
concerns that are easily managed by the client side.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en