frivol 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,8 +1,69 @@
1
- = Frivol
1
+ = Frivol - Frivolously simple temporary storage backed by Redis
2
+ A really simple Redis-backed temporary storage mechanism intended to be used with ActiveRecord,
3
+ but will work with other ORM's or any classes really.
2
4
 
3
- A really simple Redis-backed temporary storage mechanism.
5
+ I developed Frivol secifically for use in Mad Mimi (http://madmimi.com) to help with caching
6
+ of data which requires fairly long running (multi-second) database queries, and also to help
7
+ with communication of status from background tasks running in Resque on workers to the front
8
+ end web servers. Redis was chosen because we already had Resque, which is Redis-backed. Also,
9
+ unlike memcached, Redis persists it's data to disk, meaning there is far less warmup required
10
+ when a hot system is restarted. Frivol's design is such that it solves our problem, but I
11
+ believe it is generic enough to be used in many Rails web projects and even in other types of
12
+ projects altogether.
13
+
14
+ == Usage
15
+ Configure Frivol in your configuration, for example in an initializer or in environment.rb
16
+ REDIS_CONFIG = {
17
+ :host => "localhost",
18
+ :port => 6379
19
+ }
20
+ Frivol::Config.redis_config = REDIS_CONFIG
21
+ Now include Frivol in whichever classes you'd like to make use of temporary storage. You can optionally
22
+ call the <tt>storage_expires_in(time)</tt> class method to set a default expiry. In your methods you can
23
+ now call the <tt>store(keys_and_values)</tt> and <tt>retrieve(keys_and_defaults)</tt> methods.
24
+
25
+ Defaults in the +retrieve+ method can be symbols, in which case Frivol will check if the class <tt>respond_to?</tt>
26
+ a method by that name to get the default.
27
+
28
+ The <tt>expire_storage(time)</tt> method can be used to set the expiry time in seconds of the temporary storage.
29
+ The default is not to expire the storage, in which case it will live for as long as Redis keeps it.
30
+
31
+ Frivol uses the +storage_key+ method to create a base key for storage in Redis. The current implementation uses
32
+ <tt>"#{self.class.name}-#{id}"</tt> so you'll want to override that method if you have classes that don't
33
+ respond to id.
34
+
35
+ Frivol also extends Time to allow it to be (de)serialized to JSON, which currently used to store
36
+ data in Redis.
37
+ == Example
38
+ class BigComplexCalcer
39
+ include Frivol
40
+ storage_expires_in 600 # temporary storage expires in 10 minutes.
41
+
42
+ def initialize(key)
43
+ @key = key
44
+ end
45
+
46
+ def storage_key
47
+ "frivol-test-#{key}" # override the storage key because we don't respond_to? id
48
+ end
49
+
50
+ def big_complex_calc
51
+ retrieve :complex => :do_big_complex_calc # do_big_complex_calc is the method to get the default from
52
+ end
53
+
54
+ def last_calc_done
55
+ last = retrieve :last => nil # default is nil
56
+ return "never" if last.nil?
57
+ return "#{Time.now - last} seconds ago"
58
+ end
59
+
60
+ def do_big_complex_calc
61
+ # Wee! Do some really hard work here...
62
+ # ...still working...
63
+ store :complex => result, :last => Time.now # ...and let's keep the result for at least 10 minutes, as well as the last time we did it
64
+ end
65
+ end
4
66
 
5
- Also extends Time to allow it to be (de)serialized to JSON.
6
67
 
7
68
  == Note on Patches/Pull Requests
8
69
 
data/Rakefile CHANGED
@@ -10,7 +10,9 @@ begin
10
10
  gem.email = "marc@eternal.co.za"
11
11
  gem.homepage = "http://github.com/marcheiligers/frivol"
12
12
  gem.authors = ["Marc Heiligers"]
13
- gem.add_development_dependency "shoulda", ">= 2"
13
+ gem.add_dependency "json", ">= 1.2.0"
14
+ gem.add_dependency "redis", ">= 0.1.2"
15
+ gem.add_development_dependency "shoulda", ">= 2.11.1"
14
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
17
  end
16
18
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
@@ -0,0 +1,303 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Module: Frivol</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Module</strong></td>
53
+ <td class="class-name-in-header">Frivol</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../files/lib/frivol_rb.html">
59
+ lib/frivol.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ </table>
66
+ </div>
67
+ <!-- banner header -->
68
+
69
+ <div id="bodyContent">
70
+
71
+
72
+
73
+ <div id="contextContent">
74
+
75
+ <div id="description">
76
+ <h2><a href="Frivol.html">Frivol</a></h2>
77
+
78
+ </div>
79
+
80
+
81
+ </div>
82
+
83
+ <div id="method-list">
84
+ <h3 class="section-bar">Methods</h3>
85
+
86
+ <div class="name-list">
87
+ <a href="#M000005">delete_storage</a>&nbsp;&nbsp;
88
+ <a href="#M000006">expire_storage</a>&nbsp;&nbsp;
89
+ <a href="#M000004">retrieve</a>&nbsp;&nbsp;
90
+ <a href="#M000007">storage_key</a>&nbsp;&nbsp;
91
+ <a href="#M000003">store</a>&nbsp;&nbsp;
92
+ </div>
93
+ </div>
94
+
95
+ </div>
96
+
97
+
98
+ <!-- if includes -->
99
+
100
+ <div id="section">
101
+
102
+ <div id="class-list">
103
+ <h3 class="section-bar">Classes and Modules</h3>
104
+
105
+ Module <a href="Frivol/ClassMethods.html" class="link">Frivol::ClassMethods</a><br />
106
+ Module <a href="Frivol/Config.html" class="link">Frivol::Config</a><br />
107
+
108
+ </div>
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+ <!-- if method_list -->
117
+ <div id="methods">
118
+ <h3 class="section-bar">Public Instance methods</h3>
119
+
120
+ <div id="method-M000005" class="method-detail">
121
+ <a name="M000005"></a>
122
+
123
+ <div class="method-heading">
124
+ <a href="#M000005" class="method-signature">
125
+ <span class="method-name">delete_storage</span><span class="method-args">()</span>
126
+ </a>
127
+ </div>
128
+
129
+ <div class="method-description">
130
+ <p>
131
+ Deletes the stored values.
132
+ </p>
133
+ <p><a class="source-toggle" href="#"
134
+ onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
135
+ <div class="method-source-code" id="M000005-source">
136
+ <pre>
137
+ <span class="ruby-comment cmt"># File lib/frivol.rb, line 105</span>
138
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">delete_storage</span>
139
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">delete_hash</span> <span class="ruby-keyword kw">self</span>
140
+ <span class="ruby-keyword kw">end</span>
141
+ </pre>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <div id="method-M000006" class="method-detail">
147
+ <a name="M000006"></a>
148
+
149
+ <div class="method-heading">
150
+ <a href="#M000006" class="method-signature">
151
+ <span class="method-name">expire_storage</span><span class="method-args">(time)</span>
152
+ </a>
153
+ </div>
154
+
155
+ <div class="method-description">
156
+ <p>
157
+ Expire the stored data in <tt>time</tt> seconds.
158
+ </p>
159
+ <p><a class="source-toggle" href="#"
160
+ onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
161
+ <div class="method-source-code" id="M000006-source">
162
+ <pre>
163
+ <span class="ruby-comment cmt"># File lib/frivol.rb, line 110</span>
164
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">expire_storage</span>(<span class="ruby-identifier">time</span>)
165
+ <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">time</span>.<span class="ruby-identifier">nil?</span>
166
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Config</span>.<span class="ruby-identifier">redis</span>.<span class="ruby-identifier">expire</span> <span class="ruby-identifier">storage_key</span>, <span class="ruby-identifier">time</span>
167
+ <span class="ruby-keyword kw">end</span>
168
+ </pre>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <div id="method-M000004" class="method-detail">
174
+ <a name="M000004"></a>
175
+
176
+ <div class="method-heading">
177
+ <a href="#M000004" class="method-signature">
178
+ <span class="method-name">retrieve</span><span class="method-args">(keys_and_defaults)</span>
179
+ </a>
180
+ </div>
181
+
182
+ <div class="method-description">
183
+ <p>
184
+ Retrieve stored values, or defaults.
185
+ </p>
186
+ <p>
187
+ If you <a href="Frivol.html#M000004">retrieve</a> a single key just that
188
+ value is returned. If you <a href="Frivol.html#M000004">retrieve</a>
189
+ multiple keys an array of values is returned. You might do:
190
+ </p>
191
+ <pre>
192
+ name = retrieve :name =&gt; &quot;Marc Heiligers&quot;
193
+ first_name, last_name = retrieve :first_name =&gt; &quot;Marc&quot;, :last_name =&gt; &quot;Heiligers&quot;
194
+ </pre>
195
+ <p>
196
+ If the default is a symbol, <a href="Frivol.html">Frivol</a> will attempt
197
+ to get the default from a method named after that symbol. If the class does
198
+ not <tt>respond_to?</tt> a method by that name, the symbol will assumed to
199
+ be the default.
200
+ </p>
201
+ <p><a class="source-toggle" href="#"
202
+ onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
203
+ <div class="method-source-code" id="M000004-source">
204
+ <pre>
205
+ <span class="ruby-comment cmt"># File lib/frivol.rb, line 95</span>
206
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">retrieve</span>(<span class="ruby-identifier">keys_and_defaults</span>)
207
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">retrieve_hash</span> <span class="ruby-keyword kw">self</span>
208
+ <span class="ruby-identifier">result</span> = <span class="ruby-identifier">keys_and_defaults</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">default</span><span class="ruby-operator">|</span>
209
+ <span class="ruby-ivar">@frivol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_s</span>] <span class="ruby-operator">||</span> (<span class="ruby-identifier">default</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">default</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">send</span>(<span class="ruby-identifier">default</span>)) <span class="ruby-operator">||</span> <span class="ruby-identifier">default</span>
210
+ <span class="ruby-keyword kw">end</span>
211
+ <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">first</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>
212
+ <span class="ruby-identifier">result</span>
213
+ <span class="ruby-keyword kw">end</span>
214
+ </pre>
215
+ </div>
216
+ </div>
217
+ </div>
218
+
219
+ <div id="method-M000007" class="method-detail">
220
+ <a name="M000007"></a>
221
+
222
+ <div class="method-heading">
223
+ <a href="#M000007" class="method-signature">
224
+ <span class="method-name">storage_key</span><span class="method-args">()</span>
225
+ </a>
226
+ </div>
227
+
228
+ <div class="method-description">
229
+ <p>
230
+ The base key used for storage in Redis.
231
+ </p>
232
+ <p>
233
+ This method has been implemented for use with ActiveRecord and uses
234
+ <tt>&quot;#{self.class.name}-#{id}&quot;</tt> If you are not using
235
+ ActiveRecord, or using classes that don&#8216;t respond to id, you should
236
+ override this method in your class.
237
+ </p>
238
+ <p><a class="source-toggle" href="#"
239
+ onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
240
+ <div class="method-source-code" id="M000007-source">
241
+ <pre>
242
+ <span class="ruby-comment cmt"># File lib/frivol.rb, line 120</span>
243
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">storage_key</span>
244
+ <span class="ruby-ivar">@frivol_key</span> <span class="ruby-operator">||=</span> <span class="ruby-node">&quot;#{self.class.name}-#{id}&quot;</span>
245
+ <span class="ruby-keyword kw">end</span>
246
+ </pre>
247
+ </div>
248
+ </div>
249
+ </div>
250
+
251
+ <div id="method-M000003" class="method-detail">
252
+ <a name="M000003"></a>
253
+
254
+ <div class="method-heading">
255
+ <a href="#M000003" class="method-signature">
256
+ <span class="method-name">store</span><span class="method-args">(keys_and_values)</span>
257
+ </a>
258
+ </div>
259
+
260
+ <div class="method-description">
261
+ <p>
262
+ Store a hash of keys and values.
263
+ </p>
264
+ <p>
265
+ The hash need not be the complete hash of all things stored, just those you
266
+ want to change. For example, you may call <tt><a
267
+ href="Frivol.html#M000003">store</a> :value1 =&gt; 1</tt> and then later
268
+ call <tt><a href="Frivol.html#M000003">store</a> :value2 =&gt; 2</tt> and
269
+ <a href="Frivol.html">Frivol</a> will now have stored <tt>{ :value1 =&gt;
270
+ 1, :value =&gt; 2 }</tt>. How <a href="Frivol.html">Frivol</a> stores or
271
+ retrieves data is intended to be hidden and while it is true that it
272
+ currently uses a <tt>Hash#to_json</tt> you should not rely on this.
273
+ </p>
274
+ <p><a class="source-toggle" href="#"
275
+ onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
276
+ <div class="method-source-code" id="M000003-source">
277
+ <pre>
278
+ <span class="ruby-comment cmt"># File lib/frivol.rb, line 78</span>
279
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">store</span>(<span class="ruby-identifier">keys_and_values</span>)
280
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">retrieve_hash</span> <span class="ruby-keyword kw">self</span>
281
+ <span class="ruby-identifier">keys_and_values</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
282
+ <span class="ruby-ivar">@frivol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_s</span>] = <span class="ruby-identifier">value</span>
283
+ <span class="ruby-keyword kw">end</span>
284
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">store_hash</span> <span class="ruby-keyword kw">self</span>
285
+ <span class="ruby-keyword kw">end</span>
286
+ </pre>
287
+ </div>
288
+ </div>
289
+ </div>
290
+
291
+
292
+ </div>
293
+
294
+
295
+ </div>
296
+
297
+
298
+ <div id="validator-badges">
299
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
300
+ </div>
301
+
302
+ </body>
303
+ </html>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <title>store (Frivol)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre><span class="ruby-comment cmt"># File lib/frivol.rb, line 68</span>
14
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">store</span>(<span class="ruby-identifier">keys_and_values</span>)
15
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">retrieve_hash</span> <span class="ruby-keyword kw">self</span>
16
+ <span class="ruby-identifier">keys_and_values</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
17
+ <span class="ruby-ivar">@frivol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_s</span>] = <span class="ruby-identifier">value</span>
18
+ <span class="ruby-keyword kw">end</span>
19
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">store_hash</span> <span class="ruby-keyword kw">self</span>
20
+ <span class="ruby-keyword kw">end</span></pre>
21
+ </body>
22
+ </html>
@@ -0,0 +1,23 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <title>retrieve (Frivol)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre><span class="ruby-comment cmt"># File lib/frivol.rb, line 85</span>
14
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">retrieve</span>(<span class="ruby-identifier">keys_and_defaults</span>)
15
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Helpers</span>.<span class="ruby-identifier">retrieve_hash</span> <span class="ruby-keyword kw">self</span>
16
+ <span class="ruby-identifier">result</span> = <span class="ruby-identifier">keys_and_defaults</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">default</span><span class="ruby-operator">|</span>
17
+ <span class="ruby-ivar">@frivol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_s</span>] <span class="ruby-operator">||</span> (<span class="ruby-identifier">default</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">default</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">send</span>(<span class="ruby-identifier">default</span>)) <span class="ruby-operator">||</span> <span class="ruby-identifier">default</span>
18
+ <span class="ruby-keyword kw">end</span>
19
+ <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">first</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span>
20
+ <span class="ruby-identifier">result</span>
21
+ <span class="ruby-keyword kw">end</span></pre>
22
+ </body>
23
+ </html>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <title>expire_storage (Frivol)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre><span class="ruby-comment cmt"># File lib/frivol.rb, line 95</span>
14
+ <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">expire_storage</span>(<span class="ruby-identifier">time</span>)
15
+ <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">time</span>.<span class="ruby-identifier">nil?</span>
16
+ <span class="ruby-constant">Frivol</span><span class="ruby-operator">::</span><span class="ruby-constant">Config</span>.<span class="ruby-identifier">redis</span>.<span class="ruby-identifier">expire</span> <span class="ruby-identifier">storage_key</span>, <span class="ruby-identifier">time</span>
17
+ <span class="ruby-keyword kw">end</span></pre>
18
+ </body>
19
+ </html>