swerling-sinotify 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,5 +1,8 @@
1
1
  pkg/
2
+ doc/
3
+ rdoc/
2
4
  ext/Makefile
3
5
  ext/mkmf.log
4
6
  ext/*.o
5
7
  ext/*.so
8
+ *.swp
@@ -1,6 +1,8 @@
1
- sinotify
2
- by Steven Swerling
3
- http://tab-a.slot-z.net
1
+ sinotify
2
+
3
+ by {Steven Swerling}[http://tab-a.slot-z.net]
4
+
5
+ {rdoc}[http://tab-a.slot-z.net] | {github}[http://www.github.com/swerling/sinotify]
4
6
 
5
7
  == DESCRIPTION:
6
8
 
data/README.txt CHANGED
@@ -1,6 +1,8 @@
1
- sinotify
2
- by Steven Swerling
3
- http://tab-a.slot-z.net
1
+ sinotify
2
+
3
+ by {Steven Swerling}[http://tab-a.slot-z.net]
4
+
5
+ {rdoc}[http://tab-a.slot-z.net] | {github}[http://www.github.com/swerling/sinotify]
4
6
 
5
7
  == DESCRIPTION:
6
8
 
@@ -63,10 +65,10 @@ Try this:
63
65
  require 'sinotify'
64
66
  notifier = Sinotify::Notifier.new('/tmp/sinotify_test', :recurse => true, :etypes => [:create, :modify, :delete])
65
67
  notifier.spy!(:logger => Logger.new('/tmp/inotify_spy.log')) # optional event spy
66
- notifier.when_announcing(Sinotify::Event) do |sinotify_event|
68
+ notifier.on_event do |sinotify_event|
67
69
  puts "Event happened at #{sinotify_event.timestamp} on #{sinotify_event.path}, etypes => #{sinotify_event.etypes.inspect}"
68
70
  end
69
- notifier.when_announcing(Sinotify::Event) do |sinotify_event|
71
+ notifier.on_event do |sinotify_event|
70
72
  puts " --> demonstrate that multiple subscribers can be setup: #{sinotify_event.etypes.inspect}"
71
73
  end
72
74
  notifier.watch! # don't forget to start the watch
data/Rakefile CHANGED
@@ -30,21 +30,43 @@ PROJ.spec.opts << '--color'
30
30
  PROJ.rdoc.opts = ["--inline-source"]
31
31
  PROJ.rdoc.exclude = ["^tasks/setup\.rb$", "\.[ch]$"]
32
32
 
33
+
34
+
35
+
36
+
37
+ require 'fileutils'
38
+ def this_dir; File.join(File.dirname(__FILE__)); end
39
+ def doc_dir; File.join(this_dir, 'rdoc'); end
40
+ def ext_dir; File.join(this_dir, 'ext'); end
41
+ def tab_a_doc_dir; File.join(this_dir, '../tab-a/public/sinotify/rdoc'); end
42
+
33
43
  task :default => 'spec:run'
34
44
  task :myclobber => [:clobber] do
35
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'pkg')}"
36
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'doc')}"
37
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.log')}"
38
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.o')}"
39
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.so')}"
40
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/Makefile')}"
45
+ mydir = File.join(File.dirname(__FILE__))
46
+ sh "rm -rf #{File.join(mydir, 'pkg')}"
47
+ sh "rm -rf #{File.join(mydir, 'doc')}"
48
+ sh "rm -rf #{File.join(mydir, 'rdoc')}"
49
+ sh "rm -rf #{File.join(mydir, 'ext/*.log')}"
50
+ sh "rm -rf #{File.join(mydir, 'ext/*.o')}"
51
+ sh "rm -rf #{File.join(mydir, 'ext/*.so')}"
52
+ sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
53
+ sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
41
54
  end
42
55
  task :mypackage => [:myclobber] do
43
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'pkg')}"
44
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'doc')}"
45
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.log')}"
46
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.o')}"
47
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.so')}"
48
56
  Rake::Task['gem:package'].invoke
49
57
  end
50
-
58
+ task :mydoc => [:myclobber] do
59
+ FileUtils.rm_f doc_dir()
60
+ sh "cd #{this_dir()} && rdoc -o rdoc --inline-source --format=html -T hanna README.rdoc lib/**/*.rb"
61
+ end
62
+ task :taba => [:mydoc] do
63
+ this_dir = File.join(File.dirname(__FILE__))
64
+ FileUtils.rm_rf tab_a_doc_dir
65
+ FileUtils.cp_r doc_dir, tab_a_doc_dir
66
+ end
67
+ task :mygemspec => [:myclobber] do
68
+ Rake::Task['gem:spec'].invoke
69
+ end
70
+ task :mybuild => [:myclobber] do
71
+ sh "cd #{ext_dir} && ruby extconf.rb && make"
72
+ end
data/TODO ADDED
@@ -0,0 +1,12 @@
1
+ 1. Refactor Notifier and Event so that other operating systems can be used for prim events.
2
+
3
+ Currently there are couplings between Event and PrimEvent that assume linux (easy to remove),
4
+ and couplings between Notifier and PrimEvent that assume linux (harder to remove, will need
5
+ an adapter class)
6
+
7
+ 2. Batch collate events
8
+
9
+ Currently if you remove or add a directory with lots of files, events are sent out for
10
+ every single file. Would be nice option if a single event listing all the changes went
11
+ out (say, a single event that sponges up all events for 150 milliseconds, then sends them
12
+ off as an array)
@@ -32,7 +32,8 @@ module Sinotify
32
32
  # :etypes =>
