Skip to content

Commit 47aba2f

Browse files
committed
Init
0 parents  commit 47aba2f

File tree

10 files changed

+462
-0
lines changed

10 files changed

+462
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*.cr]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 2
9+
trim_trailing_whitespace = true

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/docs/
2+
/lib/
3+
/bin/
4+
/.shards/
5+
*.dwarf
6+
7+
# Libraries don't need dependency lock
8+
# Dependencies will be locked in applications that use them
9+
/shard.lock

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: crystal
2+
3+
# Uncomment the following if you'd like Travis to run specs and check code formatting
4+
# script:
5+
# - crystal spec
6+
# - crystal tool format --check

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 your-name-here
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
all:
2+
shards build --release
3+
4+
doc:
5+
crystal doc
6+
7+
init-dev:
8+
shards install
9+
10+
lint:
11+
crystal tool format
12+
./bin/ameba src spec
13+
14+
test:
15+
crystal spec --error-trace
16+
17+
.PHONY: test

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# marmot
2+
3+
Marmot is a scheduler, use it to schedule tasks.
4+
5+
## Installation
6+
7+
1. Add the dependency to your `shard.yml`:
8+
9+
```yaml
10+
dependencies:
11+
marmot:
12+
github: erdnaxeli/marmot
13+
```
14+
15+
2. Run `shards install`
16+
17+
## Usage
18+
19+
```crystal
20+
require "marmot"
21+
22+
repetitions
23+
24+
# This task will repeat every 15 minutes.
25+
repeat_task = Marmot.repeat(15.minutes) { puts Time.local }
26+
# This task will run every day at 15:28:43, and will cancel the previous task.
27+
Marmot.cron(hour: 15, minute: 28, second: 43) do
28+
puts "It is 15:28:43: #{Time.local}"
29+
repeat_task.cancel
30+
end
31+
32+
times = 0
33+
# This task will run every 10 seconds and will cancel itself after 10 runs.
34+
Marmot.repeat(10.seconds) do |task|
35+
times += 1
36+
puts "#{times} times"
37+
task.cancel if times = 10
38+
end
39+
40+
# Start the scheduler.
41+
Marmot.run
42+
```
43+
44+
## Development
45+
46+
Don't forget to run the test.
47+
48+
As they deal with timing, they could fail if your computer is busy.
49+
Do not hesitate to run then many times if that happens.
50+
51+
## Contributing
52+
53+
1. Fork it (<https://github.com/erdnaxeli/marmot/fork>)
54+
2. Create your feature branch (`git checkout -b my-new-feature`)
55+
3. Commit your changes (`git commit -am 'Add some feature'`)
56+
4. Push to the branch (`git push origin my-new-feature`)
57+
5. Create a new Pull Request
58+
59+
## Contributors
60+
61+
- [erdnaxeli](https://github.com/erdnaxeli) - creator and maintainer

shard.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: marmot
2+
version: 0.1.0
3+
4+
authors:
5+
- Alexandre Morignot <erdnaxeli@cervoi.se>
6+
7+
crystal: 0.35.1
8+
9+
license: MIT
10+
11+
development_dependencies:
12+
ameba:
13+
github: crystal-ameba/ameba
14+
version: ~>0.13.2

spec/marmot_spec.cr

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
require "./spec_helper"
2+
3+
def expect_channel_eq(channel, value)
4+
select
5+
when x = channel.receive
6+
x.should eq(value)
7+
else
8+
raise "A value was expected"
9+
end
10+
end
11+
12+
def expect_channel_be(channel, value)
13+
select
14+
when x = channel.receive
15+
x.should be(value)
16+
else
17+
raise "A value was expected"
18+
end
19+
end
20+
21+
describe Marmot do
22+
describe "#repeat" do
23+
it "schedules a new task that repeats" do
24+
channel = Channel(Int32).new
25+
26+
x = 0
27+
task = Marmot.repeat(10.milliseconds) do
28+
x += 1
29+
channel.send(x)
30+
end
31+
spawn Marmot.run
32+
33+
sleep 15.milliseconds
34+
expect_channel_eq(channel, 1)
35+
sleep 10.milliseconds
36+
expect_channel_eq(channel, 2)
37+
sleep 10.milliseconds
38+
expect_channel_eq(channel, 3)
39+
40+
task.cancel
41+
channel.close
42+
Marmot.stop
43+
end
44+
45+
it "runs on first run if specified" do
46+
channel = Channel(Int32).new
47+
48+
x = 0
49+
task = Marmot.repeat(10.milliseconds, true) do
50+
x += 1
51+
channel.send(x)
52+
end
53+
spawn Marmot.run
54+
55+
sleep 5.milliseconds
56+
expect_channel_eq(channel, 1)
57+
58+
task.cancel
59+
channel.close
60+
Marmot.stop
61+
end
62+
end
63+
64+
describe "#cron" do
65+
it "schedules a new task" do
66+
channel = Channel(Int32).new
67+
68+
time = Time.local.at_beginning_of_second + 2.second
69+
task = Marmot.cron(time.hour, time.minute, time.second) { channel.send(1) }
70+
spawn Marmot.run
71+
72+
sleep (time - Time.local + 5.milliseconds)
73+
expect_channel_eq(channel, 1)
74+
75+
task.cancel
76+
channel.close
77+
Marmot.stop
78+
end
79+
end
80+
81+
describe "#run" do
82+
it "runs a task without arguments" do
83+
channel = Channel(Int32).new
84+
85+
task = Marmot.repeat(3.milliseconds) { channel.send(1) }
86+
spawn Marmot.run
87+
88+
sleep 5.milliseconds
89+
expect_channel_eq(channel, 1)
90+
91+
task.cancel
92+
channel.close
93+
Marmot.stop
94+
end
95+
96+
it "runs a task with one argument and gives it its Task object" do
97+
channel = Channel(Marmot::Task).new
98+
99+
task = Marmot.repeat(3.milliseconds) { |t| channel.send(t) }
100+
spawn Marmot.run
101+
102+
sleep 5.milliseconds
103+
expect_channel_be(channel, task)
104+
105+
task.cancel
106+
channel.close
107+
Marmot.stop
108+
end
109+
110+
it "stops canceled tasks" do
111+
channel = Channel(Marmot::Task).new
112+
113+
task = Marmot.repeat(3.milliseconds) do |t|
114+
t.cancel
115+
channel.close
116+
end
117+
spawn Marmot.run
118+
119+
sleep 5.milliseconds
120+
channel.closed?.should be_true
121+
task.canceled?.should be_true
122+
123+
Marmot.stop
124+
end
125+
126+
it "does not run when there is no tasks" do
127+
channel = Channel(Int32).new
128+
129+
task = Marmot.repeat(1.milliseconds) { }
130+
task.cancel
131+
132+
spawn do
133+
Marmot.run
134+
channel.send(1)
135+
end
136+
137+
Fiber.yield
138+
expect_channel_eq(channel, 1)
139+
channel.close
140+
end
141+
end
142+
143+
describe "#stop" do
144+
it "stops the tasks but does not cancel them" do
145+
channel = Channel(Int32).new
146+
147+
task = Marmot.repeat(10.milliseconds) { channel.send(1) }
148+
spawn do
149+
Marmot.run
150+
channel.send(2)
151+
end
152+
153+
sleep 15.milliseconds
154+
expect_channel_eq(channel, 1)
155+
156+
Marmot.stop
157+
Fiber.yield
158+
expect_channel_eq(channel, 2)
159+
160+
task.canceled?.should be_false
161+
end
162+
end
163+
end

spec/spec_helper.cr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require "spec"
2+
require "../src/marmot"

0 commit comments

Comments
 (0)