ngauthier-active-listener 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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