chrono_trigger 0.2.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +167 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +89 -0
  6. data/Rakefile +4 -25
  7. data/SUMMARY.md +5 -0
  8. data/bin/console +7 -0
  9. data/bin/loc +3 -0
  10. data/bin/setup +8 -0
  11. data/bin/standardize +4 -0
  12. data/lib/chrono_trigger.rb +29 -8
  13. data/lib/chrono_trigger/clock.rb +50 -0
  14. data/lib/chrono_trigger/config.rb +12 -0
  15. data/lib/chrono_trigger/event.rb +105 -0
  16. data/lib/chrono_trigger/helpers/mitf.rb +19 -0
  17. data/lib/chrono_trigger/helpers/now.rb +12 -0
  18. data/lib/chrono_trigger/schedule.rb +68 -0
  19. data/lib/chrono_trigger/timeline.rb +14 -0
  20. data/lib/chrono_trigger/version.rb +5 -0
  21. data/lib/chrono_trigger/worker.rb +10 -0
  22. metadata +170 -54
  23. data/History.txt +0 -17
  24. data/Manifest.txt +0 -24
  25. data/PostInstall.txt +0 -1
  26. data/README.rdoc +0 -61
  27. data/VERSION.yml +0 -4
  28. data/bin/chrono_trigger +0 -7
  29. data/chrono_trigger.gemspec +0 -69
  30. data/lib/chrono_trigger/cron_entry.rb +0 -71
  31. data/lib/chrono_trigger/process.rb +0 -37
  32. data/lib/chrono_trigger/runner.rb +0 -292
  33. data/lib/chrono_trigger/shell.rb +0 -36
  34. data/lib/chrono_trigger/tasks.rb +0 -3
  35. data/lib/chrono_trigger/trigger.rb +0 -127
  36. data/lib/tasks/chrono_trigger.rake +0 -14
  37. data/lib/triggers/test_triggers.rb +0 -31
  38. data/script/console +0 -10
  39. data/script/destroy +0 -14
  40. data/script/generate +0 -14
  41. data/test/test_chrono_trigger.rb +0 -11
  42. data/test/test_cron_entry.rb +0 -198
  43. data/test/test_helper.rb +0 -14
  44. data/test/test_shell.rb +0 -52
  45. data/test/test_trigger.rb +0 -172
  46. data/test/triggers.rb +0 -17
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ class Config
5
+ include Singleton
6
+ attr_accessor :interval
7
+
8
+ def initialize
9
+ @interval = 0.1
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ class Event
5
+ class << self
6
+ def schedule(*args)
7
+ id = SecureRandom.uuid
8
+ options = OpenStruct.new(
9
+ id: id,
10
+ scope: @scope,
11
+ repeats: @repeats || 1,
12
+ every: @every || 1.second,
13
+ at: @at,
14
+ before: @before,
15
+ after: @after
16
+ )
17
+ new(options, args)
18
+ end
19
+
20
+ def scope(value)
21
+ return self unless value
22
+ @scope = value if value.is_a?(String)
23
+ @scope = value.to_gid.to_s if value.is_a?(ActiveRecord::Base)
24
+ self
25
+ end
26
+
27
+ def repeats(value)
28
+ return self unless value
29
+ @repeats = value.count if value.is_a?(Enumerator)
30
+ @repeats = value if value.is_a?(Integer) || value == :forever
31
+ self
32
+ end
33
+
34
+ def every(value)
35
+ return self unless value
36
+ @every = value if value.is_a?(ActiveSupport::Duration)
37
+ @every = value.seconds if value.is_a?(Integer)
38
+ self
39
+ end
40
+
41
+ def at(value)
42
+ return self unless value
43
+ value = Time.zone.parse(value) if value.is_a?(String)
44
+ @at = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
45
+ puts @at.class
46
+ self
47
+ end
48
+
49
+ def before(value)
50
+ return self unless value
51
+ value = Time.zone.parse(value) if value.is_a?(String)
52
+ @before = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
53
+ self
54
+ end
55
+
56
+ def after(value)
57
+ return self unless value
58
+ value = Time.zone.parse(value) if value.is_a?(String)
59
+ @after = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
60
+ self
61
+ end
62
+
63
+ private
64
+
65
+ include ChronoTrigger::Helpers::MITF
66
+ end
67
+
68
+ attr_reader :id, :scope, :args, :every, :before, :after, :purge
69
+ attr_accessor :repeats, :at
70
+
71
+ def initialize(options, args)
72
+ @id = options.id
73
+ @scope = options.scope
74
+ @repeats = options.repeats
75
+ @every = options.every
76
+ @at = options.at
77
+ @before = options.before
78
+ @after = options.after
79
+ @args = args
80
+ @purge = false
81
+ ChronoTrigger.schedule.add(self)
82
+ end
83
+
84
+ def ticks
85
+ ChronoTrigger::Clock.ticks
86
+ end
87
+
88
+ def purge!
89
+ @purge = true
90
+ end
91
+
92
+ include ChronoTrigger::Helpers::MITF
93
+ include ChronoTrigger::Helpers::Now
94
+
95
+ def to_s
96
+ inspect
97
+ end
98
+
99
+ private
100
+
101
+ def perform(args)
102
+ raise NotImplementedError
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ module Helpers
5
+ module MITF
6
+ class LostInTimeError < StandardError
7
+ end
8
+
9
+ class TodayIsTomorrowsYesterday < StandardError
10
+ end
11
+
12
+ def moment_in_the_future(time_with_zone)
13
+ raise(LostInTimeError, "Argument must be of type ActiveSupport::TimeWithZone eg. right_now + 1.second") unless time_with_zone.is_a?(ActiveSupport::TimeWithZone)
14
+ raise(TodayIsTomorrowsYesterday, "Time must be in the future eg. 1.second.from_now") unless time_with_zone.future?
15
+ Time.zone.today + time_with_zone.hour.hours + time_with_zone.min.minutes + time_with_zone.sec.seconds
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ module Helpers
5
+ module Now
6
+ def right_now
7
+ now = Time.zone.now
8
+ Time.zone.today + now.hour.hours + now.min.minutes + now.sec.seconds
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ class Schedule
5
+ include Singleton
6
+ attr_reader :events
7
+
8
+ def initialize
9
+ @events = Concurrent::Array.new
10
+ @pool = Concurrent::Actor::Utils::Pool.spawn! "pool", 5 do |index|
11
+ Rails.logger.info "ChronoTrigger: Spawning worker schedule-#{index}"
12
+ ChronoTrigger::Worker.spawn name: "schedule-#{index}", supervise: true, args: []
13
+ end
14
+ end
15
+
16
+ def add(event)
17
+ @events << event if event&.is_a?(ChronoTrigger::Event)
18
+ self
19
+ end
20
+
21
+ def remove(uuid)
22
+ uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
23
+ @events.each { |event| event.purge! if event.id == uuid } if uuid && uuid_regex.match?(uuid.to_s.downcase)
24
+ self
25
+ end
26
+
27
+ def clear
28
+ @events.each { |event| event.purge! }
29
+ self
30
+ end
31
+
32
+ def clear_scope(value)
33
+ return self unless value
34
+ scope = value if value.is_a?(String)
35
+ scope = value.to_gid.to_s if value.is_a?(ActiveRecord::Base)
36
+ @events.each { |event| event.purge! if event.scope == scope }
37
+ self
38
+ end
39
+
40
+ def process_events
41
+ now = right_now
42
+ events.each do |event|
43
+ if event.purge || (event.before && now >= event.before) || event.repeats == 0
44
+ @events.delete(event)
45
+ next
46
+ end
47
+ next if event.after && now < event.after
48
+ if event.at.nil? || event.at == now
49
+ @pool << event
50
+ event.at = now + event.every
51
+ event.repeats -= 1 unless event.repeats == :forever
52
+ end
53
+ end
54
+ end
55
+
56
+ def refresh
57
+ now = right_now
58
+ events.each do |event|
59
+ next if event.at.nil?
60
+ event.at = nil if event.at < now
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ include ChronoTrigger::Helpers::Now
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ module Timeline
5
+ extend ::ActiveSupport::Concern
6
+
7
+ def chrono_trigger
8
+ ChronoTrigger::Schedule.instance
9
+ end
10
+
11
+ include ChronoTrigger::Helpers::MITF
12
+ include ChronoTrigger::Helpers::Now
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ VERSION = "1.0.3"
5
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ class Worker < Concurrent::Actor::RestartingContext
5
+ def on_message(event)
6
+ Rails.logger.debug "ChronoTrigger: #{event.inspect}"
7
+ event.perform(*event.args) if event.at.nil? || (event.at && event.before.nil?) || (event.before && event.at < event.before)
8
+ end
9
+ end
10
+ end
metadata CHANGED
@@ -1,79 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrono_trigger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 1.0.3
6
5
  platform: ruby
