﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Ayende Rahien commented on Where is the ROI?</title><description>dario-g,
  
No, that belongs in the presentation layer, not service layer
</description><link>http://ayende.com/3962/where-is-the-roi#comment42</link><guid>http://ayende.com/3962/where-is-the-roi#comment42</guid><pubDate>Wed, 03 Jun 2009 10:56:47 GMT</pubDate></item><item><title>dario-g commented on Where is the ROI?</title><description>Hmm.. Maybe I'm missing the point but code like this:
  
  
latePayingCustomQuery  
  
  .Where(c =&gt; c.LastName.StartsWith("E"))  
  
  .Skip((page - 1) * itemCount)  
  
  .Take(10); 
  
  
shouldn't be placed in UI but it belongs to Service Layer, right? That layer is responsible to build query and other stuff which goes down to DAL?
</description><link>http://ayende.com/3962/where-is-the-roi#comment41</link><guid>http://ayende.com/3962/where-is-the-roi#comment41</guid><pubDate>Wed, 03 Jun 2009 09:59:33 GMT</pubDate></item><item><title>Fr&amp;#233;d&amp;#233;ric commented on Where is the ROI?</title><description>Well Ayende is absolutely right.
  
  
You can't build a software thinking in terms of "the developpers are going to do bad things".
  
  
Well I suppose that's because tests only occurs at the end of the development or even in production.
  
  
And beside, using tools like linq or nh are subject to great performance issues.
  
  
Limitating a collection, especially binded to data, is useless. It's a fake best practice.
  
  
If it is the last solution that could be applied, well, you're in deep trouble.
  
  
It's like saying "making cars with a 20mph max speed is a good solution to avoid car crashes".
  
</description><link>http://ayende.com/3962/where-is-the-roi#comment40</link><guid>http://ayende.com/3962/where-is-the-roi#comment40</guid><pubDate>Fri, 24 Apr 2009 13:42:59 GMT</pubDate></item><item><title>Andrew commented on Where is the ROI?</title><description>Arne, the problem with your arguement is that you are completely loading your example to make your answer correct.
  
  
The reality is, there should be many places where a silly query should get caught, and in one situation 10 years ago, it happened to get to production.  But due to that one case, you are advocating a heck of a lot of extra work not directly tackling the problem to prevent it from ever happening again.
  
  
Basically, and get ready for a lousy analogy, 10 years ago there was a car accident and someone died due to not wearing a seat belt and now to prevent it from happening again you are restricting the top speed of all cars to 5 km/hr rather than just ask people to wear seatbelts.
  
  
See...I told you it was lousy. ;)
</description><link>http://ayende.com/3962/where-is-the-roi#comment39</link><guid>http://ayende.com/3962/where-is-the-roi#comment39</guid><pubDate>Wed, 22 Apr 2009 21:54:55 GMT</pubDate></item><item><title>Arne Claassen commented on Where is the ROI?</title><description>Ayende,
  
I guess I'm not explaining this properly, since your response seems to indicate that our environment was a lot of simpler than it was.
  
  
First, this was almost 10 years ago now, so no cloud
  
Second, we had release procedures, including various QA cycles and load testing, and we did the load tests with slower hardware with limited sets, but that cannot catch all scenarios. Our production environment had a number of database machines with different databases being used in different capacities by a lot of different app clusters, so relying on our test loads recreating all possible contention scenarios was just likely.
  
Third, cycling versions through a single set of hardware was a large ordeal with a lot of hours and time in transferring large datasets, no matter the automation and procedure. This wasn't a setup with a single DB on a single server and one webapp hitting it, even when reduced to test environments.
  
Fourth, I have repeatedly stipulated that we had process problems, I'm just not convinced that had we had this ideal test environment our problems would have gone away.
  
  
All I'm really saying is that I still don't buy that it is better ROI to permit ad hoc queries against DBs with high contention and using load testing to determine what's bad, rather than limiting access to that resource under contention and when the access is insufficient determine what is the best solution.
  
  
</description><link>http://ayende.com/3962/where-is-the-roi#comment38</link><guid>http://ayende.com/3962/where-is-the-roi#comment38</guid><pubDate>Wed, 22 Apr 2009 07:04:42 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Arne,
  
I don't agree that you need an exact duplicate hardware for that.
  
For that matter, I would say that even if you needed, asking for 500$ per load test and setting up the test on the cloud using something like EC2 or GoGrid is a great way of doing that (yeah, I know all the trouble with data in the cloud, that is an example).
  