33
33
  # which inotify file system event types to listen for (eg :create, :delete, etc)
34
34
  # See docs for Sinotify::Event for list of event types.
35
- # default is :all_types
35
+ # default is [:create, :modify, :delete]
36
+ # Use :all_events to trace everything (although this may be more than you bargained for).
36
37
  #
37
38
  # :logger =>
38
39
  # Where to log errors to. Default is Logger.new(STDOUT).
@@ -60,7 +61,7 @@ module Sinotify
60
61
  # how many directories at a time to register.
61
62
  self.recurse_throttle = opts[:recurse_throttle] || 10
62
63
 
63
- self.etypes = Array(opts[:etypes] || :all_events)
64
+ self.etypes = Array( opts[:etypes] || [:create, :modify, :delete] )
64
65
  validate_etypes!
65
66
 
66
67
  self.prim_notifier = Sinotify::PrimNotifier.new
@@ -70,7 +71,7 @@ module Sinotify
70
71
  sleep_time = opts[:announcements_sleep_time] || 0.05
71
72
  announcement_throttle = opts[:announcement_throttle] || 50
72
73
  self.queue_announcements!(:sleep_time => sleep_time,
73
- :logger => opts[:logger],
74
+ :logger => @logger,
74
75
  :announcements_per_cycle => announcement_throttle)
75
76
 
76
77
  self.closed = false
@@ -81,6 +82,24 @@ module Sinotify
81
82
  @spy_logger_level = nil
82
83
  @watch_thread = nil
83
84
  end
85
+
86
+ # Sugar.
87
+ #
88
+ # Equivalent of calling cosell's
89
+ #
90
+ # self.when_announcing(Sinotify::Event) do |event|
91
+ # do_something_with_event(event)
92
+ # end
93
+ #
94
+ # becomes
95
+ #
96
+ # self.on_event { |event| do_something_with_event(event) }
97
+ #
98
+ # Since this class only announces one kind of event, it made sense to
99
+ # provide a more terse version of that statement.
100
+ def on_event &block
101
+ self.when_announcing(Sinotify::Event, &block)
102
+ end
84
103
 
85
104
  # whether this watch is on a directory
86
105
  def on_directory?
@@ -108,10 +127,12 @@ module Sinotify
108
127
  # Options:
109
128
  # :logger => The log to log to. Default is a logger on STDOUT
110
129
  # :level => The log level to log with. Default is :info
130
+ # :spy_on_prim_events => Spy on PrimEvents (raw inotify events) too
111
131
  #
112
132
  def spy!(opts = {})
113
- @spy_logger = opts[:logger] || Logger.new(STDOUT)
114
- @spy_logger_level = opts[:level] || :info
133
+ self.spy_on_prim_events = opts[:spy_on_prim_events].eql?(true)
134
+ self.spy_logger = opts[:logger] || Logger.new(STDOUT)
135
+ self.spy_logger_level = opts[:level] || :info
115
136
  opts[:on] = Sinotify::Event
