The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Thoughts on Service Models

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jamis Buck

Posts: 184
Nickname: minam
Registered: Oct, 2004

Jamis Buck is a C/Java software developer for BYU, and hacks in Ruby for fun.
Thoughts on Service Models Posted: Oct 14, 2004 11:20 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jamis Buck.
Original Post: Thoughts on Service Models
Feed Title: the buckblogs here
Feed URL: http://weblog.jamisbuck.org/blog.cgi/programming/index.rss
Feed Description: Jamis Buck's corner of the blogging universe. Mostly about ruby, but includes ramblings on a variety of topics.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jamis Buck
Latest Posts From the buckblogs here

Advertisement

HiveMind (the only other DI container that I have any significant experience with) introduced me to the concept of service models. What a service model does is basically determine how and when a particular service is instantiated. For example, the “singleton” model (in HiveMind) ensures that a particular service is only instantiated once. It also makes sure that the service is not instantiated until the first time a method is invoked on it (“deferred” instantiation).

I modeled the service models in both Copland and Needle on the approach taken by HiveMind. However, I’ve come to realize something:

A single HiveMind service model manages two very different things.

The first is the idea of “singleton” vs. “prototype”. That is to say, a service may be instantiated only once, or it may instantiated once for each request. Not knowing what the “proper” term for this concept might be, I’ll arbitrarily refer to it as a service’s multiplicity.

The second idea is the idea of “deferred instantiation” vs. “immediate instantiation”. With the former, a service is not actually instantiated until the last possible moment—the moment when a client attempts to invoke a method on the service. With the latter, the service is instantiated at the moment it is requested. Again, not knowing what the proper term for this concept is, I’ll refer to it as a service’s instantiability.

HiveMind (and, by inheritence, Copland and Needle) marry the combinations of multiplicity and instantiability into a set of predefined service models. For example, Copland supports the following models:

Model Multiplicity Instantiability
Prototype 0..* Immediate
Prototype-Deferred 0..* Deferred
Singleton 0..1 Immediate
Singleton-Deferred 0..1 Deferred
Threaded 0..1 (*) Deferred

(* The Threaded model is like the Singleton-Deferred model, except it allows up to one instance of the service per thread, instead of per process.)

For convenience’s sake, it makes sense to marry them together. Why specify two values every time you want the “prototype-deferred” behavior? However, from an implementation perspe 1000 ctive, I’ve begun to wonder if they shouldn’t be split apart.

Specifically, what this implies is that to instantiate a service, a kind of pipeline is constructed and executed. Each element in the pipeline adds some additional logic to the process of instantiation. Thus, a simple “prototype-immediate” model would do nothing more than instantiate the requested service—a pipeline of length 1:

       +---------+
  ...->+ service |
       +---------+

The “service” element (shown) would perform the actual instantiation of the requested service.

However, the “singleton-deferred” model would have three elements in the pipeline:

       +-----------+   +----------+   +---------+
  ...->+ singleton +-->+ deferred +-->+ service |
       +-----------+   +----------+   +---------+

The “singleton” element ensures that no subsequent element is ever called more than once. Thus, if the next element in the pipeline (whatever it might be) has never been called before, it is invoked and the result is cached. Otherwise, the cached result is automatically returned.

The “deferred” element creates a proxy object that wraps the next element in the pipeline. This proxy object is immediately returned. The next element of the pipeline is not executed, then, until some method is invoked on the proxy, at which point the pipeline is resumed, the result obtained, and the method call delegated to that new object.

Naturally, for convenience’s sake, you would want to be able to specify these pipelines as pre-defined packages. As I mentioned before, it would quickly become a burden to have to specify both the multiplicity and the instantiability when you nearly always want them in the same combination. But by implementing them separately, you would gain a smorgasbord of pipeline features that could be mixed and matched to create new packages. This would reduce code duplication between the service models, which is currently a (minor) problem in both Copland and Needle.

Some combinations would not make sense, of course. You would never combine more than one multiplicity-enforcing pipeline element in the same pipeline (i.e., “singleton-prototype”). Nor would you combine multiple instantiability-enforcing elements (“deferred-immediate”). Packaging the elements into predefined models would help prevent such madness.

Lastly, there may be additional unforeseen benefits to splitting them apart. The pipeline I described above might be used for more than just enforcing multiplicity and instantiability. I may just have to hack this approach into Needle and see what comes of it.

Read: Thoughts on Service Models

Topic: Known RubyConf2004 Blogs and Wikis Previous Topic   Next Topic Topic: RubConf.new(2004) (Saturday)

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use