Having an additional server serve as the DB for the site for load test (standard one!) would actually make the load tests more effective, since the DB would be slower.
  
  
Basically, I don't consider it disciplined to just move to production without having a proper release procedure, and that include load testing, among other things.
  
Cycling different versions through a single set of hardware is actually easy, you need to put several versions of the site on the same hardware. 
  
If this is hard, this point to a problem in your deployment.
  
  
A customer that I used to work with had a 4 days mandatory load test for every release. That is 4 days of hammering the site, trying to find slow parts, memory leaks, etc.
  
Not doing this, especially after the first time you got bitten, is not responsible.
  
  
</description><link>http://ayende.com/3962/where-is-the-roi#comment37</link><guid>http://ayende.com/3962/where-is-the-roi#comment37</guid><pubDate>Wed, 22 Apr 2009 06:19:29 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>CaliCoder,
  
Obviously that is a totally different question, and I don't advocate that at all.
</description><link>http://ayende.com/3962/where-is-the-roi#comment36</link><guid>http://ayende.com/3962/where-is-the-roi#comment36</guid><pubDate>Wed, 22 Apr 2009 06:14:09 GMT</pubDate></item><item><title>Arne Claassen commented on Where is the ROI?</title><description>Ayende,
  
I guess my answer would still be that in the our case that would still have been a bad ROI.  Education, code reviews and creating DB APIs that make devs fall in the pit of success were still a lot cheaper.
  
  
I'm going to overlook that we usually had several parallel QA/Test efforts going on for different features to be released on the site (and site here was lots of different app clusters totallling over 1000 servers) and having them all cycle through one set of load testing hardware would have been a whole lot of man hours and a big delay added to a release cycle.
  
  
So every once in a while someone would write a query they shouldn't have and had they checked with a DBA they would have gotten a very quick "woah, buddy, don't do that, let's see how we can get what you need another way". But they made it into production, because the test loads didn't show this to be bad and even production didn't until a certian load scenario happened. Now the postmortem happens and here's conversation asking for the duplicate load testing hardware:
  
  
CTO: "how can we prevent this from happening again?"
  
Me: "You know that $250k cluster we have for the main prod DBs? We need another one of those and ops cycles to populate them and build fake load scenarios so we can test the dev's code"
  
CFO:  "Really? The only way you can prevent your devs from doing something stupid is by buying loads of hardware to see their stupid actions under load? You call that engineering?. Purchase request denied"
  
  
And that response would have been valid. We had process problems, but throwing hardware at them was not the right solution. We eventually changed the most contentious DB to be a service layer that devs talked against, since them doing ad hoc queries in the first place was the real WTF. But a service layer is just another way of saying "we are limiting what you can do against the DB and if you need more, let's talk about your needs and we'll build it intelligently." Allowing adhoc queries against a DB from the webapp tier breaks down at some size of operation, test environments not withstanding, imho.
  
  
</description><link>http://ayende.com/3962/where-is-the-roi#comment35</link><guid>http://ayende.com/3962/where-is-the-roi#comment35</guid><pubDate>Tue, 21 Apr 2009 16:22:53 GMT</pubDate></item><item><title>Stephen commented on Where is the ROI?</title><description>I don't think thats essentially the point, security and whatever makes sense to exist at lower layers still exists, I think the point is that the ability to richly query the data can still bubble up to the controllers.
</description><link>http://ayende.com/3962/where-is-the-roi#comment34</link><guid>http://ayende.com/3962/where-is-the-roi#comment34</guid><pubDate>Tue, 21 Apr 2009 13:22:22 GMT</pubDate></item><item><title>CaliCoder commented on Where is the ROI?</title><description>what i would be more concerned about in my DL or UI is allowing a developer the option to make a mistake that allows the _user_ to subvert security or logic... not developer.
</description><link>http://ayende.com/3962/where-is-the-roi#comment33</link><guid>http://ayende.com/3962/where-is-the-roi#comment33</guid><pubDate>Tue, 21 Apr 2009 08:59:00 GMT</pubDate></item><item><title>CaliCoder commented on Where is the ROI?</title><description>we throw around the term middleware a lot where i work.  i apologize i misused the term.  i really meant infrastructure or framework level.
  
  
If he's trying to achieve that level of protection against mistake then how is that fear domain specific?  Isn't that an infrastructure concern?
  
  
Justin argues that by supplying the paging and sorting implementations that he's protecting the infrastructure from abuse, slowness, stupidness... He says, "So we really have two conflicting requirements, we want to provide the flexibility of paging and sorting up closer to the UI, but we also want to lock down the queries a bit."  I argue that not only are these conflicting requirements but they aren't even domain layer requirements... they are infrastructure level.
  
  
would you say that's accurate or am i missing something?
</description><link>http://ayende.com/3962/where-is-the-roi#comment32</link><guid>http://ayende.com/3962/where-is-the-roi#comment32</guid><pubDate>Tue, 21 Apr 2009 08:17:41 GMT</pubDate></item><item><title>Hendry Luk commented on Where is the ROI?</title><description>Uh, I meant, "NHQG is very rigid that it allows me to write only what *is* allowed by my Hbm config" :P
</description><link>http://ayende.com/3962/where-is-the-roi#comment31</link><guid>http://ayende.com/3962/where-is-the-roi#comment31</guid><pubDate>Tue, 21 Apr 2009 07:58:41 GMT</pubDate></item><item><title>Hendry Luk commented on Where is the ROI?</title><description>Linq starts to feel like magic string to me (almost equivalent to HQL, except plus intellisense and refactoring), in the sense that it's so liberal that you can throw almost any expression to it, and they will all compile fine, but only small portion of it are actually valid syntax,.. depending on how I configure my hbm.
  
