From techml at sgtpepper.net Thu Nov 18 08:47:29 2004 From: techml at sgtpepper.net (Daigo Moriwaki) Date: Thu Nov 18 08:47:09 2004 Subject: [Needle] Reset cached objects Message-ID: <419CA7F1.9040109@sgtpepper.net> Dear Jamis I read your article at RubyGarden. Needle is excellent! I came from Java, too. You are the man. I saw sources from CVS head and have some questions. (1) Release caches At Needle::Pipeline::Collection#chain_to when a new element (or interceptor) is added you should reset all elements so that cached objects (ex. in a singleton) are released. I wrote a test code. I (and almost users) expect third interceptor will always be called. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ require 'needle' reg = Needle::Registry.define! do #dict( :model => :prototype ) { Hash.new } # puts first, second and third dict { Hash.new } # puts only first and second end reg.intercept( :dict ).doing do |chain,context| Kernel.puts "first" chain.process_next context end reg.intercept( :dict ).doing do |chain,context| Kernel.puts "second" chain.process_next context end dict = reg.dict puts "dict[:hello] = #{dict[:hello].inspect}" reg.intercept( :dict ).doing do |chain,context| Kernel.puts "third" chain.process_next context end dict = reg.dict puts "dict[:hello] = #{dict[:hello].inspect}" ~~~~~ OUTPUT: first second dict[:hello] = nil first second dict[:hello] = nil ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (2) Mutex in ServicePoint In Needle::ServicePoint#interceptor "@chain = nil" (and a few lines around it) sould be guarded by mutex. (3) typos At the line #23 of pipeline/collection.rb thechain -> the chain At the line #23 of service-point.rb so does a service point describes -> "describe" (I may mistake because I am not a native English speaker.) Best regards, Daigo -- Daigo Moriwaki beatles_at_sgtpepper_dot_net From jgb3 at email.byu.edu Thu Nov 18 10:28:45 2004 From: jgb3 at email.byu.edu (Jamis Buck) Date: Thu Nov 18 10:29:20 2004 Subject: [Needle] Reset cached objects In-Reply-To: <419CA7F1.9040109@sgtpepper.net> References: <419CA7F1.9040109@sgtpepper.net> Message-ID: <419CBFAD.2010506@email.byu.edu> Daigo Moriwaki wrote: > Dear Jamis > > I read your article at RubyGarden. > Needle is excellent! I came from Java, too. You are the man. > > I saw sources from CVS head and have some questions. [snip] Thanks for the bug report(s). You got them to me just in time--I was able to fix them all in time for today's release of Needle 1.2. It's not out yet, but it should be available in a few hours. Thanks for your close examination of Needle! I appreciate the feedback. - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis From techml at sgtpepper.net Fri Nov 19 09:52:36 2004 From: techml at sgtpepper.net (Daigo Moriwaki) Date: Fri Nov 19 09:52:18 2004 Subject: [Needle] singleton mode In-Reply-To: <419CBFAD.2010506@email.byu.edu> References: <419CA7F1.9040109@sgtpepper.net> <419CBFAD.2010506@email.byu.edu> Message-ID: <419E08B4.4090302@sgtpepper.net> Hi Jamis, Jamis Buck wrote: > Thanks for the bug report(s). You got them to me just in time--I was > able to fix them all in time for today's release of Needle 1.2. It's > not out yet, but it should be available in a few hours. Thank you for the quick response and congratulations on the new release. But it produced another problem. ~~~~~~~~~~~~~~~~~~ require 'needle' class Foo def initialize puts "Initialized." end end reg = Needle::Registry.define! do dict( :model => :singleton ) { Foo.new } end reg.intercept( :dict ).doing do |chain,context| chain.process_next context end dict = reg.dict # => Initialized. dict = reg.dict # no output reg.intercept( :dict ).doing do |chain,context| chain.process_next context end dict = reg.dict # => Initialized. ~~~~~~~~~~~~~~~~~~ I expect instantiation of singleton occurs only once. I can not think of elegant solution... Daigo -- Daigo Moriwaki beatles_at_sgtpepper_dot_net From jgb3 at email.byu.edu Fri Nov 19 10:14:32 2004 From: jgb3 at email.byu.edu (Jamis Buck) Date: Fri Nov 19 10:14:13 2004 Subject: [Needle] singleton mode In-Reply-To: <419E08B4.4090302@sgtpepper.net> References: <419CA7F1.9040109@sgtpepper.net> <419CBFAD.2010506@email.byu.edu> <419E08B4.4090302@sgtpepper.net> Message-ID: <419E0DD8.3010101@email.byu.edu> Daigo Moriwaki wrote: > Hi Jamis, > > Jamis Buck wrote: > >> Thanks for the bug report(s). You got them to me just in time--I was >> able to fix them all in time for today's release of Needle 1.2. It's >> not out yet, but it should be available in a few hours. > > > Thank you for the quick response and congratulations on the new release. > > But it produced another problem. > > ~~~~~~~~~~~~~~~~~~ > require 'needle' > > class Foo > def initialize > puts "Initialized." > end > end > > reg = Needle::Registry.define! do > dict( :model => :singleton ) { Foo.new } > end > > reg.intercept( :dict ).doing do |chain,context| > chain.process_next context > end > > dict = reg.dict # => Initialized. > dict = reg.dict # no output > > reg.intercept( :dict ).doing do |chain,context| > chain.process_next context > end > > dict = reg.dict # => Initialized. > ~~~~~~~~~~~~~~~~~~ > > I expect instantiation of singleton occurs only once. > > I can not think of elegant solution... Neither can I. I was aware of this--in fact, the unit tests test for this precise condition as an indicator of _success_ of adding a new interceptor. It occurs (as you probably already know) because the only way to force the interceptor chain to be rebuilt is to reset the caches on the pipeline elements, including the singleton. Thus, adding a new interceptor causes the saved singleton instance to be discarded. So, if you are using interceptors, you have three options: 1) Add all of your interceptors up front, so that your singleton services will not be multiply instantiated. 2) Expect singletons to be reinstantiated when adding interceptors after the singletons have already been instantiated. 3) "Double wrap" the service, like so: registry.define do |b| b.service_core { Foo.new } b.service { |c,| c.service_core } end registry.intercept( :service ).doing { |ch,ctx| ... } registry.service.frobnicate registry.intercept( :service ).doing { |ch,ctx| ... } registry.service.frobnicate It's a workaround, but it should do what you want. > > > Daigo > - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis From techml at sgtpepper.net Sun Nov 21 06:26:08 2004 From: techml at sgtpepper.net (Daigo Moriwaki) Date: Sun Nov 21 06:25:41 2004 Subject: [Needle] singleton mode In-Reply-To: <419E0DD8.3010101@email.byu.edu> References: <419CA7F1.9040109@sgtpepper.net> <419CBFAD.2010506@email.byu.edu> <419E08B4.4090302@sgtpepper.net> <419E0DD8.3010101@email.byu.edu> Message-ID: <41A07B50.9090004@sgtpepper.net> Jamis Buck wrote: > Neither can I. I was aware of this--in fact, the unit tests test for > this precise condition as an indicator of _success_ of adding a new > interceptor. Sorry, I did not read test codes precisely. You had noticed. This is a kind of design policy. It is fine if you declare in documents that keeping singleton instance is user's responsibility. 3) "Double wrap" is good idea. Or the user includes Ruby's singleton module in the managed class. By the way how about thread safety? Which class do you design to be thread safe. Registry, Container, others? Daigo -- Daigo Moriwaki beatles_at_sgtpepper_dot_net From jgb3 at email.byu.edu Sun Nov 21 22:57:14 2004 From: jgb3 at email.byu.edu (Jamis Buck) Date: Sun Nov 21 22:57:23 2004 Subject: [Needle] singleton mode In-Reply-To: <41A07B50.9090004@sgtpepper.net> References: <419CA7F1.9040109@sgtpepper.net> <419CBFAD.2010506@email.byu.edu> <419E08B4.4090302@sgtpepper.net> <419E0DD8.3010101@email.byu.edu> <41A07B50.9090004@sgtpepper.net> Message-ID: <41A1639A.2080308@email.byu.edu> Daigo Moriwaki wrote: > Jamis Buck wrote: > >> Neither can I. I was aware of this--in fact, the unit tests test for >> this precise condition as an indicator of _success_ of adding a new >> interceptor. > > > Sorry, I did not read test codes precisely. You had noticed. > > This is a kind of design policy. It is fine if you declare in documents > that keeping singleton instance is user's responsibility. Very good point. I'll see about making that clearer in the documentation. I'd rather not _have_ to do it this way, but I really can't see a good way to make it so that the cached singleton instance can be saved. Well, I take that back. You *could* make it so that, in the pipeline, the interceptors are added AFTER the singleton element, which would mean that every request of the service would add the interceptors. This would add to the overhead involved in using interceptors, though, so I'm not sure I like this approach too much. You are certainly welcome to experiment with it and let me know what you think. > 3) "Double wrap" is good idea. Or the user includes Ruby's singleton > module in the managed class. I hadn't thought of the Singleton module. That's a good point. Although, it does move the guard into the implementation of the class, which is what the lifecycle management of Needle is supposed to protect you from. > By the way how about thread safety? Which class do you design to be > thread safe. Registry, Container, others? As far as I know, I've tried to make as much as possible thread safe. That said: registering services is *not* explicitly thread-safe (i.e., I don't have any mutexes guarding the registration process), but I don't think it needs to be. I don't have a lot of experience with threaded programming, though, so if anyone notices anything that needs guarding, please let me know. Even better: submit a patch. :) > > Daigo > - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis From hammett at gmail.com Sat Nov 27 15:23:04 2004 From: hammett at gmail.com (hammett) Date: Sat Nov 27 15:22:24 2004 Subject: [Needle] Some important concepts Message-ID: <722a859d04112712236228728@mail.gmail.com> Hello Just want to point out a few incorrections of the documentation. - DI and IoC are not the same thing. Inversion of control is design principle broader than simple dependency injection - When you refer to lifecycle in your docs, you should replace by lifestyle. Lifecycle are artifacts to initilialize, start, dispose services. Lifestyle manges instances, like singleton, transient/prototype, poolable. Keep on your good work! -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett From jamis_buck at byu.edu Sat Nov 27 22:42:33 2004 From: jamis_buck at byu.edu (Jamis Buck) Date: Sat Nov 27 22:42:11 2004 Subject: [Needle] Some important concepts In-Reply-To: <722a859d04112712236228728@mail.gmail.com> References: <722a859d04112712236228728@mail.gmail.com> Message-ID: <41A94929.2070409@byu.edu> hammett wrote: > Hello > > Just want to point out a few incorrections of the documentation. Thanks! > > - DI and IoC are not the same thing. Inversion of control is design > principle broader than simple dependency injection Well...I know there are many camps that believe this to be the case (quite possibly thanks to Fowler's landmark article on dependency injection). However, the sad fact is that the terms are used interchangeably by many: * http://jakarta.apache.org/hivemind/ioc.html * http://www.picocontainer.org/Inversion+of+Control * http://www.theserverside.com/articles/article.tss?l=SpringFramework * ... For better or for worse, people associate "dependency injection" with "inversion of control", and vice versa. > - When you refer to lifecycle in your docs, you should replace by > lifestyle. Lifecycle are artifacts to initilialize, start, dispose > services. Lifestyle manges instances, like singleton, > transient/prototype, poolable. Ah, thanks! I'll correct the documentation. > Keep on your good work! Thank-you! - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis From hammett at gmail.com Sat Nov 27 22:49:41 2004 From: hammett at gmail.com (hammett) Date: Sat Nov 27 22:48:58 2004 Subject: [Needle] Some important concepts In-Reply-To: <41A94929.2070409@byu.edu> References: <722a859d04112712236228728@mail.gmail.com> <41A94929.2070409@byu.edu> Message-ID: <722a859d04112719493a92ae29@mail.gmail.com> > > For better or for worse, people associate "dependency injection" with > "inversion of control", and vice versa. I'm one of the old guys pre-martin fowler article, and we lived peacefully without this simplification which unfortunatelly shows just one aspect of what inversion of control container should address. I think stefano said it better http://www.betaversion.org/~stefano/linotype/news/38/ I spent some time investigating needle, but honestly I didn't like the approach. Sorry. However I understand how difficult can it be to build a container to resolve services without type strict arguments and without metadata/attributes. I'm blogging about and hopefully will throw some ideas about it. -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett From jamis_buck at byu.edu Sat Nov 27 23:00:26 2004 From: jamis_buck at byu.edu (Jamis Buck) Date: Sat Nov 27 23:00:44 2004 Subject: [Needle] Some important concepts In-Reply-To: <722a859d04112719493a92ae29@mail.gmail.com> References: <722a859d04112712236228728@mail.gmail.com> <41A94929.2070409@byu.edu> <722a859d04112719493a92ae29@mail.gmail.com> Message-ID: <41A94D5A.2080909@byu.edu> hammett wrote: >>For better or for worse, people associate "dependency injection" with >>"inversion of control", and vice versa. > > > I'm one of the old guys pre-martin fowler article, and we lived > peacefully without this simplification which unfortunatelly shows just > one aspect of what inversion of control container should address. > > I think stefano said it better > http://www.betaversion.org/~stefano/linotype/news/38/ Excellent article--thanks for pointing it out to me! I certainly do not profess to be an expert on either IoC or DI, and Stefano's article clarifies a few criticle points for me. (Interesting aside: I went to high school with Stefano. Kind of fun to see him rise to such prominence! He certainly deserves it.) > > > I spent some time investigating needle, but honestly I didn't like the > approach. Sorry. However I understand how difficult can it be to build > a container to resolve services without type strict arguments and > without metadata/attributes. I'm blogging about and hopefully will > throw some ideas about it. > No need to apologize. I'm very curious to read what you have to say. Needle is certainly not perfect, nor even necessarily on target. Thanks for your comments! - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis