Module: Whisper::Dependency

Includes:
Loggy
Included in:
CachedFile, Comment, CommentSet, DirScanner, DirSet, Entry, EntrySet, Page, Text
Defined in:
lib/whisper/common.rb

Overview

model dependency behaviors.

methods provided: #content – get the latest content, built lazily #refresh! – do a check, invalidate content if necessary

methods you must define:

#dependencies: returns the set of dependencies, i.e. the set of objects

which, if they change, this object should change too.

#build(old_content): rebuild the content (i.e. from the dependencies’ contents)

optional methods you can define: #check: check for dirtiness (from external sources; we take care

of the rest), returning true iff dirty. if this is an expensive method,
you should limit operation to once every N seconds or something like that.

this module requires initialization, so you should call #dependency_init in your constructor

also, no cycle checking, so DAGs only.

also, allows for different types of content, if you pass arguments to #content

Class Attribute Summary collapse

Instance Method Summary collapse

Class Attribute Details

.min_refresh_intervalObject

Returns the value of attribute min_refresh_interval.



233
234
235
# File 'lib/whisper/common.rb', line 233

def min_refresh_interval
  @min_refresh_interval
end

Instance Method Details

#content(*a) ⇒ Object



265
266
267
268
269
270
271
272
273
# File 'lib/whisper/common.rb', line 265

def content *a
  @mutex.synchronize do
    unless @content.member?(a)
      @content[a] = build @old_content[a], *a
      #debug "[dep #{self.class}:#{object_id}] content was rebuilt"
    end
  end
  @content[a]
end

#dependency_initObject



235
236
237
238
239
240
241
242
243
# File 'lib/whisper/common.rb', line 235

def dependency_init
  @mutex = Mutex.new
  @timestamp = Time.now
  @last_refresh = Time.at 0
  @old_content = {}
  @content = {}

  Dependency.min_refresh_interval ||= 10
end

#refresh!Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/whisper/common.rb', line 247

def refresh!
  @mutex.synchronize do
    return if (@last_refresh + Dependency.min_refresh_interval) > Time.now
    #debug "[dep] refresh called, checking #{dependencies.size} deps (content empty is #{@content.empty?}; respond_to check is #{respond_to?(:check)})"
    dependencies.each { |d| d.refresh! }
    dep_changed = dependencies.find { |d| d.timestamp > @timestamp }
    i_changed = !dep_changed && respond_to?(:check) && check
    if !@content.empty? && (dep_changed || i_changed)
      #debug "[dep #{self.class}:#{object_id}] dep #{dep_changed.class}:#{dep_changed.object_id} changed (#{dep_changed.timestamp} vs #{@timestamp}), invalidating content" if dep_changed
      #debug "[dep #{self.class}:#{object_id}] i changed, invalidating content" if i_changed
      @timestamp = Time.now
      @old_content = @content
      @content = {}
    end
    @last_refresh = Time.now
  end
end

#timestampObject



245
# File 'lib/whisper/common.rb', line 245

def timestamp; @mutex.synchronize { @timestamp } end