ngauthier-active-listener 0.3.0 → 0.3.2

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.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :major: 0
3
2
  :minor: 3
4
- :patch: 0
3
+ :patch: 2
4
+ :major: 0
@@ -1,9 +1,23 @@
1
1
  require 'fileutils'
2
2
  require 'yaml'
3
3
 
4
+ # =ActiveListener
5
+ # Set up an activelistener config file in your config directory describing the
6
+ # tasks #ActiveListener should execute. Then, in an initializer, run
7
+ # #ActiveListener.autostart
4
8
  class ActiveListener
9
+ # All the #Events that an #ActiveListener is firing
5
10
  attr_reader :events
6
11
 
12
+ # Run #autostart in an initializer to run #ActiveListener when your
13
+ # Rails application initializes.
14
+ #
15
+ # ActiveListener.autostart(
16
+ # :config => File.join(RAILS_ROOT, 'config', 'active-listener.yml'),
17
+ # :pid_file => File.join(RAILS_ROOT, 'log', 'active-listener-'+RAILS_ENV+'.pid'),
18
+ # :log_file => File.join(RAILS_ROOT, 'log', 'active-listener-'+RAILS_ENV+'.log'),
19
+ # :rake_root => RAILS_ROOT
20
+ # )
7
21
  def self.autostart(opts = {})
8
22
  begin
9
23
  config_file = File.expand_path(opts[:config])
@@ -22,30 +36,47 @@ class ActiveListener
22
36
  "--",
23
37
  "#{config_file}",
24
38
  "#{log_file}",
25
- "#{rake_root}"
39
+ "#{rake_root}",
26
40
  ].join(" ")
27
41
  `#{command}`
28
42
  end
29
43
 
44
+ # Stop an #ActiveListener by specifying a pid file
45
+ #
46
+ # ActiveListener.stop(:pid_file => File.join(RAILS_ROOT, 'log', 'active-listener.pid'))
30
47
  def self.stop(opts = {})
31
48
  pid_file = opts[:pid_file]
32
49
  `start-stop-daemon --stop --oknodo --pidfile #{File.expand_path(pid_file)}`
33
50
  end
34
51
 
52
+ # Create an #ActiveListener in the foreground. This is useful for a non-rails project.
53
+ #
54
+ # ActiveListener.new(
55
+ # :log_file => File.join('log', 'active-listener.log'),
56
+ # :rake_root => '.'
57
+ # )
35
58
  def initialize(opts = {})
36
59
  self.events = []
37
60
  self.log_file = opts[:log_file]
38
61
  self.rake_root = opts[:rake_root]
39
62
  clear_log
40
63
  log("ActiveListener Initialized")
41
- load_events(opts[:config])
64
+ load_config(opts[:config])
42
65
  end
43
66
 
67
+ # Add an event to event listener.
68
+ #
69
+ # @al.add_event(Event.new(:task => 'my_task', :period => '10'))
44
70
  def add_event(evt)
45
71
  self.events.push(evt)
46
72
  log("Added Event #{evt.inspect}")
47
73
  end
48
74
 
75
+ # Fire any events that have passed their period
76
+ #
77
+ # @al.fire_events
78
+ #
79
+ # This will only fire events that have not been run within their period time of their last run
49
80
  def fire_events
50
81
  self.events.select{|e| e.time_to_fire < 0}.each do |evt|
51
82
  log("Firing event: #{evt.inspect}")
@@ -54,6 +85,10 @@ class ActiveListener
54
85
  self.events.sort{|x,y| x.time_to_fire <=> y.time_to_fire}
55
86
  end
56
87
 
88
+ # Returns the time in seconds until the next event needs to be fired. Useful for sleeping
89
+ #
90
+ # sleep(@al.time_to_next_event)
91
+ # @al.fire_events
57
92
  def time_to_next_event
58
93
  if self.events.first
59
94
  sleep_time = self.events.first.time_to_fire+0.01
@@ -63,22 +98,37 @@ class ActiveListener
63
98
  return sleep_time
64
99
  end
65
100
 
66
- def sleep_to_next_event
67
- log("Sleeping for #{time_to_next_event}")
68
- sleep(time_to_next_event)
101
+ # Not functional yet.
102
+ def self.trigger(port, event)
103
+
69
104
  end
70
105
 
106
+ # An individual #ActiveListener #Event
71
107
  class Event