116
137
  opts[:preface_with] = "Sinotify::Notifier Event Spy"
117
138
  super(opts)
@@ -141,6 +162,8 @@ module Sinotify
141
162
 
142
163
  #:stopdoc:
143
164
 
165
+ attr_accessor :spy_on_prim_events, :spy_logger, :spy_logger_level
166
+
144
167
  def validate_etypes!
145
168
  bad = self.etypes.detect{|etype| PrimEvent.mask_from_etype(etype).nil? }
146
169
  raise "Unrecognized etype '#{bad}'. Please see valid list in docs for Sinotify::Event" if bad
@@ -229,13 +252,6 @@ module Sinotify
229
252
  self.logger.send(level, msg) if self.logger
230
253
  end
231
254
 
232
- def spy_on_event(prim_event)
233
- if @spy_logger
234
- msg = "Sinotify::Notifier Prim Event Spy: #{prim_event.inspect}"
235
- @spy_logger.send(@spy_logger_level, msg)
236
- end
237
- end
238
-
239
255
  # Listen for linux inotify events, and as they come in
240
256
  # 1. adapt them into Sinotify::Event objects
241
257
  # 2. 'announce' them using Cosell.
@@ -255,9 +271,9 @@ module Sinotify
255
271
  self.prim_notifier.each_event do |prim_event|
256
272
  watch = self.watches[prim_event.watch_descriptor.to_s]
257
273
  if event_is_noise?(prim_event, watch)
258
- @spy_logger.debug("Sinotify::Notifier Spy: Skipping noise[#{prim_event.inspect}]") if @spy_logger
274
+ self.spy_logger.debug("Sinotify::Notifier Spy: Skipping noise[#{prim_event.inspect}]") if self.spy_on_prim_events
259
275
  else
260
- spy_on_event(prim_event)
276
+ spy_on_prim_event(prim_event)
261
277
  if watch.nil?
262
278
  self.log "Could not determine watch from descriptor #{prim_event.watch_descriptor}, something is wrong. Event: #{prim_event.inspect}", :warn
263
279
  else
@@ -294,6 +310,13 @@ module Sinotify
294
310
  @raw_mask
295
311
  end
296
312
 
313
+ def spy_on_prim_event(prim_event)
314
+ if self.spy_on_prim_events
315
+ msg = "Sinotify::Notifier Prim Event Spy: #{prim_event.inspect}"
316
+ self.spy_logger.send(@spy_logger_level, msg)
317
+ end
318
+ end
319
+
297
320
  # ruby gives warnings in verbose mode if you use attr_accessor to set these next few:
298
321
  def prim_notifier; @prim_notifier; end
299
322
  def prim_notifier= x; @prim_notifier = x; end
@@ -60,10 +60,6 @@ module Sinotify
60
60
  @@etype_to_mask_map = {}
61
61
  @@mask_to_etype_map.each{|k,v| @@etype_to_mask_map[v] = k}
62
62
 
63
- # def self.etype_from_mask(mask)
64
- # @@mask_to_etype_map[mask]
65
- # end
66
-
67
63
  def self.etype_from_mask(mask)
68
64
  @@mask_to_etype_map[mask]
69
65
  end
@@ -1,6 +1,6 @@
1
1
  module Sinotify
2
2
 
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
 