NHQG is very rigid that it allows me to write only what is not allowed by my Hbm config. The feedback is immediate.
  
Altho one might argue that integration-test can provide better feedback to Linq, but so can it to HQL.
</description><link>http://ayende.com/3962/where-is-the-roi#comment30</link><guid>http://ayende.com/3962/where-is-the-roi#comment30</guid><pubDate>Tue, 21 Apr 2009 07:56:41 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Hendry,
  
I am surprised that you find NHQG easier, it was explicitly modelled to be as close to Linq as I could get in C# 2.0
  
And no, I wouldn't condone using HQL in the UI
  
  
I wouldn't condone doing any complex query manipulation in the UI, for that matter.
</description><link>http://ayende.com/3962/where-is-the-roi#comment29</link><guid>http://ayende.com/3962/where-is-the-roi#comment29</guid><pubDate>Tue, 21 Apr 2009 07:44:44 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Cali,
  
I am not sure that I understand the question
</description><link>http://ayende.com/3962/where-is-the-roi#comment28</link><guid>http://ayende.com/3962/where-is-the-roi#comment28</guid><pubDate>Tue, 21 Apr 2009 07:41:38 GMT</pubDate></item><item><title>Hendry Luk commented on Where is the ROI?</title><description>Btw I'm curious, how is it different to write Linq expressions in UI from writing HQL statements in UI?
</description><link>http://ayende.com/3962/where-is-the-roi#comment27</link><guid>http://ayende.com/3962/where-is-the-roi#comment27</guid><pubDate>Tue, 21 Apr 2009 07:39:41 GMT</pubDate></item><item><title>Hendry Luk commented on Where is the ROI?</title><description>Ayende, I think using Query object (in your previous post) separates the concern out of UI, without imposing OCP problem. My concern is only when Linq/HQL ex[ressions are exposed to UI layer.
  
Doesn't look like it belongs there. It would be OK if writing Linq expression was easy. Alas the fact is it is not. Too many infrastructure-related shinanigans to deal with.
  
Btw, I am quite happy using NHQG in UI layer because the abstraction is less leaky than Linq IMO.
</description><link>http://ayende.com/3962/where-is-the-roi#comment26</link><guid>http://ayende.com/3962/where-is-the-roi#comment26</guid><pubDate>Tue, 21 Apr 2009 07:30:16 GMT</pubDate></item><item><title>CaliCoder commented on Where is the ROI?</title><description>ayende, do you think that Justin is confusing middleware with DL?  I don't see any domain level problem being solved by supplying page &amp; sort... I'm not trying to call out Justin, but just wondering if you think that's where ppl are getting confused?
</description><link>http://ayende.com/3962/where-is-the-roi#comment25</link><guid>http://ayende.com/3962/where-is-the-roi#comment25</guid><pubDate>Tue, 21 Apr 2009 07:17:38 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Arne,
  
That is pretty common scenario, and I agree that you don't want all devs to use real size data.
  
But that is no reason not to have _load_ test with reasonably sized data base.
  
You only need one of those.
</description><link>http://ayende.com/3962/where-is-the-roi#comment24</link><guid>http://ayende.com/3962/where-is-the-roi#comment24</guid><pubDate>Tue, 21 Apr 2009 06:33:34 GMT</pubDate></item><item><title>Arne Claassen commented on Where is the ROI?</title><description>Ayende,
  