108
+ # Create a new #Event
109
+ #
110
+ # Event.new(
111
+ # :task => 'my:rake:task',
112
+ # :period => 50
113
+ # )
72
114
  def initialize(opts = {})
73
115
  self.task = opts[:task] || opts["task"]
74
116
  self.period = opts[:period] || opts["period"]
117
+ self.trigger = opts[:trigger] || opts["trigger"]
75
118
  self.last_fire = Time.now.to_f
76
119
  end
77
120
 
121
+ # The amount of time until this event will need to be fired
78
122
  def time_to_fire
79
- last_fire + period - Time.now.to_f
123
+ if period
124
+ return last_fire + period - Time.now.to_f
125
+ else
126
+ # oh does! forever!
127
+ return 1.0/0.0
128
+ end
80
129
  end
81
130
 
131
+ # Fire the event. I.e. run the rake task
82
132
  def fire(opts = {})
83
133
  self.last_fire = Time.now.to_f
84
134
  Dir.chdir(opts[:rake_root]) if opts[:rake_root]
@@ -89,18 +139,43 @@ class ActiveListener
89
139
  end
90
140
  end
91
141
 
142
+ # Manual firing trigger (not implemented)
143
+ attr_reader :trigger
144
+ # The amount of time in seconds between firing this task
145
+ attr_reader :period
146
+ # The last time this event was fired
147
+ attr_reader :last_fire
148
+ # A string representation of a rake task. "my:task"
149
+ attr_reader :task
150
+
92
151
  private
93
152
 
94
- attr_accessor :task, :period, :last_fire
153
+ # Set the rake task
154
+ attr_writer :task
155
+ # Set the period
156
+ attr_writer :period
157
+ # Set the trigger
158
+ attr_writer :trigger
159
+ # Set last_fire time
160
+ attr_writer :last_fire
95
161
 
96
162
  end
97
163
 
98
164
  private
99
165
 
166
+ # Set the events this #ActiveListener has
100
167
  attr_writer :events
101
- attr_accessor :log_file, :rake_root
102
-
103
- def load_events(config_file)
168
+ # Log file path
169
+ attr_accessor :log_file
170
+ # Directory to run rake tasks from
171
+ attr_accessor :rake_root
172
+ # Port for triggers (not implemented)
173
+ attr_accessor :port
174
+
175
+ # Parse a config file to load up events.
176
+ #
177
+ # @al.load_config('active-listener.yml')
178
+ def load_config(config_file)
104
179
  return if config_file.nil?
105
180
  unless File.exists?(config_file)
106
181
  log("Config file not found at #{config_file}")
@@ -112,13 +187,21 @@ class ActiveListener
112
187
  yml["tasks"].each do |task|
113
188
  self.add_event(Event.new(task))
114
189
  end
190
+ port = yml["port"]
191
+ # puts "The port: #{port}"
192
+ if port
193
+ self.port = port
194
+ spawn_listener_thread
195
+ end
115
196
  end
116
197
 
198
+ # Delete the log file
117
199
  def clear_log
118
200
  return unless log_file
119
201
  FileUtils.rm_f log_file
120
202
  end
121
-
203
+
204
+ # Log text to the log file
122
205
  def log(text)
123
206
  return unless log_file
124
207
  f = File.new(log_file, 'a')
@@ -127,4 +210,17 @@ class ActiveListener
127
210
  f.close
128
211
  end
129
212
 
213
+ # Trigger an event (not implemented)
214
+ def trigger(trigger)
215
+ self.events.select{|e| e.trigger == trigger}.each do |evt|
216
+ log("Event triggered: #{evt.inspect}")
217
+ log(evt.fire(:rake_root => rake_root))
218
+ end
219
+ end
220
+
221
+ # Listen on a port for triggers (not implemented)
222
+ def spawn_listener_thread
223
+ # puts "Hey a port! #{port}"
224
+ end
225
+
130
226
  end
@@ -0,0 +1,5 @@
1
+ ---
2
+ tasks:
3
+ - task: test:touch_file
4
+ trigger: MY_TRIGGER
5
+ port: 20150
@@ -23,7 +23,7 @@ class ActiveListenerTest < Test::Unit::TestCase
23
23
  end
24
24
 
25
25
  should "sleep when it has no events" do
26
- @al.sleep_to_next_event
26
+ sleep(@al.time_to_next_event)
27
27
  end
28
28
 
