Configurations



  • We've all had to do this once in a while:

    Db Table: MyAppConfig
                 itemName varchar2(32) not null,
                 itemVal  varchar2(32)
    

    Then load the configs from the DB during application startup and store them somewhere. This way, you can change the configuration for many servers by simply updating the row for the given flag/attribute in the DB and bouncing the servers.

    I found this:

    Db Table: MyAppConfig_A // A, B, C in lieu of actual config attribute names here
                  itemVal varchar2(32)
              MyAppConfig_B
                  itemVal varchar2(32)
              ...
              MyAppConfig_M
                  itemVal varchar2(32)
    

    ConfigurationDAO:
    public String getMyAppConfig_A() { /* read from db and return / }
    public String getMyAppConfig_B() { /
    read from db and return / }
    ...
    public String getMyAppConfig_M() { /
    read from db and return */ }

    So, not only do we read the configuration from the DB every time it's referenced, we duplicated the table 13 times (for a single row containing a single column of data each) and duplicated the code to query said single row in 13 different functions.

    Naturally, I replaced it with a single table as in my initial example, did a single query and stuffered everything into the environment; then I just modifed each of the accessors to return:

      System.getProperties().getProperty(argNamingConfigAttribute);

    Not really a big deal; there was no common architect, so everyone went off and did their own thing; each blindly (these were fairly junior developers) copying the pattern of the person before them, and after 3 years I get to clean it up. One would think everyone would be happy.

    Not quite.

    TRWTF is that it turns out that some developer of a peer system (that has read access to our DB) spotted the 13 config tables, and recognized one of the flags as something that would be of use to them, but for a totally unrelated reason. So they used our interal configuration flag to control their application. Without asking or telling us.

    Whoops.

    They asked me to change it back.

    Since both of our systems must be deployed at the same time, and that's in a couple of weeks, and it's a 2 minute change, I instructed them to change their application to not depend upon our internal configuration flags.

    They whined. I stood my ground.They whined to their boss who asked my boss who asked me to explain. I explained. The other boss agreed that they should not be using our internal configuration flags and agreed to make the change.

    I suggested that since this has already happened, that perhaps a system-wide search for other instances of such nonsense be performed - long before the next release. Both managers agreed.

    It's the little victories...



  • @snoofle said:

    [...] Both managers agreed.

    It's the little victories...

     

    This is a bad omen.



  • That's great mate, I kept expecting a twist in the tale, lol. Sanity prevails (for a change).



  • @snoofle said:

    We've all had to do this once in a while:

    Db Table: MyAppConfig
                 itemName varchar2(32) not null,
                 itemVal  varchar2(32)
    

    Then load the configs from the DB during application startup and store them somewhere. This way, you can change the configuration for many servers by simply updating the row for the given flag/attribute in the DB and bouncing the servers.

    I found this:

    Db Table: MyAppConfig_A // A, B, C in lieu of actual config attribute names here
                  itemVal varchar2(32)
              MyAppConfig_B
                  itemVal varchar2(32)
              ...
              MyAppConfig_M
                  itemVal varchar2(32)
    

    ConfigurationDAO:
    public String getMyAppConfig_A() { /* read from db and return / }
    public String getMyAppConfig_B() { /
    read from db and return / }
    ...
    public String getMyAppConfig_M() { /
    read from db and return */ }

    So, not only do we read the configuration from the DB every time it's referenced, we duplicated the table 13 times (for a single row containing a single column of data each) and duplicated the code to query said single row in 13 different functions.

    Naturally, I replaced it with a single table as in my initial example, did a single query and stuffered everything into the environment; then I just modifed each of the accessors to return:

      System.getProperties().getProperty(argNamingConfigAttribute);

    Not really a big deal; there was no common architect, so everyone went off and did their own thing; each blindly (these were fairly junior developers) copying the pattern of the person before them, and after 3 years I get to clean it up. One would think everyone would be happy.

    Not quite.

    TRWTF is that it turns out that some developer of a peer system (that has read access to our DB) spotted the 13 config tables, and recognized one of the flags as something that would be of use to them, but for a totally unrelated reason. So they used our interal configuration flag to control their application. Without asking or telling us.

    Whoops.

    They asked me to change it back.

    Since both of our systems must be deployed at the same time, and that's in a couple of weeks, and it's a 2 minute change, I instructed them to change their application to not depend upon our internal configuration flags.

    They whined. I stood my ground.They whined to their boss who asked my boss who asked me to explain. I explained. The other boss agreed that they should not be using our internal configuration flags and agreed to make the change.

    I suggested that since this has already happened, that perhaps a system-wide search for other instances of such nonsense be performed - long before the next release. Both managers agreed.

    It's the little victories...

    You could have created views and save everyone a lot of wasted time. And by "everyone" I mostly mean people reading this entire post hoping for some kind of actual WTF.



  • @Speakerphone Dude said:

    You could have created views and save everyone a lot of wasted time spent by learning how to do things the correct way.
     

    FTFY (/ATFY?)



  • @SEMI-HYBRID code said:

    @Speakerphone Dude said:

    You could have created views and save everyone a lot of wasted time spent by learning how to do things the correct way.
     

    FTFY (/ATFY?)

    Creating one property bag that contains 13 records instead of having 13 configuration tables that contain 1 record each is a design preference that has pros and cons, and is by no mean the "Correct Way". On the cons side, there is no performance gain, and it does open the door to creating a meta-database inside that property table ("why should we create a table just for this thing, let's add it to the property bag!").

    If the system had been in a design phase, deciding to have one table instead of 13 could have been justified (we don't have enough info to decide here). But in this case, not only is it absolutely not necessary, this actually broke applications relying on the (allegedly) suboptimal table layout; and somehow the WTF is that "that other group" should never have used those tables so it's too bad for them, and let's go on a witch hunt to add the insult to the injury. This is TRWTF and makes this whole situation far from being "the correct way" to handle things. Even if there was a crucial need to have a single table right away (and it was not just the actions of a bored/zealous contractor), knowing that someone was using the old layout could have been simply flagged as a low-priority change request and a bunch of views could have been created to avoid causing disruption in the meantime.

    Here is the take away from that story:

    1. If you don't want people to use some tables in a shared database, don't give read permissions to everyone in the first place.
    2. If your organization is so poor at data management that you have no idea which internal group is using what database, then you have a much bigger problem than having a small record/table ratio.
    3. If your workload is so low that all you have to do is refactoring how configuration items are accessed, at least have the decency to avoid impacting the remaining people in your organization with your Correct Way as those may have actual work to do.

    In other words, if it ain't broke, don't fix it.



  • @snoofle said:

    It's the little victories...


    Who are you and what have you done with the real Snoofle? We all know there are no victories at Snoofle's workplace…



  • @Speakerphone Dude said:

    ..You could have created views...if it ain't broke, don't fix it

    I can't imagine creating a view of 13 config tables being a good thing, even if the volumes are miniscule. Clearly there was redundancy in both tables and code.

    My job is to explicitly seek out duplicity, inefficiency, and general wrong-doings in the code. I've spent more than a year tackling the bigger things, and now I'm onto the smaller stuff. When I find something, I discuss it with my boss, we agree on an approach, and then I go off and fix it as agreed. Neither one of us had any notion that someone from another team was misusing a config flag. True, the other team shouldn't have read access to these tables, but the DBAs (whom I've said before are not accountable to us) set it up on a per schema basis, and can't be bothered managing it in finer detail. Not ideal, and in this case it allowed someone to go in and do something wrong. If we had simply changed the value stored in that row, it still would have broken the other application, so the other application had to be fixed anyway. The managers from both teams agreed.

    I never said that the solution we chose was THE correct way (there are many ways to skin a cat); merely that it was the way we chose to combine the code and tables.

    As far as: if it ain't broke, don't fix it: what if it works, but in such a way that it's expensive to maintain (and getting moreso with each new function), inefficient and sucking up mountains of resources, etc? Just because it works now doesn't mean it will work tomorrow when the business grows.

    Most startups rush to get version 1.0 out the door with any functionality they can. At any technology debt cost.Then they rush to get real functionality out the door in version 2.0. At any technology debt cost. By version 3.0, that technology debt becomes expensive in terms of added hardware that might not otherwise be needed. For example, over the last several months, I've reduced our application requirements by 40GB of ram per server, lowered our rate of DB growth by 30%, reduced DB I/O time by 98% and improved our response time by 60%. That's upward of $2MM/year in servers and disks that don't need to be purchased. Sometimes you need to fix it while it's limping along before it completely collapses under its own weight.

    Food for thought...



  • @Speakerphone Dude said:

    1. If you don't want people to use some tables in a shared database, don't give read permissions to everyone in the first place.
    2. If your organization is so poor at data management that you have no idea which internal group is using what database, then you have a much bigger problem than having a small record/table ratio.

    You are new here, aren't you? It's snoofle we are talking about, of course there are bigger WTFs around this one. It is how things work at snoofle's place.

    Now, @snoofle. Ok, great, you increased the speed of reading the settings, did you already write the sleeps to offset that?


     



  • @Mcoder said:

    Now, @snoofle. Ok, great, you increased the speed of reading the settings, did you already write the sleeps to offset that?
    Not really necessary; that was more under the heading of cleaning up duplication.

    However, I'm presently debugging something that appears to use both Spring and Hibernate transactions, from different connection pools, interleaved, across thread boundaries, Don't yet know what fuckery I'll find, but I ran across a comment, dated 2009: "Do not change or alter this section of code in any way if you value your sanity". It sat, unmodified for 3 years. Then the SAME person made a subtle change to it, and now it doesn't work, and he can't figure out why. He rolled back his change, but the problem persists. Perhaps some demon, long since asleep, has been awkened...



  • So the WTF in this topic is the suspicious lack of WTFs in a post from snoofle?

    I can live with that.



  • @snuffle said:

    ...It sat, unmodified for 3 years. Then the SAME person made a subtle change to it, and now it doesn't work, and he can't figure out why. He rolled back his change, but the problem persists. Perhaps some demon, long since asleep, has been awkened...
    Seeing that reminded me of this quote:
    “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

    • Brian Kernighan


  • @snoofle said:

    As far as: if it ain't broke, don't fix it: what if it works, but in such a way that it's expensive to maintain (and getting moreso with each new function), inefficient and sucking up mountains of resources, etc? Just because it works now doesn't mean it will work tomorrow when the business grows.

    Most startups rush to get version 1.0 out the door with any functionality they can. At any technology debt cost.Then they rush to get real functionality out the door in version 2.0. At any technology debt cost. By version 3.0, that technology debt becomes expensive in terms of added hardware that might not otherwise be needed. For example, over the last several months, I've reduced our application requirements by 40GB of ram per server, lowered our rate of DB growth by 30%, reduced DB I/O time by 98% and improved our response time by 60%. That's upward of $2MM/year in servers and disks that don't need to be purchased. Sometimes you need to fix it while it's limping along before it completely collapses under its own weight.

    There is nothing wrong with optimization. But the "tweaking" you did by injecting a property bag to replace 13 configuration tables is unlikely to save millions of dollars in hardware cost. All it does is force regression testing, increase the risk of unforeseen side effects and disrupt people who are possibly working on value-added features. If someone was to run maintenance cost projections of the "suboptimal" 13-table version over 5 years versus the actual cost of the disruption caused by this change it would probably end up in the "premature optimization" column. Principles are nice but they come with a price tag.

    When one ventures out of the value chain, one needs to be sure that the benefits of his actions will a) not hurt the value chain and b) prove cost-effective. In this case IMHO it's a fail on both counts, for both you and your boss who approved this.

    Code optimization is like garbage collecting (IRL) or law enforcement; it's an expensive service that has its place but that should not prevent normal activities from taking place, especially since it's those normal activities that pay for it.

    This being said, since the other dudes were doing a bit of guesswork by reading data in those tables they had it coming, but unless the outcome of this incident is that they will not use the new property bag then you really just added noise.



  • Reminds me of a time when, on the CDC 6400, somebody coded a routine to print numbers in octal (base 8). He found a variable that always had 8 in it, so he used that as the radix.

    Worked fine until they ported the code to the IBM 360, and the number of characters in a word dropped from 8 down to 4. Quaternary!

     



  • @snoofle said:

    @Mcoder said:

    Now, @snoofle. Ok, great, you increased the speed of reading the settings, did you already write the sleeps to offset that?
    Not really necessary; that was more under the heading of cleaning up duplication.

    However, I'm presently debugging something that appears to use both Spring and Hibernate transactions, from different connection pools, interleaved, across thread boundaries, Don't yet know what fuckery I'll find, but I ran across a comment, dated 2009: "Do not change or alter this section of code in any way if you value your sanity". It sat, unmodified for 3 years. Then the SAME person made a subtle change to it, and now it doesn't work, and he can't figure out why. He rolled back his change, but the problem persists. Perhaps some demon, long since asleep, has been awkened...

    Ok this nearly made me spit my tea over my monitor. That sounds like some real nice WTF-ery to start the week with. Good luck with slaying the demon, Snoofle!



  • @snoofle said:

    and stuffered everything into the environment

    Is this a new verb I've not heard of? A portmanteau of stuffed and buffered? If I so I like it.



  • @snoofle said:

    I ran across a comment, dated 2009: "Do not change or alter this section of code in any way if you value your sanity". It sat, unmodified for 3 years. Then the SAME person made a subtle change to it, and now it doesn't work, and he can't figure out why. He rolled back his change, but the problem persists. Perhaps some demon, long since asleep, has been awakened..

    [url="http://www.youtube.com/watch?v=59BHNYpKx2A"]Fly, you fool[/url]



  • @Quango said:

    @snoofle said:
    and stuffered everything into the environment

    Is this a new verb I've not heard of? A portmanteau of stuffed and buffered? If I so I like it.

    Maybe it's stuffed and suffered....



  • @snoofle said:

    They whined. I stood my ground.They whined to their boss who asked my boss who asked me to explain. I explained. The other boss agreed that they should not be using our internal configuration flags and agreed to make the change.

    I suggested that since this has already happened, that perhaps a system-wide search for other instances of such nonsense be performed - long before the next release. Both managers agreed.

     

    Shiiiiit... 

    Enjoy it whilst it lasts, snoofez. Abnormal service will be resumed very soon.

    @Speakerphone Dude said:

    In other words, if it ain't broke, don't fix it.

    Fuck right off.

    Anyone who quotes this to me is cordially invited to come rock-climbing using a rope I've carefully sawn partly through.

    It ain't yet broke, so I won't fix it.

    Strangely, they don't take me up on the offer.

    "If you don't fix it, it WILL break" is a better mantra.

     


  • Discourse touched me in a no-no place

    @Speakerphone Dude said:


    There is nothing wrong with optimization. But the "tweaking" you did by injecting a property bag to replace 13 configuration tables is unlikely to save millions of dollars in hardware cost. All it does is force regression testing, increase the risk of unforeseen side effects and disrupt people who are possibly working on value-added features. If someone was to run maintenance cost projections of the "suboptimal" 13-table version over 5 years versus the actual cost of the disruption caused by this change it would probably end up in the "premature optimization" column. Principles are nice but they come with a price tag.

    Well, no. This is why you don't rely on undocumented features: because they're not part of the contract, and they're subject to change without notice.



  • @OzPeter said:

    ...Seeing that reminded me of this quote:
    “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

    • Brian Kernighan

    That quote is going to my sig line ASAP.


  • Seriously, Speakerphone Dude, how can you live with yourself defending a db design with 13 config tables? Just listen to yourself. First there is the broken window principle. And this looks more like a shattered skyscraper to me. Secondly, there is the professionality aspect. If any product I bought / used had enumerated tables like that I would run away screaming in sheer horror. Not fixing that sh*t should be considered a federal offense if you ask me. And snoofle does a good job pointing this out, so that the creators of this WTF can learn. Keep 'em coming snoofle!



  • @Obfuscator said:

    Seriously, Speakerphone Dude, how can you live with yourself defending a db design with 13 config tables?

    I like your style: flamboyant, yet mundane. You remind me of those people who have to pretend to be excited and overwhelmed when thy win a t-shirt live on a FM radio program during rush hour.


Log in to reply