rjspotter-innate 2009.06.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +10 -0
- data/CHANGELOG +3261 -0
- data/COPYING +18 -0
- data/MANIFEST +127 -0
- data/README.md +563 -0
- data/Rakefile +39 -0
- data/example/app/retro_games.rb +60 -0
- data/example/app/todo/layout/default.xhtml +11 -0
- data/example/app/todo/spec/todo.rb +63 -0
- data/example/app/todo/start.rb +51 -0
- data/example/app/todo/view/index.xhtml +39 -0
- data/example/app/whywiki_erb/layout/wiki.html.erb +15 -0
- data/example/app/whywiki_erb/spec/wiki.rb +19 -0
- data/example/app/whywiki_erb/start.rb +42 -0
- data/example/app/whywiki_erb/view/edit.erb +6 -0
- data/example/app/whywiki_erb/view/index.erb +12 -0
- data/example/custom_middleware.rb +35 -0
- data/example/hello.rb +11 -0
- data/example/howto_spec.rb +35 -0
- data/example/link.rb +27 -0
- data/example/provides.rb +31 -0
- data/example/session.rb +38 -0
- data/innate.gemspec +41 -0
- data/lib/innate.rb +269 -0
- data/lib/innate/action.rb +137 -0
- data/lib/innate/adapter.rb +76 -0
- data/lib/innate/cache.rb +134 -0
- data/lib/innate/cache/api.rb +128 -0
- data/lib/innate/cache/drb.rb +58 -0
- data/lib/innate/cache/file_based.rb +44 -0
- data/lib/innate/cache/marshal.rb +20 -0
- data/lib/innate/cache/memory.rb +21 -0
- data/lib/innate/cache/yaml.rb +20 -0
- data/lib/innate/current.rb +35 -0
- data/lib/innate/dynamap.rb +96 -0
- data/lib/innate/helper.rb +185 -0
- data/lib/innate/helper/aspect.rb +124 -0
- data/lib/innate/helper/cgi.rb +54 -0
- data/lib/innate/helper/flash.rb +36 -0
- data/lib/innate/helper/link.rb +94 -0
- data/lib/innate/helper/redirect.rb +85 -0
- data/lib/innate/helper/render.rb +152 -0
- data/lib/innate/helper/send_file.rb +26 -0
- data/lib/innate/log.rb +20 -0
- data/lib/innate/log/color_formatter.rb +49 -0
- data/lib/innate/log/hub.rb +77 -0
- data/lib/innate/middleware_compiler.rb +65 -0
- data/lib/innate/mock.rb +49 -0
- data/lib/innate/node.rb +1029 -0
- data/lib/innate/options.rb +37 -0
- data/lib/innate/options/dsl.rb +205 -0
- data/lib/innate/options/stub.rb +7 -0
- data/lib/innate/request.rb +141 -0
- data/lib/innate/response.rb +24 -0
- data/lib/innate/route.rb +114 -0
- data/lib/innate/session.rb +133 -0
- data/lib/innate/session/flash.rb +94 -0
- data/lib/innate/spec.rb +1 -0
- data/lib/innate/spec/bacon.rb +28 -0
- data/lib/innate/state.rb +26 -0
- data/lib/innate/state/accessor.rb +130 -0
- data/lib/innate/traited.rb +90 -0
- data/lib/innate/trinity.rb +18 -0
- data/lib/innate/version.rb +3 -0
- data/lib/innate/view.rb +97 -0
- data/lib/innate/view/erb.rb +14 -0
- data/lib/innate/view/etanni.rb +33 -0
- data/lib/innate/view/none.rb +9 -0
- data/spec/example/app/retro_games.rb +30 -0
- data/spec/example/hello.rb +13 -0
- data/spec/example/link.rb +25 -0
- data/spec/example/provides.rb +16 -0
- data/spec/example/session.rb +22 -0
- data/spec/helper.rb +10 -0
- data/spec/innate/action/layout.rb +121 -0
- data/spec/innate/action/layout/file_layout.xhtml +1 -0
- data/spec/innate/cache/common.rb +47 -0
- data/spec/innate/cache/marshal.rb +5 -0
- data/spec/innate/cache/memory.rb +5 -0
- data/spec/innate/cache/yaml.rb +5 -0
- data/spec/innate/dynamap.rb +22 -0
- data/spec/innate/helper.rb +86 -0
- data/spec/innate/helper/aspect.rb +75 -0
- data/spec/innate/helper/cgi.rb +37 -0
- data/spec/innate/helper/flash.rb +115 -0
- data/spec/innate/helper/link.rb +139 -0
- data/spec/innate/helper/redirect.rb +171 -0
- data/spec/innate/helper/render.rb +165 -0
- data/spec/innate/helper/send_file.rb +21 -0
- data/spec/innate/helper/view/aspect_hello.xhtml +1 -0
- data/spec/innate/helper/view/locals.xhtml +1 -0
- data/spec/innate/helper/view/loop.xhtml +4 -0
- data/spec/innate/helper/view/num.xhtml +1 -0
- data/spec/innate/helper/view/partial.xhtml +1 -0
- data/spec/innate/helper/view/recursive.xhtml +7 -0
- data/spec/innate/mock.rb +84 -0
- data/spec/innate/modes.rb +61 -0
- data/spec/innate/node/mapping.rb +37 -0
- data/spec/innate/node/node.rb +135 -0
- data/spec/innate/node/resolve.rb +82 -0
- data/spec/innate/node/view/another_layout/another_layout.xhtml +3 -0
- data/spec/innate/node/view/bar.xhtml +1 -0
- data/spec/innate/node/view/foo.html.xhtml +1 -0
- data/spec/innate/node/view/only_view.xhtml +1 -0
- data/spec/innate/node/view/with_layout.xhtml +1 -0
- data/spec/innate/node/wrap_action_call.rb +83 -0
- data/spec/innate/options.rb +123 -0
- data/spec/innate/parameter.rb +154 -0
- data/spec/innate/provides.rb +99 -0
- data/spec/innate/provides/list.html.xhtml +1 -0
- data/spec/innate/provides/list.txt.xhtml +1 -0
- data/spec/innate/request.rb +79 -0
- data/spec/innate/route.rb +135 -0
- data/spec/innate/session.rb +58 -0
- data/spec/innate/traited.rb +55 -0
- data/tasks/authors.rake +30 -0
- data/tasks/bacon.rake +66 -0
- data/tasks/changelog.rake +18 -0
- data/tasks/gem.rake +22 -0
- data/tasks/gem_setup.rake +99 -0
- data/tasks/grancher.rake +12 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/rcov.rake +19 -0
- data/tasks/release.rake +53 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/setup.rake +6 -0
- data/tasks/ycov.rake +84 -0
- metadata +218 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
Rack::Handler.register('ebb', 'Rack::Handler::Ebb')
|
2
|
+
|
3
|
+
module Innate
|
4
|
+
|
5
|
+
# Lightweight wrapper around Rack::Handler, will apply our options in a
|
6
|
+
# unified manner and deal with adapters that don't like to do what we want or
|
7
|
+
# where Rack doesn't want to take a stand.
|
8
|
+
#
|
9
|
+
# Rack handlers as of 2009.03.25:
|
10
|
+
# cgi, fastcgi, mongrel, emongrel, smongrel, webrick, lsws, scgi, thin
|
11
|
+
|
12
|
+
module Adapter
|
13
|
+
include Optioned
|
14
|
+
|
15
|
+
options.dsl do
|
16
|
+
o "IP address or hostname that we respond to - 0.0.0.0 for all",
|
17
|
+
:host, "0.0.0.0"
|
18
|
+
|
19
|
+
o "Port for the server",
|
20
|
+
:port, 7000
|
21
|
+
|
22
|
+
o "Web server to run on",
|
23
|
+
:handler, :webrick
|
24
|
+
end
|
25
|
+
|
26
|
+
# Pass given app to the Handler, handler is chosen based on config.adapter
|
27
|
+
# option.
|
28
|
+
# If there is a method named start_name_of_adapter it will be run instead
|
29
|
+
# of the default run method of the handler, this makes it easy to define
|
30
|
+
# custom startup of handlers for your server of choice.
|
31
|
+
def self.start(app, given_options = nil)
|
32
|
+
options.merge!(given_options) if given_options
|
33
|
+
|
34
|
+
handler = options[:handler].to_s.downcase
|
35
|
+
config = { :Host => options[:host], :Port => options[:port] }
|
36
|
+
|
37
|
+
Log.debug "Using #{handler}"
|
38
|
+
|
39
|
+
if respond_to?(method = "start_#{handler}")
|
40
|
+
send(method, app, config)
|
41
|
+
else
|
42
|
+
Rack::Handler.get(handler).run(app, config)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Due to buggy autoload on Ruby 1.8 we have to require 'ebb' manually.
|
47
|
+
# This most likely happens because autoload doesn't respect the require of
|
48
|
+
# rubygems and uses the C require directly.
|
49
|
+
def self.start_ebb(app, config)
|
50
|
+
require 'ebb'
|
51
|
+
Rack::Handler.get('ebb').run(app, config)
|
52
|
+
end
|
53
|
+
|
54
|
+
# We want webrick to use our logger.
|
55
|
+
def self.start_webrick(app, config)
|
56
|
+
handler = Rack::Handler.get('webrick')
|
57
|
+
config = {
|
58
|
+
:BindAddress => config[:Host],
|
59
|
+
:Port => config[:Port],
|
60
|
+
:Logger => Log,
|
61
|
+
:AccessLog => [
|
62
|
+
[Log, ::WEBrick::AccessLog::COMMON_LOG_FORMAT],
|
63
|
+
[Log, ::WEBrick::AccessLog::REFERER_LOG_FORMAT]]
|
64
|
+
}
|
65
|
+
|
66
|
+
handler.run(app, config)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Thin shouldn't give excessive output, especially not to $stdout
|
70
|
+
def self.start_thin(app, config)
|
71
|
+
handler = Rack::Handler.get('thin')
|
72
|
+
::Thin::Logging.silent = true
|
73
|
+
handler.run(app, config)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/innate/cache.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
module Innate
|
2
|
+
# Cache manager and wrapper.
|
3
|
+
#
|
4
|
+
# Provides a convenient wrapper around caches to keep method name confusion
|
5
|
+
# at a minimum while still having short and meaningful method names for every
|
6
|
+
# cache instance.
|
7
|
+
#
|
8
|
+
# The default caching is specified in lib/innate.rb in the config section.
|
9
|
+
# At the time of writing it defaults to Innate::Cache::Memory but can be
|
10
|
+
# changed easily.
|
11
|
+
#
|
12
|
+
# Configuration has to be done before Innate::setup_dependencies is being
|
13
|
+
# called.
|
14
|
+
#
|
15
|
+
# Configuration:
|
16
|
+
#
|
17
|
+
# Innate::Cache.options do |cache|
|
18
|
+
# cache.names = [:session, :user]
|
19
|
+
# cache.session = Innate::Cache::Marshal
|
20
|
+
# cache.user = Innate::Cache::YAML
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# Usage for storing:
|
24
|
+
#
|
25
|
+
# # Storing with a time to live (10 seconds)
|
26
|
+
# Innate::Cache.user.store(:manveru, "Michael Fellinger", :ttl => 10)
|
27
|
+
#
|
28
|
+
# # Storing indefinitely
|
29
|
+
# Innate::Cache.user[:Pistos] = "unknown"
|
30
|
+
# # or without :ttl argument
|
31
|
+
# Innate::Cache.user.store(:Pistos, "unknown")
|
32
|
+
#
|
33
|
+
# Usage for retrieving:
|
34
|
+
#
|
35
|
+
# # we stored this one for 10 seconds
|
36
|
+
# Innate::Cache.user.fetch(:manveru, 'not here anymore')
|
37
|
+
# # => "Michael Fellinger"
|
38
|
+
# sleep 11
|
39
|
+
# Innate::Cache.user.fetch(:manveru, 'not here anymore')
|
40
|
+
# # => "not here anymore"
|
41
|
+
#
|
42
|
+
# Innate::Cache.user[:Pistos]
|
43
|
+
# # => "unknown"
|
44
|
+
# Innate::Cache.user.fetch(:Pistos)
|
45
|
+
# # => "unknown"
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# For more details and to find out how to implement your own cache please
|
49
|
+
# read the documentation of Innate::Cache::API
|
50
|
+
#
|
51
|
+
# NOTE:
|
52
|
+
# * Some caches might expose their contents for everyone else on the same
|
53
|
+
# system, or even on connected systems. The rule as usual is, not to
|
54
|
+
# cache sensitive information.
|
55
|
+
|
56
|
+
class Cache
|
57
|
+
autoload :API, 'innate/cache/api'
|
58
|
+
autoload :DRb, 'innate/cache/drb'
|
59
|
+
autoload :YAML, 'innate/cache/yaml'
|
60
|
+
autoload :Memory, 'innate/cache/memory'
|
61
|
+
autoload :Marshal, 'innate/cache/marshal'
|
62
|
+
autoload :FileBased, 'innate/cache/file_based'
|
63
|
+
|
64
|
+
include Optioned
|
65
|
+
|
66
|
+
options.dsl do
|
67
|
+
o "Assign a cache to each of these names on Innate::Cache::setup",
|
68
|
+
:names, [:session, :view]
|
69
|
+
|
70
|
+
default "If no option for the cache name exists, fall back to this",
|
71
|
+
Innate::Cache::Memory
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :name, :instance
|
75
|
+
|
76
|
+
def initialize(name, klass = nil)
|
77
|
+
@name = name.to_s.dup.freeze
|
78
|
+
|
79
|
+
klass ||= options[@name.to_sym]
|
80
|
+
@instance = klass.new
|
81
|
+
|
82
|
+
@instance.cache_setup(
|
83
|
+
ENV['HOSTNAME'],
|
84
|
+
ENV['USER'],
|
85
|
+
'pristine',
|
86
|
+
@name
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Add all caches from the options.
|
91
|
+
#
|
92
|
+
# @see Innate::setup_dependencies
|
93
|
+
# @api stable
|
94
|
+
# @return [Array] names of caches initialized
|
95
|
+
# @author manveru
|
96
|
+
def self.setup
|
97
|
+
options.names.each{|name| add(name) }
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add accessors for cache
|
101
|
+
#
|
102
|
+
# @param [Cache] cache
|
103
|
+
def self.register(cache)
|
104
|
+
key = cache.name
|
105
|
+
source = "def self.%s() @%s; end
|
106
|
+
def self.%s=(o) @%s = o; end" % [key, key, key, key]
|
107
|
+
self.class_eval(source, __FILE__, __LINE__)
|
108
|
+
|
109
|
+
self.send("#{key}=", cache)
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.add(*names)
|
113
|
+
names.each{|name| register(new(name)) }
|
114
|
+
end
|
115
|
+
|
116
|
+
def clear
|
117
|
+
instance.cache_clear
|
118
|
+
end
|
119
|
+
|
120
|
+
def delete(*keys)
|
121
|
+
instance.cache_delete(*keys)
|
122
|
+
end
|
123
|
+
|
124
|
+
def fetch(key, default = nil)
|
125
|
+
instance.cache_fetch(key, default)
|
126
|
+
end
|
127
|
+
alias [] fetch
|
128
|
+
|
129
|
+
def store(key, value, options = {})
|
130
|
+
instance.cache_store(key, value, options)
|
131
|
+
end
|
132
|
+
alias []= store
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Innate
|
2
|
+
class Cache
|
3
|
+
|
4
|
+
# This is the API every Cache has to conform to.
|
5
|
+
#
|
6
|
+
# The default behaviour is tailored for the Memory cache, override any
|
7
|
+
# behaviour as you need.
|
8
|
+
#
|
9
|
+
# +key+ may be a String or Symbol
|
10
|
+
# +value+ is a Hash of serializable (as according to Marshal) objects
|
11
|
+
#
|
12
|
+
# Every cache instance has to respond to:
|
13
|
+
#
|
14
|
+
# ::new()
|
15
|
+
# #cache_setup(hostname, username, appname, cachename)
|
16
|
+
# #cache_clear()
|
17
|
+
# #cache_delete(*keys)
|
18
|
+
# #cache_fetch(key, default = nil)
|
19
|
+
# #cache_store(key, value, options = {})
|
20
|
+
#
|
21
|
+
# We are prefixing cache_ to make the intent clear and implementation
|
22
|
+
# easier, as there may be existing behaviour associated with the
|
23
|
+
# non-prefixed version.
|
24
|
+
#
|
25
|
+
# Also note that we create one instance per cache name-space.
|
26
|
+
module API
|
27
|
+
# Executed after #initialize and before any other method.
|
28
|
+
#
|
29
|
+
# Some parameters identifying the current process will be passed so
|
30
|
+
# caches that act in one global name-space can use them as a prefix.
|
31
|
+
#
|
32
|
+
# @param [String #to_s] hostname the hostname of the machine
|
33
|
+
# @param [String #to_s] username user executing the process
|
34
|
+
# @param [String #to_s] appname identifier for the application
|
35
|
+
# @param [String #to_s] cachename namespace, like 'session' or 'action'
|
36
|
+
# @author manveru
|
37
|
+
def cache_setup(hostname, username, appname, cachename)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Remove all key/value pairs from the cache.
|
41
|
+
# Should behave as if #delete had been called with all +keys+ as argument.
|
42
|
+
#
|
43
|
+
# @author manveru
|
44
|
+
def cache_clear
|
45
|
+
clear
|
46
|
+
end
|
47
|
+
|
48
|
+
# Remove the corresponding key/value pair for each key passed.
|
49
|
+
# If removing is not an option it should set the corresponding value to nil.
|
50
|
+
#
|
51
|
+
# If only one key was deleted, answer with the corresponding value.
|
52
|
+
# If multiple keys were deleted, answer with an Array containing the values.
|
53
|
+
#
|
54
|
+
# NOTE: Due to differences in the underlying implementation in the
|
55
|
+
# caches, some may not return the deleted value as it would mean
|
56
|
+
# another lookup before deletion. This is the case for caches on
|
57
|
+
# memcached or any database system.
|
58
|
+
#
|
59
|
+
# @param [Object] key the key for the value to delete
|
60
|
+
# @param [Object] keys any other keys to delete as well
|
61
|
+
# @return [Object Array nil]
|
62
|
+
# @author manveru
|
63
|
+
def cache_delete(key, *keys)
|
64
|
+
if keys.empty?
|
65
|
+
if value = yield(key)
|
66
|
+
value[:value]
|
67
|
+
end
|
68
|
+
else
|
69
|
+
[key, *keys].map{|k| cache_delete(k) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Answer with the value associated with the +key+, +nil+ if not found or
|
74
|
+
# expired.
|
75
|
+
#
|
76
|
+
# @param [Object] key the key for which to fetch the value
|
77
|
+
# @param [Object] default will return this if no value was found
|
78
|
+
# @return [Object]
|
79
|
+
# @see Innate::Cache#fetch Innate::Cache#[]
|
80
|
+
# @author manveru
|
81
|
+
def cache_fetch(key, default = nil)
|
82
|
+
value = default
|
83
|
+
|
84
|
+
if entry = yield(key)
|
85
|
+
if expires = entry[:expires]
|
86
|
+
if expires > Time.now
|
87
|
+
value = entry[:value]
|
88
|
+
else
|
89
|
+
cache_delete(key)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
value = entry[:value]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
return value
|
97
|
+
end
|
98
|
+
|
99
|
+
# Set +key+ to +value+.
|
100
|
+
#
|
101
|
+
# +options+ may be one of:
|
102
|
+
# :ttl => time to live in seconds if given in Numeric
|
103
|
+
# infinite or maximum if not given
|
104
|
+
#
|
105
|
+
# Usage:
|
106
|
+
# Cache.value.store(:num, 3, :ttl => 20)
|
107
|
+
# Cache.value.fetch(:num) # => 3
|
108
|
+
# sleep 21
|
109
|
+
# Cache.value.fetch(:num) # => nil
|
110
|
+
#
|
111
|
+
# @param [Object] key the value is stored with this key
|
112
|
+
# @param [Object] value the key points to this value
|
113
|
+
# @param [Hash] options for now, only :ttl => Fixnum is used.
|
114
|
+
# @see Innate::Cache#store Innate::Cache#[]=
|
115
|
+
# @author manveru
|
116
|
+
def cache_store(key, value, options = {})
|
117
|
+
ttl = options[:ttl]
|
118
|
+
|
119
|
+
value_hash = {:value => value}
|
120
|
+
value_hash[:expires] = Time.now + ttl if ttl
|
121
|
+
|
122
|
+
yield(key, value_hash)
|
123
|
+
|
124
|
+
return value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'drb'
|
2
|
+
|
3
|
+
module Innate
|
4
|
+
module Cache
|
5
|
+
|
6
|
+
# Cache utilizing a DRb server.
|
7
|
+
#
|
8
|
+
# You will need to run a corresponding DRb server to use this cache. The
|
9
|
+
# example below is using a normal Hash, but it is recommended to use a
|
10
|
+
# thread-safe alternative like SyncHash.
|
11
|
+
#
|
12
|
+
# @example usage of DRb server
|
13
|
+
# require 'drb'
|
14
|
+
#
|
15
|
+
# URI = "druby://127.0.0.1:9069"
|
16
|
+
# CACHE = {}
|
17
|
+
#
|
18
|
+
# $SAFE = 1 # disable eval and friends
|
19
|
+
#
|
20
|
+
# DRb.start_service(URI, CACHE)
|
21
|
+
# DRb.thread.join
|
22
|
+
#
|
23
|
+
# Please note that on some Ruby implementations, access to Hash is not
|
24
|
+
# atomic and you might need to lock around access to avoid race conditions.
|
25
|
+
#
|
26
|
+
# @example for all caches
|
27
|
+
# Innate.options.cache.default = Innate::Cache::DRb
|
28
|
+
#
|
29
|
+
# @example for sessions only
|
30
|
+
# Innate.options.cache.session = Innate::Cache::DRb
|
31
|
+
class DRb
|
32
|
+
include Cache::API
|
33
|
+
|
34
|
+
OPTIONS = {:address => '127.0.0.1', :port => 9069}
|
35
|
+
|
36
|
+
def cache_setup(*args)
|
37
|
+
address, port = OPTIONS.values_at(:address, :port)
|
38
|
+
@store = DRbObject.new(nil, "druby://#{address}:#{port}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def cache_clear
|
42
|
+
@store.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
def cache_store(*args)
|
46
|
+
super{|key, value| @store[key] = value }
|
47
|
+
end
|
48
|
+
|
49
|
+
def cache_fetch(*args)
|
50
|
+
super{|key| @store[key] }
|
51
|
+
end
|
52
|
+
|
53
|
+
def cache_delete(*args)
|
54
|
+
super{|key| @store.delete(key) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Innate
|
2
|
+
class Cache
|
3
|
+
|
4
|
+
# Used by caches that serialize their contents to the filesystem.
|
5
|
+
# Right now we do not lock around write access to the file outside of the
|
6
|
+
# process, that means that all FileBased caches are not safe for use if you
|
7
|
+
# need more than one instance of your application.
|
8
|
+
module FileBased
|
9
|
+
attr_reader :filename
|
10
|
+
|
11
|
+
def cache_setup(*args)
|
12
|
+
@prefix = args.compact.join('-')
|
13
|
+
|
14
|
+
@dir = File.join(Dir.tmpdir, self.class::DIR)
|
15
|
+
FileUtils.mkdir_p(@dir)
|
16
|
+
|
17
|
+
@filename = File.join(@dir, @prefix + self.class::EXT)
|
18
|
+
@store = self.class::STORE.new(@filename)
|
19
|
+
end
|
20
|
+
|
21
|
+
def cache_clear
|
22
|
+
FileUtils.mkdir_p(@dir)
|
23
|
+
FileUtils.rm_f(@filename)
|
24
|
+
@store = self.class::STORE.new(@filename)
|
25
|
+
end
|
26
|
+
|
27
|
+
def cache_store(*args)
|
28
|
+
super{|key, value| transaction{|store| store[key] = value } }
|
29
|
+
end
|
30
|
+
|
31
|
+
def cache_fetch(*args)
|
32
|
+
super{|key| transaction{|store| store[key] } }
|
33
|
+
end
|
34
|
+
|
35
|
+
def cache_delete(*args)
|
36
|
+
super{|key| transaction{|store| store.delete(key) } }
|
37
|
+
end
|
38
|
+
|
39
|
+
def transaction(&block)
|
40
|
+
Innate.sync{ @store.transaction(&block) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'pstore'
|
2
|
+
|
3
|
+
module Innate
|
4
|
+
class Cache
|
5
|
+
# Keeps every cache in a separate file like this:
|
6
|
+
# /tmp/innate-cache-marshal/delta-manveru-session.marshal
|
7
|
+
#
|
8
|
+
# The Marshal cache is not safe for use between multiple processes, it is
|
9
|
+
# also slow compared to other caches, so generally the use of it is
|
10
|
+
# discouraged.
|
11
|
+
class Marshal
|
12
|
+
include Cache::API
|
13
|
+
include Cache::FileBased
|
14
|
+
|
15
|
+
STORE = ::PStore
|
16
|
+
DIR = 'innate-cache-marshal'
|
17
|
+
EXT = '.marshal'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|