29
29
  context "with a file timer" do
@@ -44,7 +44,7 @@ class ActiveListenerTest < Test::Unit::TestCase
44
44
 
45
45
  should "touch a file" do
46
46
  assert !File.exists?(@sample_file)
47
- @al.sleep_to_next_event
47
+ sleep(@al.time_to_next_event)
48
48
  @al.fire_events
49
49
  assert File.exists?(@sample_file)
50
50
  end
@@ -59,7 +59,7 @@ class ActiveListenerTest < Test::Unit::TestCase
59
59
  FileUtils.rm_f(@sample_file)
60
60
  @al.fire_events
61
61
  assert !File.exists?(@sample_file)
62
- @al.sleep_to_next_event
62
+ sleep(@al.time_to_next_event)
63
63
  assert @al.events[0].time_to_fire < 0
64
64
  assert !File.exists?(@sample_file)
65
65
  @al.fire_events
@@ -81,7 +81,7 @@ class ActiveListenerTest < Test::Unit::TestCase
81
81
  @al = ActiveListener.new(:config => @config_path)
82
82
  assert @al.events.size > 0
83
83
  assert !File.exists?(@sample_file)
84
- @al.sleep_to_next_event
84
+ sleep(@al.time_to_next_event)
85
85
  @al.fire_events
86
86
  assert File.exists?(@sample_file)
87
87
  end
@@ -160,6 +160,60 @@ class ActiveListenerTest < Test::Unit::TestCase
160
160
  end
161
161
  end
162
162
 
163
+ context "An event-based listener" do
164
+
165
+ setup do
166
+ @al = ActiveListener.new({})
167
+ @al.add_event(ActiveListener::Event.new(
168
+ :task => 'test:touch_file',
169
+ :trigger => "MY_TRIGGER"
170
+ ))
171
+ @sample_file = File.join(File.dirname(__FILE__),'sample.txt')
172
+ FileUtils.rm_f @sample_file
173
+ end
174
+
175
+ teardown do
176
+ FileUtils.rm_f @sample_file
177
+ end
178
+
179
+ should "not fire any events at the beginning" do
180
+ assert !File.exists?(@sample_file)
181
+ assert @al.time_to_next_event.infinite?
182
+ @al.fire_events
183
+ assert !File.exists?(@sample_file)
184
+ end
185
+ end
186
+
187
+ context "An auto-started event based listener" do
188
+ setup do
189
+ ActiveListener.stop(
190
+ :pid_file => File.join(File.dirname(__FILE__), 'active_listener.pid')
191
+ )
192
+ sleep(0.5)
193
+ ActiveListener.autostart(
194
+ :config => File.join(File.dirname(__FILE__), 'active_listener-events.yml'),
195
+ :pid_file => File.join(File.dirname(__FILE__), 'active_listener.pid'),
196
+ :log_file => File.join(File.dirname(__FILE__), 'active_listener.log'),
197
+ :rake_root => File.join(File.dirname(__FILE__), '..')
198
+ )
199
+ @sample_file = File.join(File.dirname(__FILE__),'sample.txt')
200
+ end
201
+
202
+ teardown do
203
+ ActiveListener.stop(
204
+ :pid_file => File.join(File.dirname(__FILE__), 'active_listener.pid')
205
+ )
206
+ sleep(1)
207
+ FileUtils.rm_f(File.join(File.dirname(__FILE__),'sample.txt'))
208
+ end
209
+
210
+ should "be able to be triggered" do
211
+ #assert !File.exists?(@sample_file)
212
+ #ActiveListener.trigger(20150,"MY_TRIGGER")
213
+ #assert File.exists?(@sample_file)
214
+ end
215
+ end
216
+
163
217
  private
164
218
 
165
219
  def pid_running(pid)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngauthier-active-listener
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Gauthier
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-09 00:00:00 -08:00
12
+ date: 2009-02-12 00:00:00 -08:00
13
13
  default_executable: active-listener
14
14
  dependencies: []
15
15
 
@@ -23,12 +23,12 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - VERSION.yml
26
- - README.html
27
26
  - README.markdown
28
27
  - bin/active-listener
29
28
  - lib/activelistener
30
29
  - lib/active-listener.rb
31
30
  - test/test_helper.rb
31
+ - test/active_listener-events.yml
32
32
  - test/active_listener.log
33
33
  - test/active_listener.pid
34
34
  - test/active_listener.yml