Class: Spider::TemplateCache

Inherits:
Object
  • Object
show all
Includes:
Logger
Defined in:
lib/spiderfw/cache/template_cache.rb

Instance Method Summary collapse

Methods included from Logger

add, close, close_all, datetime_format, datetime_format=, #debug, debug, debug?, #debug?, enquire_loggers, #error, error, #error?, error?, #fatal, fatal, #fatal?, fatal?, info, #info, info?, #info?, method_missing, open, reopen, send_to_loggers, unknown, #unknown, #warn, warn, warn?, #warn?

Constructor Details

#initialize(root_path) ⇒ TemplateCache

Returns a new instance of TemplateCache.



10
11
12
13
14
# File 'lib/spiderfw/cache/template_cache.rb', line 10

def initialize(root_path)
    FileUtils.mkpath(root_path)
    @path = root_path
    @invalid = {}
end

Instance Method Details

#fetch(path, &block) ⇒ Object



16
17
18
19
# File 'lib/spiderfw/cache/template_cache.rb', line 16

def fetch(path, &block)
    return refresh(path, &block) unless fresh?(path)
    return load_cache(path)
end

#fresh?(path) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/spiderfw/cache/template_cache.rb', line 26

def fresh?(path)
    full_path = get_location(path)
    if Spider.config.get('template.cache.disable')
        Spider::Request.current[:compiled_templates] ||= {}
        return true if Spider::Request.current[:compiled_templates][full_path]
        #debug("Cache disabled, recreating #{full_path}")
        return false
    end
    exists = File.exist?(full_path)
    if (Spider.config.get('template.cache.no_check') && exists)
        return true
    end
    return false if @invalid[path]
    global_reload_file = "#{Spider.paths[:tmp]}/templates_reload.txt"
    check_file = "#{full_path}/check"
    return false unless File.exist?(check_file)
    if (File.exist?("#{Spider.paths[:tmp]}/templates_reload.txt"))
        return false if (File.mtime(global_reload_file) > File.mtime(check))
    end
    return true unless Spider.conf.get('template.cache.check_files')
    lock_file = File.new(full_path)
    lock_file.flock(File::LOCK_SH)
    File.new(full_path).flock(File::LOCK_SH)
    # TODO: maybe insert here an (optional) tamper check 
    # that looks if the cache mtime is later then the saved time
    Marshal.load(IO.read(check_file)).each do |check, time|
        #debug("Template file #{check} changed, refreshing cache")
        return false if File.mtime(check) > time
    end
    lock_file.flock(File::LOCK_UN)
    return true
end

#get_compiled_template(path) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/spiderfw/cache/template_cache.rb', line 70

def get_compiled_template(path)
    compiled = Spider::CompiledTemplate.new
    compiled.cache_path = path
    init_code = IO.read(path+'/init.rb')
    run_code = IO.read(path+'/run.rb')
    compiled.assets = Marshal.load(IO.read(path+'/assets'))
    block = Spider::TemplateBlocks::CompiledBlock.new(init_code, run_code)
    compiled.block = block
    Dir.new(path).each do |entry|
        next if entry[0].chr == '.'
        sub_path = "#{path}/#{entry}"
        next if entry == '__info'
        next unless File.directory?(sub_path)
        compiled.subtemplates[entry] = get_compiled_template(sub_path)
    end
    return compiled
end

#get_location(path, &block) ⇒ Object



21
22
23
24
# File 'lib/spiderfw/cache/template_cache.rb', line 21

def get_location(path, &block)
    refresh(path, &block) if (block && !fresh?(path))
    return @path+'/'+path
end

#invalidate(path) ⇒ Object



59
60
61
# File 'lib/spiderfw/cache/template_cache.rb', line 59

def invalidate(path)
    @invalid[path] = true
end

#load_cache(template_path) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/spiderfw/cache/template_cache.rb', line 88

def load_cache(template_path)
    # debug("Using cached #{template_path}")
    full_path = get_location(template_path)
    lock_file = File.new(full_path)
    lock_file.flock(File::LOCK_SH)
    compiled = get_compiled_template(full_path)
    lock_file.flock(File::LOCK_UN)
    return compiled
end

#refresh(path, &block) ⇒ Object



63
64
65
66
67
68
# File 'lib/spiderfw/cache/template_cache.rb', line 63

def refresh(path, &block)
    #debug("Refreshing cache for #{path}")
    res = block.call()
    write_cache(path, res)
    return res
end

#write_cache(template_path, compiled_template) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/spiderfw/cache/template_cache.rb', line 127

def write_cache(template_path, compiled_template)
    full_path = get_location(template_path)
    FileUtils.mkpath(full_path)
    lock_file = File.new(full_path+'/lock', 'w')
    lock_file.flock(File::LOCK_EX)
    write_compiled_template(compiled_template, full_path)
    modified = compiled_template.collect_mtimes
    File.open(full_path+'/check', 'w') do |file|
        file.puts(Marshal.dump(modified))
    end
    lock_file.flock(File::LOCK_UN)
end

#write_compiled_template(compiled, path) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/spiderfw/cache/template_cache.rb', line 98

def write_compiled_template(compiled, path)
    compiled.cache_path = path
    File.open(path+'/init.rb', 'w') do |file|
        file.puts(compiled.block.init_code)
    end
    File.open(path+'/run.rb', 'w') do |file|
        file.puts(compiled.block.run_code)
    end
    File.open(path+'/assets', 'w') do |file|
        file.puts(Marshal.dump(compiled.assets))
    end
    compiled.subtemplates.each do |id, sub|
        sub_path = "#{path}/#{id}"
        FileUtils.mkpath(sub_path)
        write_compiled_template(sub, sub_path)
    end
    compiled.devel_info.each do |name, val|
        FileUtils.mkpath("#{path}/__info")
        sub_path = "#{path}/__info/#{name}"
        File.open(sub_path, 'w') do |f|
            f.puts(val)
        end
    end
    if Spider.config.get('template.cache.disable')
        Spider::Request.current[:compiled_templates] ||= {}
        Spider::Request.current[:compiled_templates][path] = true
    end
end