tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/196-injectorinjectinto-conundrum-and-object-pooling-optimizationRobotlegs: Discussion 2013-04-28T09:55:56Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-10-28T17:17:47Z2010-10-28T17:17:47ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Hi Zack,</p>
<blockquote><p>I'm sure this refusal was planned as a short-circuit to prevent re-walking and re-satisfying dependency trees...</p></blockquote>
<p>That's exactly it. Have you had a look through the SwiftSuspenders source? Perhaps there is an easy way to remove objects from the dictionary?</p>
<p>I'm not sure I like the Boolean param in the method signature... will have to ponder it some more.</p>
<p>Nevertheless, I like the idea, and am interested in seeing your pooling approach.. do you have any code for that online? Perhaps we could combine efforts - I've started down a similar path with a library/extension called "Oil":</p>
<p><a href="http://github.com/darscan/robotlegs-extensions-Oil">http://github.com/darscan/robotlegs-extensions-Oil</a></p>
<p>My object pool is super rudimentary, but works ok for now:</p>
<p><a href="http://github.com/darscan/robotlegs-extensions-Oil/blob/master/src/org/robotlegs/oil/pool/BasicObjectPool.as">http://github.com/darscan/robotlegs-extensions-Oil/blob/master/src/...</a></p>
<p>The pool was initially intended to recycle item/data renderers; I hadn't even considered pooling mediators and commands. I think an event-less, object-pooled RL framework impl would be pretty cool.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-10-29T00:06:54Z2010-10-29T00:06:54ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>I've looked in the SwiftSuspenders source, and it seems quite accessible for modifications. No code to share yet, was trying to decide the best place for it -- forking Oil seems like a fun and appropriate place to get going tonight.</p></div>ZackPiercetag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-10-29T01:35:11Z2010-10-29T01:35:11ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Cool. Have just pushed some updates, docs and a demo thing. Kinda freestyling it, so feel free to go wild.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-10-29T05:43:50Z2010-10-29T05:48:21ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>I've got command and mediator instance reuse working in my fork of Oil:</p>
<p><a href="http://github.com/ZackPierce/robotlegs-extensions-Oil">http://github.com/ZackPierce/robotlegs-extensions-Oil</a></p>
<p>Which in turn requires my slightly-tweaked forks of Robotlegs and SwiftSuspenders.<br />
<a href="http://github.com/ZackPierce/robotlegs-framework">http://github.com/ZackPierce/robotlegs-framework</a><br />
<a href="http://github.com/ZackPierce/SwiftSuspenders">http://github.com/ZackPierce/SwiftSuspenders</a></p>
<p>These should all differ from the upstream only with regards to adding support for re-injection, and thus object recycling.</p>
<p>The solution I reached is not to change the IInjector interface, but to modify the SwiftSuspenders Injector to have the optional capability for forced re-injection.<br />
</p>
<p>The old SwiftSuspenders Injector.injectInto was renamed <code>injectIntoObject.</code>The <code>SwiftSuspendersInjector</code> class has a public <code>injectInto</code> method that wraps a call like <code>super.injectIntoObject(object, true);</code></p>
<p>This way, we only use forced injection if one explicitly calls injectInto (rather than indirectly through IInjector.instantiate) at the Robotlegs level.</p>
<p>This is based on the assumption that if you call IInjector.injectInto on an object, you always want your latest mappings to be reflected in what the object holds at the end of the call, and not worry about any previous state-manipulations or injection calls related to that object.<br />
</p>
<p>"I don't care how it got here, but it damn well better have all of its dependencies met after I call injectInto"</p>
<p>Test cases were added to Oil as well.</p></div>ZackPiercetag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-10-29T10:46:43Z2010-10-29T10:46:43ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Nice one! I'm away for the weekend, but will check it all out next week. Cheers!</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-11-02T00:33:13Z2010-11-02T00:33:13ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Hi Zack,</p>
<p>I haven't had much time to look through your code (moving house, starting new job), but I did spot a couple of things:</p>
<p>DRY: RecyclingCommand/MediatorMap completely re-implement the RL base classes. I realize that the hooks needed to avoid this are missing from RL at present, but we can easily add them to RL as they won't incur any behavioral or API changes. I'm probably not explaining myself well... think of it this way: how can we make the Recycling*Maps as short as possible, and avoid duplicating a single line of code from the RL base classes?</p>
<p>Also, I think they should be called PooledCommandMap and PooledMediatorMap. And they should probably live in an mvcs package (as they are modeled on the RL mvcs framework).</p>
<p>I've pushed some updates (Promise processing) in the meantime. Will try get round to adding those RL hooks some time this week (or next), and updating your maps.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-11-09T19:19:24Z2010-11-09T19:19:24ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Thanks for the feedback, I'll jump back into this when my day-job workload eases up a bit.</p></div>ZackPiercetag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352010-12-21T20:38:31Z2010-12-21T20:38:33ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>I ran into this problem today. had a solution that worked within
my app. Shaun, would like to see how you would address this at the
framework level. The boolean seems to be a pretty straight forward
approach, Is this something you are actively looking at?</p></div>vijay shantag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352011-05-05T05:12:02Z2011-05-05T05:12:02ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Super-late for a reply, but I thought I'd follow up for the sake
of closure.</p>
<p>Ultimately, I abandoned development on the
recycling/object-pooling oriented approach to the mediator and
command maps because the additional overhead of cleaning up objects
for re-use imposed a more considerable cognitive load on
development than I originally anticipated.</p>
<p>While ideally, most mediators should be nearly stateless, in
practice, I found that consistently doing the book-keeping of
clearing out all intermediate data was an extra dev-stress with
pretty minimal performance benefits. It turns out that it's not
technically hard to add a bunch of <code>property = null;</code>
statements, but it is troublesome to determine which properties are
truly disposable or a cross-injection usage risk for every single
mediator class in a nontrivial codebase and remember to clean them
all.</p></div>ZackPiercetag:robotlegs.tenderapp.com,2009-10-18:Comment/35408352011-05-05T12:48:28Z2011-05-05T12:48:28ZInjector.injectInto Conundrum and Object Pooling Optimization<div><p>Thanks Zack,</p>
<p>I completely agree with your math:</p>
<p>(developer-headaches = opportunities to make mistakes = broken
code) < faster code</p>
<p>It's great to get a follow up though. I agree that mediators
should be stateless, but it's best not to hand out more rope :)</p>
<p>Stray</p></div>Stray