7
6
  authors:
8
- - Jon Ciccone
7
+ - leastbad
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-10 00:00:00.000000000 Z
13
- dependencies: []
14
- description: c
15
- email: darful@gmail.com
16
- executables:
17
- - chrono_trigger
11
+ date: 2021-04-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.1.8
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.1'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.1.8
47
+ - !ruby/object:Gem::Dependency
48
+ name: concurrent-ruby-edge
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.6'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.6.0
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '0.6'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 0.6.0
67
+ - !ruby/object:Gem::Dependency
68
+ name: magic_frozen_string_literal
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: 1.2.0
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: 1.2.0
81
+ - !ruby/object:Gem::Dependency
82
+ name: pry
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '0.12'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '0.12'
95
+ - !ruby/object:Gem::Dependency
96
+ name: pry-nav
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '0.3'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '0.3'
109
+ - !ruby/object:Gem::Dependency
110
+ name: rake
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '13.0'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 13.0.3
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '13.0'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 13.0.3
129
+ - !ruby/object:Gem::Dependency
130
+ name: standardrb
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '1.0'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '1.0'
143
+ description:
144
+ email:
145
+ - hello@leastbad.com
146
+ executables: []
18
147
  extensions: []
19
- extra_rdoc_files:
20
- - README.rdoc
148
+ extra_rdoc_files: []
21
149
  files:
