needle 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/manual-html/chapter-1.html +138 -78
- data/doc/manual-html/chapter-2.html +180 -99
- data/doc/manual-html/chapter-3.html +111 -75
- data/doc/manual-html/chapter-4.html +80 -48
- data/doc/manual-html/chapter-5.html +106 -56
- data/doc/manual-html/chapter-6.html +82 -34
- data/doc/manual-html/chapter-7.html +74 -38
- data/doc/manual-html/chapter-8.html +70 -41
- data/doc/manual-html/chapter-9.html +88 -63
- data/doc/manual-html/index.html +6 -6
- data/doc/manual-html/needle.png +0 -0
- data/doc/manual-html/{manual.css → stylesheets/manual.css} +83 -10
- data/doc/manual-html/stylesheets/ruby.css +17 -0
- data/doc/manual/chapter.erb +20 -0
- data/doc/manual/img/Needle.ai +0 -0
- data/doc/manual/img/needle.png +0 -0
- data/doc/manual/manual.rb +80 -5
- data/doc/manual/manual.yml +3 -3
- data/doc/manual/page.erb +1 -1
- data/doc/manual/parts/01_use_cases.txt +70 -70
- data/doc/manual/parts/02_creating.txt +19 -19
- data/doc/manual/parts/02_namespaces.txt +29 -29
- data/doc/manual/parts/02_services.txt +40 -41
- data/doc/manual/parts/03_conventional.txt +20 -20
- data/doc/manual/parts/03_locator.txt +44 -44
- data/doc/manual/parts/04_overview.txt +1 -1
- data/doc/manual/parts/04_setup.txt +32 -32
- data/doc/manual/parts/customizing_contexts.txt +14 -14
- data/doc/manual/parts/customizing_interceptors.txt +25 -25
- data/doc/manual/parts/customizing_namespaces.txt +12 -12
- data/doc/manual/parts/interceptors_attaching.txt +29 -30
- data/doc/manual/parts/interceptors_custom.txt +16 -16
- data/doc/manual/parts/interceptors_ordering.txt +5 -5
- data/doc/manual/parts/libraries_creating.txt +18 -18
- data/doc/manual/parts/libraries_using.txt +19 -19
- data/doc/manual/parts/logging_configuration.txt +13 -13
- data/doc/manual/parts/logging_logfactory.txt +21 -22
- data/doc/manual/parts/models_models.txt +8 -8
- data/doc/manual/parts/models_overview.txt +1 -1
- data/doc/manual/parts/models_pipelines.txt +22 -22
- data/doc/manual/{manual.css → stylesheets/manual.css} +83 -10
- data/doc/manual/stylesheets/ruby.css +17 -0
- data/lib/needle/definition-context.rb +3 -2
- data/lib/needle/lifecycle/proxy.rb +1 -1
- data/lib/needle/version.rb +1 -1
- metadata +94 -85
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Needle Manual :: Chapter 6: Service Models</title>
|
4
|
-
<link type="text/css" rel="stylesheet" href="manual.css" />
|
4
|
+
<link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
|
5
5
|
</head>
|
6
6
|
|
7
7
|
<body>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.2.
|
18
|
-
Manual Last Updated: <strong>
|
17
|
+
Needle Version: <strong>1.2.1</strong><br />
|
18
|
+
Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -208,7 +208,17 @@
|
|
208
208
|
|
209
209
|
<div id="content">
|
210
210
|
|
211
|
-
|
211
|
+
<div class="top"><div class="prevnext">
|
212
|
+
|
213
|
+
<a href="chapter-5.html">Previous (5. Interceptors)</a> |
|
214
|
+
|
215
|
+
<a href="index.html">Up</a>
|
216
|
+
|
217
|
+
| <a href="chapter-7.html">Next (7. Logging)</a>
|
218
|
+
|
219
|
+
</div></div>
|
220
|
+
|
221
|
+
<h1>6. Service Models</h1>
|
212
222
|
|
213
223
|
|
214
224
|
|
@@ -220,7 +230,8 @@
|
|
220
230
|
|
221
231
|
|
222
232
|
<div class="section">
|
223
|
-
<p>Service models are the mechanism by which a client can specify how the
|
233
|
+
<p>Service models are the mechanism by which a client can specify how the lifestyle of a particular service should be managed. By default, all services are managed as <em>singletons</em>, but it is a simple matter to choose a different behavior when a service is registered.</p>
|
234
|
+
|
224
235
|
|
225
236
|
<p>Underneath, service models are implemented using an <em>instantiation pipeline</em>.</p>
|
226
237
|
</div>
|
@@ -237,11 +248,16 @@
|
|
237
248
|
<div class="section">
|
238
249
|
<p>An <em>instantiation pipeline</em> is a sequence of elements, each of which knows how to perform some aspect of the instantiation of a service.</p>
|
239
250
|
|
240
|
-
|
251
|
+
|
252
|
+
<p>Every service consists of at least one instantiation element—the block that was given when the service was registered. Other elements may be combined with this block to enforce various aspects of lifestyle management, such as <em>multiplicity</em> (singleton vs. prototype) and <em>laziness</em> (deferred vs. immediate instantiation).</p>
|
253
|
+
|
241
254
|
|
242
255
|
<h3>Standard Pipeline Elements</h3>
|
243
256
|
|
244
|
-
|
257
|
+
|
258
|
+
<p>There are six standard pipeline elements available in Needle (although you may certainly create your own):</p>
|
259
|
+
|
260
|
+
|
245
261
|
<ul>
|
246
262
|
<li><code>deferred</code>: this will always return a proxy that wraps subsequent pipeline elements, causing the subsequent elements to be executed only when a method is invoked on the proxy (at which point the method is then delegated to the resulting service).</li>
|
247
263
|
<li><code>initialize</code>: this will invoke a method on the resulting service (defaults to <code>initialize_service</code>, though it can be changed). It is used for doing final initialization of services (for services that need it).</li>
|
@@ -251,56 +267,71 @@
|
|
251
267
|
<li><code>threaded</code>: this is like the <code>singleton</code> element, but it ensures that a service is instantiated no more than once <em>per thread</em>.</li>
|
252
268
|
</ul>
|
253
269
|
|
270
|
+
|
254
271
|
<h3>Priorities</h3>
|
255
272
|
|
273
|
+
|
256
274
|
<p>Just like interceptors, pipeline elements have priorities as well. These priorities determine the order in which the elements are executed in the pipeline.</p>
|
257
275
|
|
276
|
+
|
258
277
|
<p>Each element type has a default priority, although that priority can be overridden when the element is added to the pipeline.</p>
|
259
278
|
|
279
|
+
|
260
280
|
<h3>Custom Pipeline Elements</h3>
|
261
281
|
|
282
|
+
|
262
283
|
<p>Creating new pipeline elements simple. Just create a new class that extends <code>Needle::Pipeline::Element</code>. Set the default pipeline priority (using the <code>#set_default_priority</code> class method), and then implement the <code>#call</code> method (accepting at least two parameters: the container and the service point).</p>
|
263
284
|
|
264
285
|
|
265
|
-
<
|
266
|
-
|
286
|
+
<div class='figure'>
|
287
|
+
<span class='caption'>Custom pipeline element example [ruby]</span>
|
288
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle/pipeline/element</span><span class="punct">'</span>
|
289
|
+
|
290
|
+
<span class="keyword">class </span><span class="class">MyPipelineElement</span> <span class="punct"><</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Pipeline</span><span class="punct">::</span><span class="constant">Element</span>
|
291
|
+
<span class="ident">set_default_priority</span> <span class="number">50</span>
|
292
|
+
|
293
|
+
<span class="keyword">def </span><span class="method">call</span><span class="punct">(</span> <span class="ident">container</span><span class="punct">,</span> <span class="ident">point</span><span class="punct">,</span> <span class="punct">*</span><span class="ident">args</span> <span class="punct">)</span>
|
294
|
+
<span class="punct">...</span>
|
295
|
+
<span class="ident">result</span> <span class="punct">=</span> <span class="ident">succ</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span> <span class="ident">container</span><span class="punct">,</span> <span class="ident">point</span><span class="punct">,</span> <span class="punct">*</span><span class="ident">args</span> <span class="punct">)</span>
|
296
|
+
<span class="punct">...</span>
|
297
|
+
<span class="keyword">return</span> <span class="ident">result</span>
|
298
|
+
<span class="keyword">end</span>
|
299
|
+
<span class="keyword">end</span></pre></div></td></tr></table></div></div>
|
267
300
|
|
268
|
-
class MyPipelineElement < Needle::Pipeline::Element
|
269
|
-
set_default_priority 50
|
270
301
|
|
271
|
-
def call( container, point, *args )
|
272
|
-
...
|
273
|
-
result = succ.call( container, point, *args )
|
274
|
-
...
|
275
|
-
return result
|
276
|
-
end
|
277
|
-
end
|
278
|
-
</pre>
|
279
302
|
<p>To invoke the next element of the pipeline, just invoke <code>#succ.call(...)</code>.</p>
|
280
303
|
|
304
|
+
|
281
305
|
<p>If needed, you can also implement <code>#initialize_element</code> (with no arguments), which you may invoke to perform initialization of the element. From there, you can access the options that were given to the element via the <code>#options</code> accessor.</p>
|
282
306
|
|
307
|
+
|
283
308
|
<p>See the implementations of the existing elements in <code>needle/lifecycle</code> for examples.</p>
|
284
309
|
|
310
|
+
|
285
311
|
<h3>Added Pipelines Elements to Services</h3>
|
286
312
|
|
313
|
+
|
287
314
|
<p>You can specify the pipeline elements to use for a service via the <code>:pipeline</code> option. This must refer to an array, each element of which must be either a symbol (in which case it references an element of the <code>:pipeline_elements</code> service), or a class (in which case it must implement the interface required by @Needle::Pipeline::Element).</p>
|
288
315
|
|
289
316
|
|
290
|
-
<
|
291
|
-
|
292
|
-
</pre>
|
317
|
+
<div class='figure'>
|
318
|
+
<span class='caption'>Adding pipelines to services [ruby]</span>
|
319
|
+
<div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:pipeline</span> <span class="punct">=></span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="constant">MyPipelineElement</span> <span class="punct">]</span> <span class="punct">)</span> <span class="punct">{</span> <span class="punct">...</span> <span class="punct">}</span></pre></div></div></div>
|
320
|
+
|
321
|
+
|
293
322
|
<p>The elements will be sorted based on their priorities, with lower priorities sorting closer to the instantiation block, and higher priorities sorting closer to the client.</p>
|
294
323
|
|
324
|
+
|
295
325
|
<h3>Making Custom Pipeline Elements Available</h3>
|
296
326
|
|
327
|
+
|
297
328
|
<p>You can make your custom pipeline elements available (so they can be referenced by symbol, instead of class name) by adding them to the <code>:pipeline_elements</code> service:</p>
|
298
329
|
|
299
330
|
|
300
|
-
<
|
301
|
-
|
302
|
-
|
303
|
-
</pre>
|
331
|
+
<div class='figure'>
|
332
|
+
<span class='caption'>Publishing custom pipeline elements [ruby]</span>
|
333
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">pipeline_elements</span><span class="punct">[</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span> <span class="punct">=</span> <span class="constant">MyPipelineElement</span>
|
334
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:pipeline</span> <span class="punct">=></span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span> <span class="punct">)</span> <span class="punct">{</span> <span class="punct">...</span> <span class="punct">}</span></pre></div></td></tr></table></div></div>
|
304
335
|
</div>
|
305
336
|
|
306
337
|
|
@@ -315,9 +346,11 @@
|
|
315
346
|
<div class="section">
|
316
347
|
<p>Specifying an entire pipeline for every service point can be tedious. For that reason, there are <em>service models</em>. A service model is a kind of template that names a pre-configured sequence of pipeline elements. Needle comes preconfigured with many service models.</p>
|
317
348
|
|
349
|
+
|
318
350
|
<h3>Standard Service Models:</h3>
|
319
351
|
|
320
|
-
|
352
|
+
|
353
|
+
<table class="list">
|
321
354
|
<tr>
|
322
355
|
<th style="text-align:left;">Name</th>
|
323
356
|
<th style="text-align:left;">Pipeline</th>
|
@@ -407,27 +440,42 @@
|
|
407
440
|
|
408
441
|
|
409
442
|
|
443
|
+
|
410
444
|
<h3>Specifying a Service Model</h3>
|
411
445
|
|
446
|
+
|
412
447
|
<p>You specify the service model by passing the <code>:model</code> option when you register a service. (You must only specify <em>either</em> the model, <em>or</em> the pipeline, but not both.)</p>
|
413
448
|
|
414
449
|
|
415
|
-
<
|
416
|
-
|
417
|
-
</pre>
|
450
|
+
<div class='figure'>
|
451
|
+
<span class='caption'>Specifying a service model [ruby]</span>
|
452
|
+
<div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:model</span> <span class="punct">=></span> <span class="symbol">:singleton_deferred</span> <span class="punct">)</span> <span class="punct">{...}</span></pre></div></div></div>
|
453
|
+
|
454
|
+
|
418
455
|
<h3>Defining New Models</h3>
|
419
456
|
|
457
|
+
|
420
458
|
<p>You can create your own service models by adding the corresponding pipelines to the <code>:service_models</code> service:</p>
|
421
459
|
|
422
460
|
|
423
|
-
<
|
424
|
-
|
425
|
-
|
426
|
-
</pre>
|
461
|
+
<div class='figure'>
|
462
|
+
<span class='caption'>Defining a custom model [ruby]</span>
|
463
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">service_models</span><span class="punct">[</span> <span class="symbol">:my_service_model</span> <span class="punct">]</span> <span class="punct">=</span> <span class="punct">[</span> <span class="symbol">:singleton</span><span class="punct">,</span> <span class="symbol">:my_pipeline_element</span> <span class="punct">]</span>
|
464
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span><span class="punct">,</span> <span class="symbol">:model</span> <span class="punct">=></span> <span class="symbol">:my_service_model</span> <span class="punct">)</span> <span class="punct">{...}</span></pre></div></td></tr></table></div></div>
|
427
465
|
</div>
|
428
466
|
|
429
467
|
|
430
468
|
|
469
|
+
<div class="bottom"><div class="prevnext">
|
470
|
+
|
471
|
+
<a href="chapter-5.html">Previous (5. Interceptors)</a> |
|
472
|
+
|
473
|
+
<a href="index.html">Up</a>
|
474
|
+
|
475
|
+
| <a href="chapter-7.html">Next (7. Logging)</a>
|
476
|
+
|
477
|
+
</div></div>
|
478
|
+
|
431
479
|
|
432
480
|
</div>
|
433
481
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Needle Manual :: Chapter 7: Logging</title>
|
4
|
-
<link type="text/css" rel="stylesheet" href="manual.css" />
|
4
|
+
<link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
|
5
5
|
</head>
|
6
6
|
|
7
7
|
<body>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.2.
|
18
|
-
Manual Last Updated: <strong>
|
17
|
+
Needle Version: <strong>1.2.1</strong><br />
|
18
|
+
Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -208,7 +208,17 @@
|
|
208
208
|
|
209
209
|
<div id="content">
|
210
210
|
|
211
|
-
|
211
|
+
<div class="top"><div class="prevnext">
|
212
|
+
|
213
|
+
<a href="chapter-6.html">Previous (6. Service Models)</a> |
|
214
|
+
|
215
|
+
<a href="index.html">Up</a>
|
216
|
+
|
217
|
+
| <a href="chapter-8.html">Next (8. Service Libraries)</a>
|
218
|
+
|
219
|
+
</div></div>
|
220
|
+
|
221
|
+
<h1>7. Logging</h1>
|
212
222
|
|
213
223
|
|
214
224
|
|
@@ -222,8 +232,10 @@
|
|
222
232
|
<div class="section">
|
223
233
|
<p>Logging is a pretty common activity in many applications. Because it is so common, Needle provides a powerful framework for logging messages in a consistent manner.</p>
|
224
234
|
|
235
|
+
|
225
236
|
<p>Needle’s logging framework is built on top of the standard Ruby <code>Logger</code> library. However, it extends that library to add additional functionality, including customizable message formats and a centralized location for obtaining logger instances.</p>
|
226
237
|
|
238
|
+
|
227
239
|
<p>This centralized location is the LogFactory.</p>
|
228
240
|
</div>
|
229
241
|
|
@@ -240,43 +252,53 @@
|
|
240
252
|
<p>The LogFactory is available as a service, so that any component that needs a logger instance can gain easy access to one. The factory’s service name is <code>:logs</code>.</p>
|
241
253
|
|
242
254
|
|
243
|
-
<
|
244
|
-
|
245
|
-
</pre>
|
255
|
+
<div class='figure'>
|
256
|
+
<span class='caption'>Accessing the LogFactory service [ruby]</span>
|
257
|
+
<div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">factory</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">logs</span></pre></div></div></div>
|
258
|
+
|
259
|
+
|
246
260
|
<p>You obtain logger instances from the factory by passing a logger name to <code>#get</code>:</p>
|
247
261
|
|
248
262
|
|
249
|
-
<
|
250
|
-
|
251
|
-
</pre>
|
263
|
+
<div class='figure'>
|
264
|
+
<span class='caption'>Getting a named logger instance [ruby]</span>
|
265
|
+
<div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">logger</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span> <span class="punct">"</span><span class="string">a logger name</span><span class="punct">"</span></pre></div></div></div>
|
266
|
+
|
267
|
+
|
252
268
|
<p>Subsequent calls to <code>#get</code> will return the same logger instance for the given logger name.</p>
|
253
269
|
|
270
|
+
|
254
271
|
<h3>Loggers for Services</h3>
|
255
272
|
|
273
|
+
|
256
274
|
<p>Typically, you’ll use this to assign a logger instance to a service when it is constructed. In that case, the name of the logger is the fully-qualified name of the service:</p>
|
257
275
|
|
258
276
|
|
259
|
-
<
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
</pre>
|
277
|
+
<div class='figure'>
|
278
|
+
<span class='caption'>Getting a logger for a service [ruby]</span>
|
279
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
|
280
|
+
<span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span> <span class="ident">p</span><span class="punct">.</span><span class="ident">fullname</span> <span class="punct">)</span> <span class="punct">)</span>
|
281
|
+
<span class="keyword">end</span></pre></div></td></tr></table></div></div>
|
282
|
+
|
283
|
+
|
264
284
|
<p>As a convenience, if the value passed to <code>#get</code> responds to either <code>fullname</code> or <code>name</code>, the return value of that message will be used as the name. Thus, you can do the following:</p>
|
265
285
|
|
266
286
|
|
267
|
-
<
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
</pre>
|
287
|
+
<div class='figure'>
|
288
|
+
<span class='caption'>Getting a logger for a service (simplified) [ruby]</span>
|
289
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
|
290
|
+
<span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">logs</span><span class="punct">.</span><span class="ident">get</span><span class="punct">(</span> <span class="ident">p</span> <span class="punct">)</span> <span class="punct">)</span>
|
291
|
+
<span class="keyword">end</span></pre></div></td></tr></table></div></div>
|
292
|
+
|
293
|
+
|
272
294
|
<p>As a further convenience, there is a <code>:log_for</code> service that is parameterized. Just pass the name of the log to retreive (or the service point instance) and it will return the log handle directly:</p>
|
273
295
|
|
274
296
|
|
275
|
-
<
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
</pre>
|
297
|
+
<div class='figure'>
|
298
|
+
<span class='caption'>Getting a logger for a service (simplified further) [ruby]</span>
|
299
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">,</span><span class="ident">p</span><span class="punct">|</span>
|
300
|
+
<span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">log_for</span><span class="punct">(</span> <span class="ident">p</span> <span class="punct">)</span> <span class="punct">)</span>
|
301
|
+
<span class="keyword">end</span></pre></div></td></tr></table></div></div>
|
280
302
|
</div>
|
281
303
|
|
282
304
|
|
@@ -291,6 +313,7 @@
|
|
291
313
|
<div class="section">
|
292
314
|
<p>You can configure the LogFactory when you create the registry by passing a hash as the <code>:logs</code> option to <code>Registry.new</code>. The hash may have the following properties:</p>
|
293
315
|
|
316
|
+
|
294
317
|
<table>
|
295
318
|
<tr>
|
296
319
|
<td style="vertical-align:top;"><code>:device</code></td>
|
@@ -332,29 +355,42 @@
|
|
332
355
|
|
333
356
|
|
334
357
|
|
358
|
+
|
335
359
|
<p>By default, the filename is ”./needle.log”, and the roll_size is one megabyte. The default level is <code>:debug</code>. If you wanted to specify a different filename and default level of <code>:warn</code>, you could do:</p>
|
336
360
|
|
337
361
|
|
338
|
-
<
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
</pre>
|
362
|
+
<div class='figure'>
|
363
|
+
<span class='caption'>Configuring the loggers [ruby]</span>
|
364
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span>
|
365
|
+
<span class="symbol">:logs</span> <span class="punct">=></span> <span class="punct">{</span>
|
366
|
+
<span class="symbol">:filename</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">./my-app.log</span><span class="punct">",</span>
|
367
|
+
<span class="symbol">:default_level</span> <span class="punct">=></span> <span class="symbol">:warn</span> <span class="punct">}</span>
|
368
|
+
<span class="punct">)</span></pre></div></td></tr></table></div></div>
|
369
|
+
|
370
|
+
|
345
371
|
<p>Alternatively, you can easily put the logging configuration in a <span class="caps">YAML</span> file and read it in, like so:</p>
|
346
372
|
|
347
373
|
|
348
|
-
<
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
)
|
353
|
-
</pre>
|
374
|
+
<div class='figure'>
|
375
|
+
<span class='caption'>Configuring the loggers from a YAML file [ruby]</span>
|
376
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">yaml</span><span class="punct">'</span>
|
377
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span>
|
378
|
+
<span class="symbol">:logs</span> <span class="punct">=></span> <span class="constant">YAML</span><span class="punct">.</span><span class="ident">load</span><span class="punct">(</span> <span class="constant">File</span><span class="punct">.</span><span class="ident">read</span><span class="punct">(</span> <span class="punct">"</span><span class="string">log-conf.yml</span><span class="punct">"</span> <span class="punct">)</span> <span class="punct">)</span>
|
379
|
+
<span class="punct">)</span></pre></div></td></tr></table></div></div>
|
354
380
|
</div>
|
355
381
|
|
356
382
|
|
357
383
|
|
384
|
+
<div class="bottom"><div class="prevnext">
|
385
|
+
|
386
|
+
<a href="chapter-6.html">Previous (6. Service Models)</a> |
|
387
|
+
|
388
|
+
<a href="index.html">Up</a>
|
389
|
+
|
390
|
+
| <a href="chapter-8.html">Next (8. Service Libraries)</a>
|
391
|
+
|
392
|
+
</div></div>
|
393
|
+
|
358
394
|
|
359
395
|
</div>
|
360
396
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Needle Manual :: Chapter 8: Service Libraries</title>
|
4
|
-
<link type="text/css" rel="stylesheet" href="manual.css" />
|
4
|
+
<link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
|
5
5
|
</head>
|
6
6
|
|
7
7
|
<body>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.2.
|
18
|
-
Manual Last Updated: <strong>
|
17
|
+
Needle Version: <strong>1.2.1</strong><br />
|
18
|
+
Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -208,7 +208,17 @@
|
|
208
208
|
|
209
209
|
<div id="content">
|
210
210
|
|
211
|
-
|
211
|
+
<div class="top"><div class="prevnext">
|
212
|
+
|
213
|
+
<a href="chapter-7.html">Previous (7. Logging)</a> |
|
214
|
+
|
215
|
+
<a href="index.html">Up</a>
|
216
|
+
|
217
|
+
| <a href="chapter-9.html">Next (9. Customizing Needle)</a>
|
218
|
+
|
219
|
+
</div></div>
|
220
|
+
|
221
|
+
<h1>8. Service Libraries</h1>
|
212
222
|
|
213
223
|
|
214
224
|
|
@@ -222,6 +232,7 @@
|
|
222
232
|
<div class="section">
|
223
233
|
<p>Using Needle as it has been presented so far works fine when you are dealing with a single application, all self-encapsulated. When you start dealing with combining multiple libraries, each potentially written by a different author, into a single registry, things get a little more complicated.</p>
|
224
234
|
|
235
|
+
|
225
236
|
<p>Needle provides a way for service authors to share their services. All it requires is that authors centralize their service configuration.</p>
|
226
237
|
</div>
|
227
238
|
|
@@ -237,33 +248,37 @@
|
|
237
248
|
<div class="section">
|
238
249
|
<p>This centralization is implemented by creating a module for each library you want to have services for. That module should then define a module function called (by default) <code>register_services</code>. This function should accept a single parameter—the Needle container that the services will be added to.</p>
|
239
250
|
|
251
|
+
|
240
252
|
<p>For example, if I had a library of cryptographic routines and I wanted to make them accessible as Needle services, I would create a module to contain the service definitions. Typically, this module will be defined in a file called “services.rb”, although you can certainly name it whatever you like.</p>
|
241
253
|
|
242
254
|
|
243
|
-
<
|
244
|
-
|
255
|
+
<div class='figure'>
|
256
|
+
<span class='caption'>Needle-enabled library example [ruby]</span>
|
257
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">module </span><span class="module">Crypto</span>
|
258
|
+
|
259
|
+
<span class="keyword">def </span><span class="method">register_services</span><span class="punct">(</span> <span class="ident">container</span> <span class="punct">)</span>
|
260
|
+
<span class="ident">container</span><span class="punct">.</span><span class="ident">namespace_define</span><span class="punct">(</span> <span class="symbol">:crypto</span> <span class="punct">)</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
|
261
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">prng</span> <span class="keyword">do</span>
|
262
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/prng</span><span class="punct">'</span>
|
263
|
+
<span class="constant">PRNG</span><span class="punct">.</span><span class="ident">new</span>
|
264
|
+
<span class="keyword">end</span>
|
245
265
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
PRNG.new
|
251
|
-
end
|
266
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">des</span> <span class="keyword">do</span>
|
267
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/des</span><span class="punct">'</span>
|
268
|
+
<span class="constant">DES</span><span class="punct">.</span><span class="ident">new</span>
|
269
|
+
<span class="keyword">end</span>
|
252
270
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
271
|
+
<span class="punct">...</span>
|
272
|
+
<span class="keyword">end</span>
|
273
|
+
<span class="keyword">end</span>
|
274
|
+
<span class="ident">module_function</span> <span class="symbol">:register_services</span>
|
275
|
+
|
276
|
+
<span class="keyword">end</span></pre></div></td></tr></table></div></div>
|
257
277
|
|
258
|
-
...
|
259
|
-
end
|
260
|
-
end
|
261
|
-
module_function :register_services
|
262
278
|
|
263
|
-
end
|
264
|
-
</pre>
|
265
279
|
<p>Notice that there are no explicit dependencies on Needle, only on the interfaces Needle publishes. Thus, third-parties can add service configuration modules to their libraries without introducing dependencies on Needle.</p>
|
266
280
|
|
281
|
+
|
267
282
|
<p>Once a service library has been created, it can then be accessed from another library or application that wishes to import those services.</p>
|
268
283
|
</div>
|
269
284
|
|
@@ -280,38 +295,52 @@
|
|
280
295
|
<p>Using the libraries is as simple as requiring the file that has the service definitions, and then invoking the <code>#register_services</code> module function:</p>
|
281
296
|
|
282
297
|
|
283
|
-
<
|
284
|
-
|
298
|
+
<div class='figure'>
|
299
|
+
<span class='caption'>Example of using a Needle-enabled library [ruby]</span>
|
300
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle</span><span class="punct">'</span>
|
285
301
|
|
286
|
-
|
287
|
-
|
288
|
-
|
302
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
|
303
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
|
304
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
|
305
|
+
|
306
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/services</span><span class="punct">'</span>
|
307
|
+
<span class="constant">Crypto</span><span class="punct">.</span><span class="ident">register_services</span><span class="punct">(</span> <span class="ident">reg</span> <span class="punct">)</span>
|
308
|
+
<span class="keyword">end</span>
|
309
|
+
|
310
|
+
<span class="ident">prng</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">crypto</span><span class="punct">.</span><span class="ident">prng</span></pre></div></td></tr></table></div></div>
|
289
311
|
|
290
|
-
require 'crypto/services'
|
291
|
-
Crypto.register_services( reg )
|
292
|
-
end
|
293
312
|
|
294
|
-
prng = reg.crypto.prng
|
295
|
-
</pre>
|
296
313
|
<p>To make this easier, the Container class has a convenience method named <code>#require</code>:</p>
|
297
314
|
|
298
315
|
|
299
|
-
<
|
300
|
-
|
316
|
+
<div class='figure'>
|
317
|
+
<span class='caption'>Example of using Container#require [ruby]</span>
|
318
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">needle</span><span class="punct">'</span>
|
319
|
+
|
320
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
|
321
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
|
322
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">foo</span> <span class="punct">{</span> <span class="constant">Foo</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
|
323
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">require</span> <span class="punct">'</span><span class="string">crypto/services</span><span class="punct">',</span> <span class="punct">"</span><span class="string">Crypto</span><span class="punct">"</span>
|
324
|
+
<span class="keyword">end</span>
|
325
|
+
|
326
|
+
<span class="ident">prng</span> <span class="punct">=</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">crypto</span><span class="punct">.</span><span class="ident">prng</span></pre></div></td></tr></table></div></div>
|
301
327
|
|
302
|
-
reg = Needle::Registry.new
|
303
|
-
reg.define do |b|
|
304
|
-
b.foo { Foo.new }
|
305
|
-
b.require 'crypto/services', "Crypto"
|
306
|
-
end
|
307
328
|
|
308
|
-
prng = reg.crypto.prng
|
309
|
-
</pre>
|
310
329
|
<p>The <code>Container#require</code> method will require the file, and then look for a <code>#register_services</code> method of the named module. It will execute that method, passing the container as an argument.</p>
|
311
330
|
</div>
|
312
331
|
|
313
332
|
|
314
333
|
|
334
|
+
<div class="bottom"><div class="prevnext">
|
335
|
+
|
336
|
+
<a href="chapter-7.html">Previous (7. Logging)</a> |
|
337
|
+
|
338
|
+
<a href="index.html">Up</a>
|
339
|
+
|
340
|
+
| <a href="chapter-9.html">Next (9. Customizing Needle)</a>
|
341
|
+
|
342
|
+
</div></div>
|
343
|
+
|
315
344
|
|
316
345
|
</div>
|
317
346
|
|