5
5
  # :stopdoc:
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{sinotify}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Steven Swerling"]
9
- s.date = %q{2009-07-19}
9
+ s.date = %q{2009-08-09}
10
10
  s.description = %q{ALPHA Alert -- just uploaded initial release.
11
11
 
12
12
  Linux inotify is a means to receive events describing file system activity (create, modify, delete, close, etc).
@@ -53,12 +53,13 @@ Selected quotes from the README for inotify:
53
53
  s.email = %q{sswerling@yahoo.com}
54
54
  s.extensions = ["ext/extconf.rb"]
55
55
  s.extra_rdoc_files = ["History.txt", "README.txt"]
56
- s.files = [".gitignore", "History.txt", "README.rdoc", "README.txt", "Rakefile", "examples/watcher.rb", "ext/extconf.rb", "ext/src/inotify-syscalls.h", "ext/src/inotify.h", "ext/src/sinotify.c", "lib/sinotify.rb", "lib/sinotify/event.rb", "lib/sinotify/notifier.rb", "lib/sinotify/prim_event.rb", "lib/sinotify/watch.rb", "lib/sinotify_info.rb", "sinotify.gemspec", "spec/prim_notify_spec.rb", "spec/sinotify_spec.rb", "spec/spec_helper.rb"]
56
+ s.files = [".gitignore", "History.txt", "README.rdoc", "README.txt", "Rakefile", "TODO", "examples/watcher.rb", "ext/extconf.rb", "ext/src/inotify-syscalls.h", "ext/src/inotify.h", "ext/src/sinotify.c", "lib/sinotify.rb", "lib/sinotify/event.rb", "lib/sinotify/notifier.rb", "lib/sinotify/prim_event.rb", "lib/sinotify/watch.rb", "lib/sinotify_info.rb", "sinotify.gemspec", "spec/prim_notify_spec.rb", "spec/sinotify_spec.rb", "spec/spec_helper.rb"]
57
+ s.has_rdoc = true
57
58
  s.homepage = %q{http://tab-a.slot-z.net}
58
59
  s.rdoc_options = ["--inline-source", "--main", "README.txt"]
59
60
  s.require_paths = ["lib", "ext"]
60
61
  s.rubyforge_project = %q{sinotify}
61
- s.rubygems_version = %q{1.3.3}
62
+ s.rubygems_version = %q{1.3.2}
62
63
  s.summary = %q{ALPHA Alert -- just uploaded initial release}
63
64
 
64
65
  if s.respond_to? :specification_version then
@@ -67,13 +68,13 @@ Selected quotes from the README for inotify:
67
68
 
68
69
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
69
70
  s.add_runtime_dependency(%q<cosell>, [">= 0"])
70
- s.add_development_dependency(%q<bones>, [">= 2.4.0"])
71
+ s.add_development_dependency(%q<bones>, [">= 2.5.1"])
71
72
  else
72
73
  s.add_dependency(%q<cosell>, [">= 0"])
73
- s.add_dependency(%q<bones>, [">= 2.4.0"])
74
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
74
75
  end
75
76
  else
76
77
  s.add_dependency(%q<cosell>, [">= 0"])
77
- s.add_dependency(%q<bones>, [">= 2.4.0"])
78
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
78
79
  end
79
80
  end
@@ -15,11 +15,17 @@ end
15
15
  describe Sinotify do
16
16
 
17
17
  # A lot of Sinotify work occurs in background threads (eg. adding watches, adding subdirectories),
18
- # so the tests may insert a tiny pause to allow the bg threads to do their thing before making
18
+ # so the tests may insert a tiny pauses to allow the bg threads to do their thing before making
19
19
  # any assertions.
20
- def tiny_pause!; sleep 0.05; end
21
- def pause!; sleep 0.5; end
22
- def big_pause!; sleep 1.5; end
20
+ def tiny_pause!
21
+ 25.times{sleep 0.0001}
22
+ end
23
+ def pause!
24
+ 25.times{sleep 0.005}
25
+ end
26
+ def big_pause!
27
+ 10.times{sleep 0.1}
28
+ end
23
29
 
24
30
  def reset_test_dir!
25
31
  raise 'not gonna happen' unless @test_root_dir =~ /\/tmp\//
@@ -74,7 +80,9 @@ describe Sinotify do
74
80
  notifier.all_directories_being_watched.should be_eql([@test_root_dir])
75
81
 
76
82
  # make a watch, recurse TRUE. There should only be 27 watches (a-z, and @test_root_dir)
77
- notifier = Sinotify::Notifier.new(@test_root_dir, :recurse => true).watch!
83
+ notifier = Sinotify::Notifier.new(@test_root_dir,
84
+ :etypes => [:all_events],
85
+ :recurse => true).watch!
78
86
  # notifier.spy!(:logger => Logger.new('/tmp/spy.log'))
79
87
 
80
88
  pause!
@@ -83,7 +91,7 @@ describe Sinotify do
83
91
  # check a single announcement on a file in a subdir
84
92
  events = []
85
93
  test_fn = File.join(@test_root_dir, 'a', 'hi')
86
- notifier.when_announcing(Sinotify::Event) { |event| events << event }
94
+ notifier.on_event { |event| events << event }
87
95
  FileUtils.touch test_fn
88
96
  pause!
89
97
  #puts events.map{|e|e.to_s}.join("\n")
@@ -116,21 +124,29 @@ describe Sinotify do
116
124
  subdir_a = File.join(@test_root_dir, 'a')
117
125
  events = []
118
126
  notifier = Sinotify::Notifier.new(@test_root_dir, :recurse => true).watch!
119
- # notifier.spy!(:logger => spylog = Logger.new('/tmp/spy.log'))
120
- notifier.when_announcing(Sinotify::Event) { |event| events << event }
127
+ #notifier.spy!(:logger => spylog = Logger.new(STDOUT))
128
+ notifier.on_event { |event| events << event }
121
129
 
122
130
  # one watch for the root and the 26 subdirs 'a'..'z'
123
131
  pause!
124
132
  notifier.all_directories_being_watched.size.should be_eql(27)
125
133
 
126
134
  # create a new subdir
127
- FileUtils.mkdir File.join(@test_root_dir, 'a', 'abc')
128
- big_pause! # takes a moment to sink in because the watch is added in a bg thread
135
+ subdir_abc = File.join(@test_root_dir, 'a', 'abc')
136
+ FileUtils.mkdir subdir_abc
137
+ pause! # takes a moment to sink in because the watch is added in a bg thread
129
138
  notifier.all_directories_being_watched.size.should be_eql(28)
130
139
  pause!
140
+
141
+ # create a file in the new subdir, it should send and event
142
+ file_in_subdir_abc = File.join(subdir_abc, 'new_file')
143
+ events_before = events.size
144
+ FileUtils.touch file_in_subdir_abc
145
+ pause!
146
+ events.size.should be_eql(events_before + 1)
131
147
  end
132
148
 
133
- it "should delete watches for on subdirectires when a parent directory is deleted" do
149
+ it "should delete watches for on subdirectories when a parent directory is deleted" do
134
150
 
135
151
  # Setup (create the usual test dir and 26 subdirs, and an additional sub-subdir, and a file
136
152
  reset_test_dir! # creates the root dir and 'a'...'z'
@@ -143,7 +159,7 @@ describe Sinotify do
143
159
  events = []
144
160
  notifier = Sinotify::Notifier.new(@test_root_dir, :recurse => true).watch!
145
161
  #notifier.spy!(:logger => Logger.new('/tmp/spy.log'))
146
- notifier.when_announcing(Sinotify::Event) { |event| events << event }
162
+ notifier.on_event { |event| events << event }
147
163
 
148
164
  # first assert: all directories should have a watch
149
165
  pause!
@@ -172,7 +188,7 @@ describe Sinotify do
172
188
  events = []
173
189
  notifier = Sinotify::Notifier.new(@test_root_dir, :recurse => true).watch!
174
190
  #notifier.spy!(:logger => Logger.new('/tmp/spy.log'))
175
- notifier.when_announcing(Sinotify::Event) { |event| events << event }
191
+ notifier.on_event { |event| events << event }
176
192
 
177
193
  # first assert: all directories should have a watch
178
194
  pause!
@@ -196,7 +212,7 @@ describe Sinotify do
196
212
  :recurse => true).watch!
197
213
  #notifier.spy!(:logger => Logger.new('/tmp/spy.log'))
198
214
  creates = deletes = modifies = closes = 0
199
- notifier.when_announcing(Sinotify::Event) do |event|
215
+ notifier.on_event do |event|
200
216
  creates += 1 if event.etypes.include?(:create)
201
217
  deletes += 1 if event.etypes.include?(:delete)
202
218
  modifies += 1 if event.etypes.include?(:modify)
@@ -226,9 +242,11 @@ describe Sinotify do
226
242
  break if waits > 30
227
243
  #raise "Tired of waiting for create events to reach #{total_iterations}, it is only at #{creates}" if waits > 30
228
244
  end
245
+
229
246
  puts "It took #{Time.now - start_wait} seconds for all the create/modify/delete/close events to come through"
230
247
 
231
- pause!; pause!; pause! # give it a tiny bit longer to let any remaining modify/delete/close stragglers to come through
248
+ # give it a tiny bit longer to let any remaining modify/delete/close stragglers to come through
249
+ 5.times{tiny_pause!}
232
250
 
233
251
  puts "Ceates detected: #{creates}"
234
252
  puts "Deletes: #{deletes}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swerling-sinotify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Swerling
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-19 00:00:00 -07:00
12
+ date: 2009-08-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 2.4.0
33
+ version: 2.5.1
34
34
  version:
35
35
  description: "ALPHA Alert -- just uploaded initial release. Linux inotify is a means to receive events describing file system activity (create, modify, delete, close, etc). Sinotify was derived from aredridel's package (http://raa.ruby-lang.org/project/ruby-inotify/), with the addition of Paul Boon's tweak for making the event_check thread more polite (see http://www.mindbucket.com/2009/02/24/ruby-daemons-verifying-good-behavior/) In sinotify, the classes Sinotify::PrimNotifier and Sinotify::PrimEvent provide a low level wrapper to inotify, with the ability to establish 'watches' and then listen for inotify events using one of inotify's synchronous event loops, and providing access to the events' masks (see 'man inotify' for details). Sinotify::PrimEvent class adds a little semantic sugar to the event in to the form of 'etypes', which are just ruby symbols that describe the event mask. If the event has a raw mask of (DELETE_SELF & IS_DIR), then the etypes array would be [:delete_self, :is_dir]. In addition to the 'straight' wrapper in inotify, sinotify provides an asynchronous implementation of the 'observer pattern' for notification. In other words, Sinotify::Notifier listens in the background for inotify events, adapting them into instances of Sinotify::Event as they come in and immediately placing them in a concurrent queue, from which they are 'announced' to 'subscribers' of the event. [Sinotify uses the 'cosell' implementation of the Announcements event notification framework, hence the terminology 'subscribe' and 'announce' rather then 'listen' and 'trigger' used in the standard event observer pattern. See the 'cosell' package on github for details.] A variety of 'knobs' are provided for controlling the behavior of the notifier: whether a watch should apply to a single directory or should recurse into subdirectores, how fast it should broadcast queued events, etc (see Sinotify::Notifier, and the example in the synopsis section below). An event 'spy' can also be setup to log all Sinotify::PrimEvents and Sinotify::Events. Sinotify::Event simplifies inotify's muddled event model, sending events only for those files/directories that have changed. That's not to say you can't setup a notifier that recurses into subdirectories, just that any individual event will apply to a single file, and not to its children. Also, event types are identified using words (in the form of ruby :symbols) instead of inotify's event masks. See Sinotify::Event for more explanation. The README for inotify: http://www.kernel.org/pub/linux/kernel/people/rml/inotify/README Selected quotes from the README for inotify: * \"Rumor is that the 'd' in 'dnotify' does not stand for 'directory' but for 'suck.'\" * \"The 'i' in inotify does not stand for 'suck' but for 'inode' -- the logical choice since inotify is inode-based.\" (The 's' in 'sinotify' does in fact stand for 'suck.')"
36
36
  email: sswerling@yahoo.com
@@ -47,6 +47,7 @@ files:
47
47
  - README.rdoc
48
48
  - README.txt
49
49
  - Rakefile
50
+ - TODO
50
51
  - examples/watcher.rb
51
52
  - ext/extconf.rb
52
53
  - ext/src/inotify-syscalls.h
@@ -62,8 +63,9 @@ files:
62
63
  - spec/prim_notify_spec.rb
63
64
  - spec/sinotify_spec.rb
64
65
  - spec/spec_helper.rb
65
- has_rdoc: false
66
+ has_rdoc: true
66
67
  homepage: http://tab-a.slot-z.net
68
+ licenses:
67
69
  post_install_message:
68
70
  rdoc_options:
69
71
  - --inline-source
@@ -87,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
89
  requirements: []
88
90
 
89
91
  rubyforge_project: sinotify
90
- rubygems_version: 1.2.0
92
+ rubygems_version: 1.3.5
91
93
  signing_key:
92
94
  specification_version: 3
93
95
  summary: ALPHA Alert -- just uploaded initial release