chrono_trigger 0.2.1 → 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cbca0c2caa1b69582cd2e5e35bb6df578b9ae913d2da07f8e3b84d76c812ade7
4
+ data.tar.gz: 02c0808b8df6dc06be2aa7c8812f1cac72bfb53192c97acb0ba9ba6a48f5225e
5
+ SHA512:
6
+ metadata.gz: 016a3b4aacbf0c960de0c17885287eb4505da012d130eb6c0ea9a96cd4098d1848cc37af9072d4907816e3c25bc6d2f712ef0f449245cff598020cad6bea184d
7
+ data.tar.gz: dfb36735721ce71346ac77bbd0a031f91ffa98082850f89fc1d201a5dafe6de0875cfe36fa6c95f6b39b3233593b5e0006c3bc6792eb2d887991fc19806f74c6
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in cable_ready.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,167 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chrono_trigger (1.0.0)
5
+ concurrent-ruby (~> 1.1, >= 1.1.8)
6
+ concurrent-ruby-edge (~> 0.6, >= 0.6.0)
7
+ rails (~> 5.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actioncable (5.2.5)
13
+ actionpack (= 5.2.5)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ actionmailer (5.2.5)
17
+ actionpack (= 5.2.5)
18
+ actionview (= 5.2.5)
19
+ activejob (= 5.2.5)
20
+ mail (~> 2.5, >= 2.5.4)
21
+ rails-dom-testing (~> 2.0)
22
+ actionpack (5.2.5)
23
+ actionview (= 5.2.5)
24
+ activesupport (= 5.2.5)
25
+ rack (~> 2.0, >= 2.0.8)
26
+ rack-test (>= 0.6.3)
27
+ rails-dom-testing (~> 2.0)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
+ actionview (5.2.5)
30
+ activesupport (= 5.2.5)
31
+ builder (~> 3.1)
32
+ erubi (~> 1.4)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
35
+ activejob (5.2.5)
36
+ activesupport (= 5.2.5)
37
+ globalid (>= 0.3.6)
38
+ activemodel (5.2.5)
39
+ activesupport (= 5.2.5)
40
+ activerecord (5.2.5)
41
+ activemodel (= 5.2.5)
42
+ activesupport (= 5.2.5)
43
+ arel (>= 9.0)
44
+ activestorage (5.2.5)
45
+ actionpack (= 5.2.5)
46
+ activerecord (= 5.2.5)
47
+ marcel (~> 1.0.0)
48
+ activesupport (5.2.5)
49
+ concurrent-ruby (~> 1.0, >= 1.0.2)
50
+ i18n (>= 0.7, < 2)
51
+ minitest (~> 5.1)
52
+ tzinfo (~> 1.1)
53
+ arel (9.0.0)
54
+ ast (2.4.2)
55
+ builder (3.2.4)
56
+ coderay (1.1.3)
57
+ concurrent-ruby (1.1.8)
58
+ concurrent-ruby-edge (0.6.0)
59
+ concurrent-ruby (~> 1.1.6)
60
+ crass (1.0.6)
61
+ erubi (1.10.0)
62
+ globalid (0.4.2)
63
+ activesupport (>= 4.2.0)
64
+ i18n (1.8.10)
65
+ concurrent-ruby (~> 1.0)
66
+ loofah (2.9.1)
67
+ crass (~> 1.0.2)
68
+ nokogiri (>= 1.5.9)
69
+ magic_frozen_string_literal (1.2.0)
70
+ mail (2.7.1)
71
+ mini_mime (>= 0.1.1)
72
+ marcel (1.0.1)
73
+ method_source (0.9.2)
74
+ mini_mime (1.1.0)
75
+ minitest (5.14.4)
76
+ nio4r (2.5.7)
77
+ nokogiri (1.11.3-x86_64-linux)
78
+ racc (~> 1.4)
79
+ parallel (1.20.1)
80
+ parser (3.0.0.0)
81
+ ast (~> 2.4.1)
82
+ pry (0.12.2)
83
+ coderay (~> 1.1.0)
84
+ method_source (~> 0.9.0)
85
+ pry-nav (0.3.0)
86
+ pry (>= 0.9.10, < 0.13.0)
87
+ racc (1.5.2)
88
+ rack (2.2.3)
89
+ rack-test (1.1.0)
90
+ rack (>= 1.0, < 3)
91
+ rails (5.2.5)
92
+ actioncable (= 5.2.5)
93
+ actionmailer (= 5.2.5)
94
+ actionpack (= 5.2.5)
95
+ actionview (= 5.2.5)
96
+ activejob (= 5.2.5)
97
+ activemodel (= 5.2.5)
98
+ activerecord (= 5.2.5)
99
+ activestorage (= 5.2.5)
100
+ activesupport (= 5.2.5)
101
+ bundler (>= 1.3.0)
102
+ railties (= 5.2.5)
103
+ sprockets-rails (>= 2.0.0)
104
+ rails-dom-testing (2.0.3)
105
+ activesupport (>= 4.2.0)
106
+ nokogiri (>= 1.6)
107
+ rails-html-sanitizer (1.3.0)
108
+ loofah (~> 2.3)
109
+ railties (5.2.5)
110
+ actionpack (= 5.2.5)
111
+ activesupport (= 5.2.5)
112
+ method_source
113
+ rake (>= 0.8.7)
114
+ thor (>= 0.19.0, < 2.0)
115
+ rainbow (3.0.0)
116
+ rake (13.0.3)
117
+ regexp_parser (2.1.1)
118
+ rexml (3.2.4)
119
+ rubocop (1.11.0)
120
+ parallel (~> 1.10)
121
+ parser (>= 3.0.0.0)
122
+ rainbow (>= 2.2.2, < 4.0)
123
+ regexp_parser (>= 1.8, < 3.0)
124
+ rexml
125
+ rubocop-ast (>= 1.2.0, < 2.0)
126
+ ruby-progressbar (~> 1.7)
127
+ unicode-display_width (>= 1.4.0, < 3.0)
128
+ rubocop-ast (1.4.1)
129
+ parser (>= 2.7.1.5)
130
+ rubocop-performance (1.10.1)
131
+ rubocop (>= 0.90.0, < 2.0)
132
+ rubocop-ast (>= 0.4.0)
133
+ ruby-progressbar (1.11.0)
134
+ sprockets (4.0.2)
135
+ concurrent-ruby (~> 1.0)
136
+ rack (> 1, < 3)
137
+ sprockets-rails (3.2.2)
138
+ actionpack (>= 4.0)
139
+ activesupport (>= 4.0)
140
+ sprockets (>= 3.0.0)
141
+ standard (1.0.4)
142
+ rubocop (= 1.11.0)
143
+ rubocop-performance (= 1.10.1)
144
+ standardrb (1.0.0)
145
+ standard
146
+ thor (1.1.0)
147
+ thread_safe (0.3.6)
148
+ tzinfo (1.2.9)
149
+ thread_safe (~> 0.1)
150
+ unicode-display_width (2.0.0)
151
+ websocket-driver (0.7.3)
152
+ websocket-extensions (>= 0.1.0)
153
+ websocket-extensions (0.1.5)
154
+
155
+ PLATFORMS
156
+ x86_64-linux
157
+
158
+ DEPENDENCIES
159
+ chrono_trigger!
160
+ magic_frozen_string_literal (~> 1.2.0)
161
+ pry (~> 0.12.2)
162
+ pry-nav (~> 0.3.0)
163
+ rake (~> 13.0, >= 13.0.3)
164
+ standardrb (~> 1.0.0)
165
+
166
+ BUNDLED WITH
167
+ 2.2.3
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 leastbad
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.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # Initial page
2
+
data/Rakefile CHANGED
@@ -1,26 +1,4 @@
1
- # %w[rubygems rake rake/clean fileutils newgem rubigen rake/testtask].each { |f| require f }
2
- # require File.dirname(__FILE__) + '/lib/chrono_trigger'
1
+ # frozen_string_literal: true
3
2
 
4
- require 'rake/testtask'
5
-
6
- Rake::TestTask.new do |t|
7
- t.libs << 'test'
8
- end
9
-
10
- desc "Run tests"
11
- task :default => :test
12
-
13
- begin
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |s|
16
- s.name = "chrono_trigger"
17
- s.authors = ["Jon Ciccone"]
18
- s.date = "2013-01-10"
19
- s.summary = "Rails cron jobs."
20
- s.description = "This gem allows you to write, deploy, and maintain cron jobs withing the rails framework."
21
- s.email = "darful@gmail.com"
22
- s.homepage = "https://github.com/darful/chrono_trigger"
23
- end
24
- rescue LoadError
25
- puts "Jeweler not available. Install it with: gem install technicalpickles-jeweler -s http://gems.github.com"
26
- end
3
+ require "bundler/gem_tasks"
4
+ require "pry"
data/SUMMARY.md ADDED
@@ -0,0 +1,4 @@
1
+ # Table of contents
2
+
3
+ * [Initial page](README.md)
4
+
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "chrono_trigger"
5
+ require "pry"
6
+
7
+ Pry.start
data/bin/loc ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ cloc --exclude-dir=node_modules,test --include-ext=rb,js .
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/standardize ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle exec magic_frozen_string_literal
4
+ bundle exec standardrb --fix
@@ -1,14 +1,30 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
1
+ # frozen_string_literal: true
3
2
 
4
- if RUBY_VERSION =~ /1\.8\.6/
5
- require "activerecord"
6
- else
7
- require "active_record"
8
- end
9
-
10
- require 'active_support/all'
3
+ require "rails/engine"
4
+ require "active_support/all"
5
+ require "singleton"
6
+ require "concurrent-edge"
7
+ require "chrono_trigger/clock"
8
+ require "chrono_trigger/config"
9
+ require "chrono_trigger/event"
10
+ require "chrono_trigger/schedule"
11
+ require "chrono_trigger/timeline"
11
12
  require "chrono_trigger/version"
12
- require "chrono_trigger/shell"
13
- require "chrono_trigger/trigger"
14
- require "chrono_trigger/cron_entry"
13
+ require "chrono_trigger/worker"
14
+
15
+ module ChronoTrigger
16
+ class Engine < Rails::Engine
17
+ end
18
+
19
+ def self.config
20
+ ChronoTrigger::Config.instance
21
+ end
22
+
23
+ def self.schedule
24
+ ChronoTrigger::Schedule.instance
25
+ end
26
+
27
+ def self.configure
28
+ yield config
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChronoTrigger
4
+ class Clock
5
+ class << self
6
+ attr_reader :status, :ticks
7
+
8
+ def init
9
+ @ticks = 0
10
+ @status ||= :stopped
11
+ end
12
+
13
+ def start
14
+ init
15
+ if stopped?
16
+ last_tick = Time.zone.now
17
+ Rails.logger.info "ChronoTrigger: Clock started with a #{ChronoTrigger.config.interval}s interval"
18
+ ChronoTrigger.schedule.refresh
19
+ task = Concurrent::TimerTask.new(execution_interval: ChronoTrigger.config.interval) do |task|
20
+ if Time.zone.now - last_tick >= 1
21
+ last_tick += 1
22
+ @ticks += 1
23
+ ChronoTrigger.schedule.process_events
24
+ end
25
+ task.shutdown if stopped?
26
+ end
27
+ task.execute
28
+ end
29
+
30
+ @status = :started
31
+ end
32
+
33
+ def stop
34
+ if ticking?
35
+ Rails.logger.info "ChronoTrigger: Timer stopped"
36
+ @status = :stopped
37
+ end
38
+ @status
39
+ end
40
+
41
+ def ticking?
42
+ @status == :started
43
+ end
44
+
45
+ def stopped?
46
+ @status == :stopped
47
+ end
48
+ end
49
+ end
50
+ end
@@ -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,118 @@
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
+ id
19
+ end
20
+
21
+ def scope(value)
22
+ return self unless value
23
+ @scope = value if value.is_a?(String)
24
+ @scope = value.to_gid.to_s if value.is_a?(ActiveRecord::Base)
25
+ self
26
+ end
27
+
28
+ def repeats(value)
29
+ return self unless value
30
+ @repeats = value.count if value.is_a?(Enumerator)
31
+ @repeats = value if value.is_a?(Integer) || value == :forever
32
+ self
33
+ end
34
+
35
+ def every(value)
36
+ return self unless value
37
+ @every = value if value.is_a?(ActiveSupport::Duration)
38
+ @every = value.seconds if value.is_a?(Integer)
39
+ self
40
+ end
41
+
42
+ def at(value)
43
+ return self unless value
44
+ value = Time.zone.parse(value) if value.is_a?(String)
45
+ @at = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
46
+ puts @at.class
47
+ self
48
+ end
49
+
50
+ def before(value)
51
+ return self unless value
52
+ value = Time.zone.parse(value) if value.is_a?(String)
53
+ @before = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
54
+ self
55
+ end
56
+
57
+ def after(value)
58
+ return self unless value
59
+ value = Time.zone.parse(value) if value.is_a?(String)
60
+ @after = moment_in_the_future(value) if value.is_a?(ActiveSupport::TimeWithZone)
61
+ self
62
+ end
63
+
64
+ private
65
+
66
+ def moment_in_the_future(time_with_zone)
67
+ Time.zone.today + time_with_zone.hour.hours + time_with_zone.min.minutes + time_with_zone.sec.seconds
68
+ end
69
+ end
70
+
71
+ class LostInTimeError < StandardError
72
+ end
73
+
74
+ class TodayIsTomorrowsYesterday < StandardError
75
+ end
76
+
77
+ attr_reader :id, :scope, :args, :every, :before, :after, :purge
78
+ attr_accessor :repeats, :at
79
+
80
+ def initialize(options, args)
81
+ @id = options.id
82
+ @scope = options.scope
83
+ @repeats = options.repeats
84
+ @every = options.every
85
+ @at = options.at
86
+ @before = options.before
87
+ @after = options.after
88
+ @args = args
89
+ @purge = false
90
+ ChronoTrigger.schedule.add(self)
91
+ end
92
+
93
+ def ticks
94
+ ChronoTrigger::Clock.ticks
95
+ end
96
+
97
+ def purge!
98
+ @purge = true
99
+ end
100
+
101
+ def right_now
102
+ now = Time.zone.now
103
+ Time.zone.today + now.hour.hours + now.min.minutes + now.sec.seconds
104
+ end
105
+
106
+ def moment_in_the_future(time_with_zone)
107
+ raise(LostInTimeError, "Argument must be of type ActiveSupport::TimeWithZone eg. right_now + 1.second") unless time_with_zone.is_a?(ActiveSupport::TimeWithZone)
108
+ raise(TodayIsTomorrowsYesterday, "Time must be in the future eg. 1.second.from_now") unless time_with_zone.future?
109
+ Time.zone.today + time_with_zone.hour.hours + time_with_zone.min.minutes + time_with_zone.sec.seconds
110
+ end
111
+
112
+ private
113
+
114
+ def perform(args)
115
+ raise NotImplementedError
116
+ end
117
+ end
118
+ end