Class: EBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/el/ipcm.rb,
lib/el/cache.rb,
lib/el/assets.rb

Overview

Inter-Process Cache Manager

Instance Method Summary collapse

Instance Method Details

#assetsObject



122
123
124
# File 'lib/el/assets.rb', line 122

def assets
  @sprockets_env ||= Sprockets::Environment.new(root)
end

#assets_url(url = nil, server = true) ⇒ Object Also known as: assets_map

Note:

by default, Sprockets will be used to serve static files. to disable this, set second argument to false.

set the baseurl for assets. by default, assets URL is empty.

Examples:

assets_url not set

script_tag 'master.js'
=> <script src="master.js"
style_tag 'theme.css'
=> <link href="theme.css"

assets_url set to /assets


script_tag 'master.js'
=> <script src="/assets/master.js"
style_tag 'theme.css'
=> <link href="/assets/theme.css"


112
113
114
115
116
117
118
119
# File 'lib/el/assets.rb', line 112

def assets_url url = nil, server = true
  return @assets_url if @assets_url
  url = url.to_s.dup.strip
  url = url =~ /\A[\w|\d]+\:\/\//i ? url : EUtils.rootify_url(url)
  @assets_url = (url =~ /\/\Z/ ? url : String.new(url) << '/').freeze
  return unless server
  mount_application(assets, @assets_url, on: :GET)
end

#cache(key = nil, &proc) ⇒ Object

Note:

value is not stored if block returns false or nil

simply running a block and store returned value. on next request the stored value will be returned.



28
29
30
31
# File 'lib/el/cache.rb', line 28

def cache key = nil, &proc
  key ||= proc.source_location
  cache_pool[key] || ( (val = proc.call) && (cache_pool[key] = val) )
end

#cache_pool(pool = nil) ⇒ Object

very basic cache implementation. by default the cache will be kept in memory. if you want to use a different pool, set it by using ‘cache_pool` at app level. make sure your pool behaves just like a Hash, meant it responds to `[]=`, `[]`, `keys`, `delete` and `clear`



16
17
18
19
20
# File 'lib/el/cache.rb', line 16

def cache_pool pool = nil
  return @cache_pool if @cache_pool
  @cache_pool = pool if pool
  @cache_pool ||= Hash.new
end

#clear_cache(*matchers) ⇒ Object

same as ‘clear_cache!` except it is working only on current process

Parameters:

  • keys (Array)


85
86
87
88
89
90
91
92
93
94
# File 'lib/el/cache.rb', line 85

def clear_cache *matchers
  return cache_pool.clear if matchers.empty?
  keys = Array.new(cache_pool.keys)
  matchers.each do |matcher|
    mkeys = matcher.is_a?(Regexp) ?
      keys.select {|k| k =~ matcher} :
      keys.select {|k| k == matcher}
    mkeys.each {|k| cache_pool.delete k}
  end
end

#clear_cache!(*matchers) ⇒ Object

a simple way to manage stored cache. any number of arguments(actually matchers) accepted. matchers can be of String, Symbol or Regexp type. any other arguments ignored

end

Examples:

class App < E

  before do
    if 'some condition occurred'
      # clearing cache only for @red_banners and @db_items
      clear_cache! :red_banners, :db_items
    end
    if 'some another condition occurred'
      # clearing all cache
      clear_cache!
    end
    if 'Yet another condition occurred'
      # clearing cache by regexp
      clear_cache! /banners/, /db/
    end
  end
end

def index
  @db_items = cache :db_items do
    # ...
  end
  @red_banners = cache :red_banners do
    # ...
  end
  @blue_banners = cache :blue_banners do
    # ...
  end
  # ...
end

def products
  cache do
    # fetch and render products
  end
end

Parameters:

  • keys (Array)


77
78
79
80
# File 'lib/el/cache.rb', line 77

def clear_cache! *matchers
  clear_cache *matchers
  ipcm_trigger :clear_cache, *matchers
end

#ipcm_signal(signal = nil) ⇒ Object



35
36
37
38
39
# File 'lib/el/ipcm.rb', line 35

def ipcm_signal signal = nil
  return @ipcm_signal if @ipcm_signal
  @ipcm_signal = signal.to_s if signal
  @ipcm_signal ||= 'ALRM'
end

#ipcm_tmpdir(path = nil) ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/el/ipcm.rb', line 24

def ipcm_tmpdir path = nil
  return @ipcm_tmpdir if @ipcm_tmpdir
  if path
    @ipcm_tmpdir = ((path =~ /\A\// ? path : root + path) + '/').freeze
  else
    @ipcm_tmpdir = (root + 'tmp/ipcm/').freeze
  end
  FileUtils.mkdir_p @ipcm_tmpdir
  @ipcm_tmpdir
end

#ipcm_trigger(*args) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/el/ipcm.rb', line 4

def ipcm_trigger *args
  if pids_reader
    pids = pids_reader.call rescue nil
    if pids.is_a?(Array)
      pids.map(&:to_i).reject {|p| p < 2 || p == Process.pid }.each do |pid|
        file = '%s/%s.%s-%s' % [ipcm_tmpdir, pid, args.hash, Time.now.to_f]
        begin
          File.open(file, 'w') {|f| f << Marshal.dump(args)}
          Process.kill ipcm_signal, pid
        rescue => e
          warn "was unable to perform IPCM operation because of error: %s" % ::CGI.escapeHTML(e.message)
          File.unlink(file) if File.file?(file)
        end
      end
    else
      warn "pids_reader should return an array of pids. Exiting IPCM..."
    end
  end
end

#pids_reader(&proc) ⇒ Object Also known as: pids



58
59
60
61
62
63
64
# File 'lib/el/ipcm.rb', line 58

def pids_reader &proc
  return @pids_reader if @pids_reader
  if proc.is_a?(Proc)
    @pids_reader = proc
    register_ipcm_signal
  end
end

#register_ipcm_signalObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/el/ipcm.rb', line 41

def register_ipcm_signal
  Signal.trap ipcm_signal do
    Dir[ipcm_tmpdir + '%s.*' % Process.pid].each do |file|
      unless (setup = Marshal.restore(File.read(file)) rescue nil).is_a?(Array)
        warn "Was unable to process \"%s\" cache file, skipping cache cleaning" % file
      end
      File.unlink(file) if File.file?(file)
      meth = setup.shift
      [ :clear_cache,
        :clear_cache_like,
        :clear_compiler,
        :clear_compiler_like,
      ].include?(meth) && self.send(meth, *setup)
    end
  end
end