Oh, I agree that there were plenty of process problems and having dev be an exact replica of production is desirable, but in this case, even with my process complaints I don't think it would have been feasible. Our databases were several gigabytes (back when gigabytes meant something), we had, at any given time, 10 or more separate dev environments going for 100+ developers in different groups, so getting everyone production equivalent hardware and DBs wasn't feasible. And even if that hadn't been a limiting factor, faking the production loads all our apps were generating would have required yet more dev hardware.
</description><link>http://ayende.com/3962/where-is-the-roi#comment23</link><guid>http://ayende.com/3962/where-is-the-roi#comment23</guid><pubDate>Tue, 21 Apr 2009 06:08:17 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Henry,
  
1) that is not a problem, the first time it is used, it will generate an error, that is very easy to discover and detect.
  
2) never had that problem, and see the previous posts about the problem with doing it this way
  
3) again, read the post and show me the ROI
</description><link>http://ayende.com/3962/where-is-the-roi#comment22</link><guid>http://ayende.com/3962/where-is-the-roi#comment22</guid><pubDate>Tue, 21 Apr 2009 04:49:45 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Arne,
  
You have a process problem. Why aren't you giving the developers a real sized database?
  
Why aren't you having a load test with real sized database before going to production?
</description><link>http://ayende.com/3962/where-is-the-roi#comment21</link><guid>http://ayende.com/3962/where-is-the-roi#comment21</guid><pubDate>Tue, 21 Apr 2009 04:42:21 GMT</pubDate></item><item><title>Hendry Luk commented on Where is the ROI?</title><description>I think I don't want to write Linq expression in UI either, just for the same reason I don't want to write SQL/HQL in it.
  
  
I was thinking 3 folds implication:
  
1. Where(customer.FullName.Contains("Something")); We necessarily know that FullName property is mapped to ORM. Restructuring this property to an non-ORM property e.g. get {return FirstName + " " + LastName; } will cause runtime error all over the place. The impact is not isolated, so we need to hunt them down in every single UI screen.
  
I know unit-test helps there but I know many projects that don't even have unit-test (other than their own hands).
  
2. It's really hard to write query in UI if we have to handpick expressions and entity properties that are understood by ORM mapping out of a forest of domain structure. That tightly depends on ORM configuration. IMO it leaks persistence infrastructure to UI layer. And I believe it slows developers down. I think it's sensible to abstract those queries in data-access layer so we can deal with it and never look back at it again. I thought this is what SoC is all about
  
3. There are many ways to write the same Linq expression. Some are more optimum that the other. And I don't think UI layer is the best place to do it.
  
  
More about protecting the team, it's something to protect myself. I don't want to consult ORM mapping config in every screen just to validate if I'm writing a valid Linq expression.
  
  
Btw, what's your view about writing HQL in UI Controller/Services?
</description><link>http://ayende.com/3962/where-is-the-roi#comment20</link><guid>http://ayende.com/3962/where-is-the-roi#comment20</guid><pubDate>Tue, 21 Apr 2009 04:31:10 GMT</pubDate></item><item><title>Rei commented on Where is the ROI?</title><description>Interesting points made by all, so here we go, the be all end all IQueryFilter:
  
  
public interface IQueryFilter
&lt;t  
{
  
        IQueryable
&lt;t GetQuery(IQueryable
&lt;t query);
  
}
  
  
public LatePayingCustomerQuery  : IQueryFilter
&lt;customer  
{
  
        public IQueryable
&lt;customer GetQuery(IQueryable
&lt;customer query) {
  
           //return stuff
  
        }
  
}
  
  
^^
  
  
No need for a reference to nhibernate (no ISession) works with any Linq enabled persistence technology (nh, linqtosql, etc).
  
  
I hope I don't get shot, but i'm implementing it!
  