22
- - History.txt
23
- - Manifest.txt
24
- - PostInstall.txt
25
- - README.rdoc
150
+ - Gemfile
151
+ - Gemfile.lock
152
+ - LICENSE.txt
153
+ - README.md
26
154
  - Rakefile
27
- - VERSION.yml
28
- - bin/chrono_trigger
29
- - chrono_trigger.gemspec
155
+ - SUMMARY.md
156
+ - bin/console
157
+ - bin/loc
158
+ - bin/setup
159
+ - bin/standardize
30
160
  - lib/chrono_trigger.rb
31
- - lib/chrono_trigger/cron_entry.rb
32
- - lib/chrono_trigger/process.rb
33
- - lib/chrono_trigger/runner.rb
34
- - lib/chrono_trigger/shell.rb
35
- - lib/chrono_trigger/tasks.rb
36
- - lib/chrono_trigger/trigger.rb
37
- - lib/tasks/chrono_trigger.rake
38
- - lib/triggers/test_triggers.rb
39
- - script/console
40
- - script/destroy
41
- - script/generate
42
- - test/test_chrono_trigger.rb
43
- - test/test_cron_entry.rb
44
- - test/test_helper.rb
45
- - test/test_shell.rb
46
- - test/test_trigger.rb
47
- - test/triggers.rb
48
- homepage: https://rubygems.org/gems/chrono_trigger
49
- licenses: []
161
+ - lib/chrono_trigger/clock.rb
162
+ - lib/chrono_trigger/config.rb
163
+ - lib/chrono_trigger/event.rb
164
+ - lib/chrono_trigger/helpers/mitf.rb
165
+ - lib/chrono_trigger/helpers/now.rb
166
+ - lib/chrono_trigger/schedule.rb
167
+ - lib/chrono_trigger/timeline.rb
168
+ - lib/chrono_trigger/version.rb
169
+ - lib/chrono_trigger/worker.rb
170
+ homepage: https://chronotrigger.leastbad.com/
171
+ licenses:
172
+ - MIT
173
+ metadata:
174
+ source_code_uri: https://github.com/leastbad/chrono_trigger
175
+ documentation_uri: https://chronotrigger.leastbad.com/
50
176
  post_install_message:
51
- rdoc_options:
52
- - --charset=UTF-8
177
+ rdoc_options: []
53
178
  require_paths:
54
179
  - lib
55
180
  required_ruby_version: !ruby/object:Gem::Requirement
56
- none: false
57
181
  requirements:
58
- - - ! '>='
182
+ - - ">="
59
183
  - !ruby/object:Gem::Version
60
184
  version: '0'
61
185
  required_rubygems_version: !ruby/object:Gem::Requirement
62
- none: false
63
186
  requirements:
64
- - - ! '>='
187
+ - - ">="
65
188
  - !ruby/object:Gem::Version
66
189
  version: '0'
67
190
  requirements: []
68
- rubyforge_project:
69
- rubygems_version: 1.8.24
191
+ rubygems_version: 3.1.4
70
192
  signing_key:
71
- specification_version: 3
72
- summary: A cron framework for defining cron tasks using a readable DSL.
73
- test_files:
74
- - test/test_chrono_trigger.rb
75
- - test/test_cron_entry.rb
76
- - test/test_helper.rb
77
- - test/test_shell.rb
78
- - test/test_trigger.rb
79
- - test/triggers.rb
193
+ specification_version: 4
194
+ summary: A clock-based scheduler that runs inside your Rails app.
195
+ test_files: []