merb-cache 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ module Merb::Cache::DatabaseStore::ActiveRecord
2
+ # Module that provides ActiveRecord support for the database backend
3
+
4
+ # The cache model migration
5
+ class CacheMigration < ActiveRecord::Migration
6
+ def self.up
7
+ create_table (Merb::Controller._cache.config[:table_name]), :primary_key => :ckey do |t|
8
+ t.column :ckey, :string
9
+ t.column :data, :text
10
+ t.datetime :expire, :default => nil
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table Merb::Controller._cache.config[:table_name]
16
+ end
17
+ end
18
+
19
+ # The cache model
20
+ class CacheModel < ActiveRecord::Base
21
+ set_table_name Merb::Controller._cache.config[:table_name]
22
+
23
+ # Fetch data from the database using the specified key
24
+ # The entry is deleted if it has expired
25
+ #
26
+ # ==== Parameter
27
+ # key<Sting>:: The key identifying the cache entry
28
+ #
29
+ # ==== Returns
30
+ # data<String, NilClass>::
31
+ # nil is returned whether the entry expired or was not found
32
+ def self.cache_get(key)
33
+ if entry = self.find(:first, :conditions => ["ckey=?", key])
34
+ return entry.data if entry.expire.nil? || Time.now < entry.expire
35
+ self.expire(key)
36
+ end
37
+ nil
38
+ end
39
+
40
+ # Store data to the database using the specified key
41
+ #
42
+ # ==== Parameters
43
+ # key<Sting>:: The key identifying the cache entry
44
+ # data<String>:: The data to be put in cache
45
+ # expire<~minutes>::
46
+ # The number of minutes (from now) the cache should persist
47
+ # get<Boolean>::
48
+ # used internally to behave like this
49
+ # - when set to true, perform update_or_create on the cache entry
50
+ # - when set to false, force creation of the cache entry
51
+ def self.cache_set(key, data, expire = nil, get = true)
52
+ attributes = {:ckey => key, :data => data, :expire => expire }
53
+ if get
54
+ entry = self.find(:first, :conditions => ["ckey=?",key])
55
+ entry.nil? ? self.create(attributes) : entry.update_attributes(attributes)
56
+ else
57
+ self.create(attributes)
58
+ end
59
+ true
60
+ end
61
+
62
+ # Expire the cache entry identified by the given key
63
+ #
64
+ # ==== Parameter
65
+ # key<Sting>:: The key identifying the cache entry
66
+ def self.expire(key)
67
+ self.delete_all(["ckey=?", key])
68
+ end
69
+
70
+ # Expire the cache entries matching the given key
71
+ #
72
+ # ==== Parameter
73
+ # key<Sting>:: The key matching the cache entries
74
+ def self.expire_match(key)
75
+ self.delete_all(["ckey like ?", key + "%"])
76
+ end
77
+
78
+ # Expire all the cache entries
79
+ def self.expire_all
80
+ self.delete_all
81
+ end
82
+
83
+ # Perform auto-migration in case the table is unknown in the database
84
+ def self.check_table
85
+ CacheMigration.up unless self.table_exists?
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,79 @@
1
+ module Merb::Cache::DatabaseStore::DataMapper
2
+ # Module that provides DataMapper support for the database backend
3
+
4
+ # The cache model
5
+ class CacheModel < DataMapper::Base
6
+ set_table_name Merb::Controller._cache.config[:table_name]
7
+ property :ckey, :string, :length => 255, :lazy => false, :key => true
8
+ property :data, :text, :lazy => false
9
+ property :expire, :datetime, :default => nil
10
+
11
+ # Fetch data from the database using the specified key
12
+ # The entry is deleted if it has expired
13
+ #
14
+ # ==== Parameter
15
+ # key<Sting>:: The key identifying the cache entry
16
+ #
17
+ # ==== Returns
18
+ # data<String, NilClass>::
19
+ # nil is returned whether the entry expired or was not found
20
+ def self.cache_get(key)
21
+ if entry = self.first(key)
22
+ return entry.data if entry.expire.nil? || DateTime.now < entry.expire
23
+ entry.destroy!
24
+ end
25
+ nil
26
+ end
27
+
28
+ # Store data to the database using the specified key
29
+ #
30
+ # ==== Parameters
31
+ # key<Sting>:: The key identifying the cache entry
32
+ # data<String>:: The data to be put in cache
33
+ # expire<~minutes>::
34
+ # The number of minutes (from now) the cache should persist
35
+ # get<Boolean>::
36
+ # used internally to behave like this:
37
+ # - when set to true, perform update_or_create on the cache entry
38
+ # - when set to false, force creation of the cache entry
39
+ def self.cache_set(key, data, expire = nil, get = true)
40
+ attributes = {:ckey => key, :data => data,
41
+ :expire => expire.nil? ? nil : expire.to_s_db }
42
+ if get
43
+ entry = self.first(key)
44
+ entry.nil? ? self.create(attributes) : entry.update_attributes(attributes)
45
+ else
46
+ self.create(attributes)
47
+ end
48
+ true
49
+ end
50
+
51
+ # Expire the cache entry identified by the given key
52
+ #
53
+ # ==== Parameter
54
+ # key<Sting>:: The key identifying the cache entry
55
+ def self.expire(key)
56
+ entry = self.first(key)
57
+ entry.destroy! unless entry.nil?
58
+ end
59
+
60
+ # Expire the cache entries matching the given key
61
+ #
62
+ # ==== Parameter
63
+ # key<Sting>:: The key matching the cache entries
64
+ def self.expire_match(key)
65
+ #FIXME
66
+ database.execute("DELETE FROM #{self.table.name} WHERE ckey LIKE '#{key}%'")
67
+ end
68
+
69
+ # Expire all the cache entries
70
+ def self.expire_all
71
+ self.truncate!
72
+ end
73
+
74
+ # Perform auto-migration in case the table is unknown in the database
75
+ def self.check_table
76
+ self.auto_migrate! unless self.table.exists?
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,78 @@
1
+ module Merb::Cache::DatabaseStore::Sequel
2
+ # Module that provides Sequel support for the database backend
3
+
4
+ # The cache model
5
+ class CacheModel < Sequel::Model(Merb::Controller._cache.config[:table_name].to_sym)
6
+ set_schema do
7
+ primary_key :id
8
+ varchar :ckey, :index => true
9
+ varchar :data
10
+ timestamp :expire, :default => nil
11
+ end
12
+
13
+ # Fetch data from the database using the specified key
14
+ # The entry is deleted if it has expired
15
+ #
16
+ # ==== Parameter
17
+ # key<Sting>:: The key identifying the cache entry
18
+ #
19
+ # ==== Returns
20
+ # data<String, NilClass>::
21
+ # nil is returned whether the entry expired or was not found
22
+ def self.cache_get(key)
23
+ if entry = self.filter(:ckey => key).single_record(:limit => 1)
24
+ return entry.data if entry.expire.nil? || Time.now < entry.expire
25
+ self.expire(key)
26
+ end
27
+ nil
28
+ end
29
+
30
+ # Store data to the database using the specified key
31
+ #
32
+ # ==== Parameters
33
+ # key<Sting>:: The key identifying the cache entry
34
+ # data<String>:: The data to be put in cache
35
+ # expire<~minutes>::
36
+ # The number of minutes (from now) the cache should persist
37
+ # get<Boolean>::
38
+ # used internally to behave like this
39
+ # - when set to true, perform update_or_create on the cache entry
40
+ # - when set to false, force creation of the cache entry
41
+ def self.cache_set(key, data, expire = nil, get = true)
42
+ attributes = {:ckey => key, :data => data, :expire => expire }
43
+ if get
44
+ entry = self.filter(:ckey => key).single_record(:limit => 1)
45
+ entry.nil? ? self.create(attributes) : entry.set(attributes)
46
+ else
47
+ self.create(attributes)
48
+ end
49
+ true
50
+ end
51
+
52
+ # Expire the cache entry identified by the given key
53
+ #
54
+ # ==== Parameter
55
+ # key<Sting>:: The key identifying the cache entry
56
+ def self.expire(key)
57
+ self.filter(:ckey => key).delete
58
+ end
59
+
60
+ # Expire the cache entries matching the given key
61
+ #
62
+ # ==== Parameter
63
+ # key<Sting>:: The key matching the cache entries
64
+ def self.expire_match(key)
65
+ self.filter{:ckey.like key + "%"}.delete
66
+ end
67
+
68
+ # Expire all the cache entries
69
+ def self.expire_all
70
+ self.delete_all
71
+ end
72
+
73
+ # Perform auto-migration in case the table is unknown in the database
74
+ def self.check_table
75
+ self.create_table unless self.table_exists?
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,144 @@
1
+ class Merb::Cache::DatabaseStore
2
+ # Provides the database cache store for merb-cache
3
+
4
+ def initialize
5
+ @config = Merb::Controller._cache.config
6
+ prepare
7
+ end
8
+
9
+ class OrmNotFound < Exception #:nodoc:
10
+ def initialize
11
+ super("No valid ORM found (did you specify use_orm in init.rb?)")
12
+ end
13
+ end
14
+
15
+ # Requires the ORM at startup, raising an OrmNotFound exception if
16
+ # the backend is not found
17
+ Merb::Controller._cache.config[:table_name] ||= "merb_cache"
18
+ if defined?(Merb::Orms::ActiveRecord)
19
+ require "merb-cache/cache-store/database-activerecord.rb"
20
+ include Merb::Cache::DatabaseStore::ActiveRecord
21
+ elsif defined?(Merb::Orms::DataMapper)
22
+ require "merb-cache/cache-store/database-datamapper.rb"
23
+ include Merb::Cache::DatabaseStore::DataMapper
24
+ elsif defined?(Merb::Orms::Sequel)
25
+ require "merb-cache/cache-store/database-sequel.rb"
26
+ include Merb::Cache::DatabaseStore::Sequel
27
+ else
28
+ raise OrmNotFound
29
+ end
30
+
31
+ # This method is there to ensure minimal requirements are met
32
+ # (file permissions, table exists, connected to server, ...)
33
+ def prepare
34
+ CacheModel.check_table
35
+ true
36
+ end
37
+
38
+ # Checks whether a cache entry exists
39
+ #
40
+ # ==== Parameter
41
+ # key<String>:: The key identifying the cache entry
42
+ #
43
+ # ==== Returns
44
+ # true if the cache entry exists, false otherwise
45
+ def cached?(key)
46
+ not CacheModel.cache_get(key).nil?
47
+ end
48
+
49
+ # Capture or restore the data in cache.
50
+ # If the cache entry expired or does not exist, the data are taken
51
+ # from the execution of the block, marshalled and stored in cache.
52
+ # Otherwise, the data are loaded from the cache and returned unmarshalled
53
+ #
54
+ # ==== Parameters
55
+ # _controller<Merb::Controller>:: The instance of the current controller
56
+ # key<String>:: The key identifying the cache entry
57
+ # from_now<~minutes>::
58
+ # The number of minutes (from now) the cache should persist
59
+ # &block:: The template to be used or not
60
+ #
61
+ # ==== Additional information
62
+ # When fetching data (the cache entry exists and has not expired)
63
+ # The data are loaded from the cache and returned unmarshalled.
64
+ # Otherwise:
65
+ # The controller is used to capture the rendered template (from the block).
66
+ # It uses the capture_#{engine} and concat_#{engine} methods to do so.
67
+ # The captured data are then marshalled and stored.
68
+ def cache(_controller, key, from_now = nil, &block)
69
+ _data = CacheModel.cache_get(key)
70
+ if _data.nil?
71
+ _expire = from_now ? from_now.minutes.from_now : nil
72
+ _data = _controller.send(:capture, &block)
73
+ CacheModel.cache_set(key, Marshal.dump(_data), _expire, false)
74
+ else
75
+ _data = Marshal.load(_data)
76
+ end
77
+ _controller.send(:concat, _data, block.binding)
78
+ true
79
+ end
80
+
81
+ # Store data to the database using the specified key
82
+ #
83
+ # ==== Parameters
84
+ # key<Sting>:: The key identifying the cache entry
85
+ # data<String>:: The data to be put in cache
86
+ # from_now<~minutes>::
87
+ # The number of minutes (from now) the cache should persist
88
+ def cache_set(key, data, from_now = nil)
89
+ _expire = from_now ? from_now.minutes.from_now : nil
90
+ CacheModel.cache_set(key, Marshal.dump(data), _expire)
91
+ Merb.logger.info("cache: set (#{key})")
92
+ true
93
+ end
94
+
95
+ # Fetch data from the database using the specified key
96
+ # The entry is deleted if it has expired
97
+ #
98
+ # ==== Parameter
99
+ # key<Sting>:: The key identifying the cache entry
100
+ #
101
+ # ==== Returns
102
+ # data<String, NilClass>::
103
+ # nil is returned whether the entry expired or was not found
104
+ def cache_get(key)
105
+ data = CacheModel.cache_get(key)
106
+ Merb.logger.info("cache: #{data.nil? ? "miss" : "hit"} (#{key})")
107
+ data.nil? ? nil : Marshal.load(data)
108
+ end
109
+
110
+ # Expire the cache entry identified by the given key
111
+ #
112
+ # ==== Parameter
113
+ # key<Sting>:: The key identifying the cache entry
114
+ def expire(key)
115
+ CacheModel.expire(key)
116
+ Merb.logger.info("cache: expired (#{key})")
117
+ true
118
+ end
119
+
120
+ # Expire the cache entries matching the given key
121
+ #
122
+ # ==== Parameter
123
+ # key<Sting>:: The key matching the cache entries
124
+ def expire_match(key)
125
+ CacheModel.expire_match(key)
126
+ Merb.logger.info("cache: expired matching (#{key})")
127
+ true
128
+ end
129
+
130
+ # Expire all the cache entries
131
+ def expire_all
132
+ CacheModel.expire_all
133
+ Merb.logger.info("cache: expired all")
134
+ true
135
+ end
136
+
137
+ # Gives info on the current cache store
138
+ #
139
+ # ==== Returns
140
+ # The type of the current cache store
141
+ def cache_store_type
142
+ "database"
143
+ end
144
+ end
@@ -0,0 +1,106 @@
1
+ class Merb::Cache::DummyStore
2
+ # Provides dummy cache store for merb-cache
3
+
4
+ def initialize
5
+ @config = Merb::Controller._cache.config
6
+ prepare
7
+ end
8
+
9
+ # This method is there to ensure minimal requirements are met
10
+ # (directories are accessible, table exists, connected to server, ...)
11
+ def prepare
12
+ true
13
+ end
14
+
15
+ # Checks whether a cache entry exists
16
+ #
17
+ # ==== Parameter
18
+ # key<String>:: The key identifying the cache entry
19
+ #
20
+ # ==== Returns
21
+ # true if the cache entry exists, false otherwise
22
+ def cached?(key)
23
+ false
24
+ end
25
+
26
+ # Capture or restore the data in cache.
27
+ # If the cache entry expired or does not exist, the data are taken
28
+ # from the execution of the block, marshalled and stored in cache.
29
+ # Otherwise, the data are loaded from the cache and returned unmarshalled
30
+ #
31
+ # ==== Parameters
32
+ # _controller<Merb::Controller>:: The instance of the current controller
33
+ # key<String>:: The key identifying the cache entry
34
+ # from_now<~minutes>::
35
+ # The number of minutes (from now) the cache should persist
36
+ # &block:: The template to be used or not
37
+ #
38
+ # ==== Additional information
39
+ # When fetching data (the cache entry exists and has not expired)
40
+ # The data are loaded from the cache and returned unmarshalled.
41
+ # Otherwise:
42
+ # The controller is used to capture the rendered template (from the block).
43
+ # It uses the capture_#{engine} and concat_#{engine} methods to do so.
44
+ # The captured data are then marshalled and stored.
45
+ def cache(_controller, key, from_now = nil, &block)
46
+ _data = _controller.send(:capture, &block)
47
+ _controller.send(:concat, _data, block.binding)
48
+ true
49
+ end
50
+
51
+ # Store data to memcache using the specified key
52
+ #
53
+ # ==== Parameters
54
+ # key<Sting>:: The key identifying the cache entry
55
+ # data<String>:: The data to be put in cache
56
+ # from_now<~minutes>::
57
+ # The number of minutes (from now) the cache should persist
58
+ def cache_set(key, data, from_now = nil)
59
+ true
60
+ end
61
+
62
+ # Fetch data from memcache using the specified key
63
+ # The entry is deleted if it has expired
64
+ #
65
+ # ==== Parameter
66
+ # key<Sting>:: The key identifying the cache entry
67
+ #
68
+ # ==== Returns
69
+ # data<String, NilClass>::
70
+ # nil is returned whether the entry expired or was not found
71
+ def cache_get(key)
72
+ nil
73
+ end
74
+
75
+ # Expire the cache entry identified by the given key
76
+ #
77
+ # ==== Parameter
78
+ # key<Sting>:: The key identifying the cache entry
79
+ def expire(key)
80
+ true
81
+ end
82
+
83
+ # Expire the cache entries matching the given key
84
+ #
85
+ # ==== Parameter
86
+ # key<Sting>:: The key matching the cache entries
87
+ #
88
+ # ==== Warning !
89
+ # This does not work in memcache.
90
+ def expire_match(key)
91
+ true
92
+ end
93
+
94
+ # Expire all the cache entries
95
+ def expire_all
96
+ true
97
+ end
98
+
99
+ # Gives info on the current cache store
100
+ #
101
+ # ==== Returns
102
+ # The type of the current cache store
103
+ def cache_store_type
104
+ "dummy"
105
+ end
106
+ end
@@ -0,0 +1,192 @@
1
+ class Merb::Cache::FileStore
2
+ # Provides the file cache store for merb-cache
3
+
4
+ def initialize
5
+ @config = Merb::Controller._cache.config
6
+ @config[:cache_directory] ||= Merb.root_path("tmp/cache")
7
+ # @config[:cache_action_directory] ||= Merb.dir_for(:public) / "cache"
8
+ prepare
9
+ end
10
+
11
+ class NotAccessible < Exception #:nodoc:
12
+ def initialize(message)
13
+ super("Cache directories are not readable/writeable (#{message})")
14
+ end
15
+ end
16
+
17
+ # This method is there to ensure minimal requirements are met
18
+ # (directories are accessible, table exists, connected to server, ...)
19
+ def prepare
20
+ unless File.readable?(@config[:cache_directory]) &&
21
+ File.writable?(@config[:cache_directory])
22
+ raise NotAccessible, @config[:cache_directory]
23
+ end
24
+ true
25
+ end
26
+
27
+ # Checks whether a cache entry exists
28
+ #
29
+ # ==== Parameter
30
+ # key<String>:: The key identifying the cache entry
31
+ #
32
+ # ==== Returns
33
+ # true if the cache entry exists, false otherwise
34
+ def cached?(key)
35
+ cache_file = @config[:cache_directory] / "#{key}.cache"
36
+ _data = _expire = nil
37
+ if File.file?(cache_file)
38
+ _data, _expire = Marshal.load(cache_read(cache_file))
39
+ return true if _expire.nil? || Time.now < _expire
40
+ FileUtils.rm_f(cache_file)
41
+ end
42
+ false
43
+ end
44
+
45
+ # Capture or restore the data in cache.
46
+ # If the cache entry expired or does not exist, the data are taken
47
+ # from the execution of the block, marshalled and stored in cache.
48
+ # Otherwise, the data are loaded from the cache and returned unmarshalled
49
+ #
50
+ # ==== Parameters
51
+ # _controller<Merb::Controller>:: The instance of the current controller
52
+ # key<String>:: The key identifying the cache entry
53
+ # from_now<~minutes>::
54
+ # The number of minutes (from now) the cache should persist
55
+ # &block:: The template to be used or not
56
+ #
57
+ # ==== Additional information
58
+ # When fetching data (the cache entry exists and has not expired)
59
+ # The data are loaded from the cache and returned unmarshalled.
60
+ # Otherwise:
61
+ # The controller is used to capture the rendered template (from the block).
62
+ # It uses the capture_#{engine} and concat_#{engine} methods to do so.
63
+ # The captured data are then marshalled and stored.
64
+ def cache(_controller, key, from_now = nil, &block)
65
+ cache_file = @config[:cache_directory] / "#{key}.cache"
66
+ _cache_hit = _data = _expire = nil
67
+
68
+ if File.file?(cache_file)
69
+ _data, _expire = Marshal.load(cache_read(cache_file))
70
+ _cache_hit = true if _expire.nil? || Time.now < _expire
71
+ end
72
+ unless _cache_hit
73
+ cache_directory = File.dirname(cache_file)
74
+ FileUtils.mkdir_p(cache_directory)
75
+ _expire = from_now ? from_now.minutes.from_now : nil
76
+ _data = _controller.send(:capture, &block)
77
+ cache_write(cache_file, Marshal.dump([_data, _expire]))
78
+ end
79
+ _controller.send(:concat, _data, block.binding)
80
+ true
81
+ end
82
+
83
+ # Store data to the file using the specified key
84
+ #
85
+ # ==== Parameters
86
+ # key<Sting>:: The key identifying the cache entry
87
+ # data<String>:: The data to be put in cache
88
+ # from_now<~minutes>::
89
+ # The number of minutes (from now) the cache should persist
90
+ def cache_set(key, data, from_now = nil)
91
+ cache_file = @config[:cache_directory] / "#{key}.cache"
92
+ cache_directory = File.dirname(cache_file)
93
+ FileUtils.mkdir_p(cache_directory)
94
+ _expire = from_now ? from_now.minutes.from_now : nil
95
+ cache_write(cache_file, Marshal.dump([data, _expire]))
96
+ Merb.logger.info("cache: set (#{key})")
97
+ true
98
+ end
99
+
100
+ # Fetch data from the file using the specified key
101
+ # The entry is deleted if it has expired
102
+ #
103
+ # ==== Parameter
104
+ # key<Sting>:: The key identifying the cache entry
105
+ #
106
+ # ==== Returns
107
+ # data<String, NilClass>::
108
+ # nil is returned whether the entry expired or was not found
109
+ def cache_get(key)
110
+ cache_file = @config[:cache_directory] / "#{key}.cache"
111
+ if File.file?(cache_file)
112
+ _data, _expire = Marshal.load(cache_read(cache_file))
113
+ if _expire.nil? || Time.now < _expire
114
+ Merb.logger.info("cache: hit (#{key})")
115
+ return _data
116
+ end
117
+ FileUtils.rm_f(cache_file)
118
+ end
119
+ Merb.logger.info("cache: miss (#{key})")
120
+ nil
121
+ end
122
+
123
+ # Expire the cache entry identified by the given key
124
+ #
125
+ # ==== Parameter
126
+ # key<Sting>:: The key identifying the cache entry
127
+ def expire(key)
128
+ FileUtils.rm_f(@config[:cache_directory] / "#{key}.cache")
129
+ Merb.logger.info("cache: expired (#{key})")
130
+ true
131
+ end
132
+
133
+ # Expire the cache entries matching the given key
134
+ #
135
+ # ==== Parameter
136
+ # key<Sting>:: The key matching the cache entries
137
+ def expire_match(key)
138
+ #files = Dir.glob(@config[:cache_directory] / "#{key}*.cache")
139
+ files = Dir.glob(@config[:cache_directory] / "#{key}*")
140
+ FileUtils.rm_rf(files)
141
+ Merb.logger.info("cache: expired matching (#{key})")
142
+ true
143
+ end
144
+
145
+ # Expire all the cache entries
146
+ def expire_all
147
+ FileUtils.rm_rf(Dir.glob("#{@config[:cache_directory]}/*"))
148
+ Merb.logger.info("cache: expired all")
149
+ true
150
+ end
151
+
152
+ # Gives info on the current cache store
153
+ #
154
+ # ==== Returns
155
+ # The type of the current cache store
156
+ def cache_store_type
157
+ "file"
158
+ end
159
+
160
+ private
161
+
162
+ # Read data from the file using exclusive lock
163
+ #
164
+ # ==== Parameters
165
+ # cache_file<String>:: The full path to the file
166
+ #
167
+ # ==== Returns
168
+ # _data<String>:: The data read from the file
169
+ def cache_read(cache_file)
170
+ _data = nil
171
+ File.open(cache_file, "r") do |cache_data|
172
+ cache_data.flock(File::LOCK_EX)
173
+ _data = cache_data.read
174
+ cache_data.flock(File::LOCK_UN)
175
+ end
176
+ _data
177
+ end
178
+
179
+ # Write data to the file using exclusive lock
180
+ #
181
+ # ==== Parameters
182
+ # cache_file<String>:: The full path to the file
183
+ # data<String>:: The data to be put in cache
184
+ def cache_write(cache_file, data)
185
+ File.open(cache_file, "w+") do |cache_data|
186
+ cache_data.flock(File::LOCK_EX)
187
+ cache_data.write(data)
188
+ cache_data.flock(File::LOCK_UN)
189
+ end
190
+ true
191
+ end
192
+ end