&gt;</description><link>http://ayende.com/3962/where-is-the-roi#comment19</link><guid>http://ayende.com/3962/where-is-the-roi#comment19</guid><pubDate>Mon, 20 Apr 2009 21:47:39 GMT</pubDate></item><item><title>Arne Claassen commented on Where is the ROI?</title><description>Here's a scenario where stopping the developer before he can hang himself with too much rope is applicable: I used to work on a very large site with a whole lot of traffic. I was part of the DB team. We supported webapp developers with APIs, Ops, etc. but a good portion of our daily operations was recovering from things that shouldn't have been done. Queries that under test DB sizes and loads seemed reasonable to developers that could hang up the main customer database causing apparent site outages in certain areas, kicking in SLAs with partners and other lovely things.
  
  
Now don't get me wrong, that this was possible to occur was the product of many WTFs, but from an operations stand point for my group it was easier to shorten the rope to be hung by than to fix all the systemic problems in the organization (which we tried to fix as well, mind you).
  
  
All that said, i much prefer working on teams where the trust, skills and responsibilities are assigned to all members in such a way that allowing developers to run with scissors is an acceptable risk, and have sought out such organizations since that past experience.
</description><link>http://ayende.com/3962/where-is-the-roi#comment18</link><guid>http://ayende.com/3962/where-is-the-roi#comment18</guid><pubDate>Mon, 20 Apr 2009 21:23:05 GMT</pubDate></item><item><title>Andrew commented on Where is the ROI?</title><description>Nice post, this is something I've believed for some time.   
  
  
I think the 5:01 developers out there get a really bad rap.  Developers who are just there to cash a pay cheque (and there are plenty) will generally move to the point of least resistance.  So they'll code what is easiest, so if you (as in "you" the project lead) write code such is this that they will use, simply explaining it (with a sample) will in most cases be more than enough to get them on the right track.
  
  
Your "average" programmer likely is still an intelligent person, so building roadblocks to prevent usage probably isn't nearly as beneficial as just explaining it to them.
</description><link>http://ayende.com/3962/where-is-the-roi#comment17</link><guid>http://ayende.com/3962/where-is-the-roi#comment17</guid><pubDate>Mon, 20 Apr 2009 16:43:45 GMT</pubDate></item><item><title>Stephen commented on Where is the ROI?</title><description>Ah very true about the cache.
</description><link>http://ayende.com/3962/where-is-the-roi#comment16</link><guid>http://ayende.com/3962/where-is-the-roi#comment16</guid><pubDate>Mon, 20 Apr 2009 14:13:44 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Stephen,
  
That is generally not really that much of an issue.
  
In most cases (unless you have BLOB or TEXT columns), it is actually more efficient to have a single select for rows in the table than to pull out just the columns that you want.
  
Mostly because it will make better use of the query cache
</description><link>http://ayende.com/3962/where-is-the-roi#comment15</link><guid>http://ayende.com/3962/where-is-the-roi#comment15</guid><pubDate>Mon, 20 Apr 2009 13:12:53 GMT</pubDate></item><item><title>Stephen commented on Where is the ROI?</title><description>The only thing I found interesting about pushing the query to the view was that the view (as a template of that data) may often have a better idea of specifically what properties it wants to use.. so far I've kept the controllers knowing what data the view will want to use, but this is something that always pops out at me, but unless theres a performance issue with pushing more properties than needed I don't think it needs to happen.. (by properties I mean the view essentially doing a Select(..) as such to get a subset of the data- with a queryable, the query provider can optimize that requirement to only pull required data).
</description><link>http://ayende.com/3962/where-is-the-roi#comment14</link><guid>http://ayende.com/3962/where-is-the-roi#comment14</guid><pubDate>Mon, 20 Apr 2009 13:06:19 GMT</pubDate></item><item><title>Ayende Rahien commented on Where is the ROI?</title><description>Justin,
  
a) I think you miss the point that I am trying to make. You _don't_ mess around with the query in the view.
  
The highest that you deal with the query (vs. its results) is in the controller.
  
  
b) I fully agree that thought should be put into making sure people fall to the pit of success. I disagree about putting roadblocks along the way, I think it is the wrong approach.
  
  
c) The question is, what is the cost of catching this perf problem in prod? Obviously it can't be too high, otherwise you would have run a load test first. Since it is not too high, why are you worrying about it?
  
  
d) Road blocks don't work. Making sure that the right way to do things is _easy_, and making sure that you put some effort into introducing people to the project properly generally work.
  
People want to do the right thing, after all.
  
  
e) I am working with mixed skilled teams as well. I haven't found this to be the major issue. Training is, and proper introduction, but that is it.
  
I also accept as given that not everyone will write the same level of code, but as long as they are writing good _enough_ code, that is fine
</description><link>http://ayende.com/3962/where-is-the-roi#comment13</link><guid>http://ayende.com/3962/where-is-the-roi#comment13</guid><pubDate>Mon, 20 Apr 2009 12:34:32 GMT</pubDate></item></channel></rss>