• knackwurst (unregistered)

    maybe it'll be super-duper-fast if they use negative numbers in the wait.cfg?

  • OrangeYoda (unregistered)

    seems to me to be a pause to keep the website fast, the developers are usually on an ethernet connection to the server, and they want to make sure that when someone connects from the interwebs that they don't get a sluggish website.

    Slow config for development, No/1ms config for the real website.

    It acutally works faster in production than in development.

  • David (unregistered)

    facepalm

    Thought this was a story about fighting the "eviltable". I might need glasses.

  • Trawn (unregistered)

    You might want a delay in Signup actions if you use a database replication scheme. (Write to a DB remote master db, read from local - where remote updates local read only)

    Or you have multiple web servers in a cluster and need to make sure the session data is replicated to all of them if you have a dumb load balancer (round robin dns).

    Or NFS...(need I say more?)

  • diaphanein (unregistered) in reply to T-Biscuit
    T-Biscuit:
    This is usually a sign of somebody trying to cheat a multithreaded application. A Thread.Sleep(1) is effectively <Trigger Interrupt> so that if it's the first thread to get there, someone else gets to go first instead. I'm not advocating the practice, I'm just saying that that's what I've seen it used for. It makes the race condition that they were trying to fix happen less often.
    sleep(0) is typically just as effective to force a context switch w/o the calling thread to wait a specified amount of time.
  • sd (unregistered)

    Wow that post took a long time to go through, anyway... bots, brute force attacks etc. Login and signup screens should be implementing this behavior. Not a very smart move to get rid of it. Not a very smart team if they couldn't collectively determine why it was there.

  • mauhiz (unregistered)

    In my opinion, the developer wanted to make room for tremendous optimisation.

    "Look, boss, the signup process is now 10x faster !"

    But he got fired since, and Paul stole the glory.

  • Fedaykin (unregistered)

    "The design was kind of strange; all HTTP requests were routed through Actions. Most Actions inherited from other Actions – for instance, LoginAction and SignupAction inherited from DelayableAction, which inherited from ActionBase."

    How exactly is this a "strange" design? Off the top of my head, I could name about a dozen web frameworks that implement an action based architecture.

    Not necessarily the best way to go about it? Sure.

    A WTF possible if implemented with custom code instead of readily available frameworks? Definitely

    Strange? Not even remotely.

  • rd (unregistered) in reply to Steve H
    Steve H:
    Skizz:
    First!

    (Oh, god, I can't believe I've sunk so low)

    And then failed at it anyway.

    Thanks for playing, please don't come around here any more.

    I didn't see that as a fail, but as a very successful delay implementation.

  • (cs)

    We've actually done stuff like this on purpose in some of our user interface software running on embedded processors.

    The reason being is that when someone would push a button to do the action that it'd be so fast users weren't sure if it actually happened or not. Since these are usually very limited text based LCD's, can't pop up a OK Message box when it's done for confirmation. So for that reason we had to implement a fake delay based progress message so that the few microsecond action gets turned into something that the user can watch for a few seconds.

  • RBoy (unregistered) in reply to Steve H
    Steve H:
    Skizz:
    First!

    (Oh, god, I can't believe I've sunk so low)

    And then failed at it anyway.

    Thanks for playing, please don't come around here any more.

    You just lost.

    Hey, not my fault you didn't get it, don't get all vindicto on me.

  • RBoy (unregistered)

    I would have changed the wait time to a negative number. Just think how fast it would be then.

    Captcha: Odio - A tribute song to Ronnie James Dio.

  • Anonymous (unregistered) in reply to RBoy
    RBoy:
    I would have changed the wait time to a negative number. Just think how fast it would be then.

    Captcha: Odio - A tribute song to Ronnie James Dio.

    And now I have "Holy Diver" in my head, thanks a lot!

  • Buffled (unregistered) in reply to Code Dependent
    Code Dependent:
    public void lay() { try { Bed.sleep(getGirlfriend()); } catch (InterruptedException ignored) {} }
    You want your bed to sleep with your girlfriend and not allow you to interrupt? Kinky.
  • anerkie33 (unregistered) in reply to diaphanein
    diaphanein:
    Code Dependent:
    public void lay() { try { Bed.sleep(getGirlfriend()); } catch (InterruptedException ignored) {} }
    Fails to link: unresolved symbol "getGirlfriend"

    I think you mean callerHasNoChanceOfEverGettingLaidException

  • (cs) in reply to Anonymous
    Anonymous:
    the real WTF (sorry) is all the people who think that fixed delays are a suitable solution to multi-threading concurrency issues!
    Of course not! That's why I always use random delays instead of proper synchronization! :*P

    np: Uusitalo - Vesi Virtaa Veri (Karhunainen)

  • (cs) in reply to T-Biscuit
    T-Biscuit:
    A Thread.Sleep(1) is effectively <Trigger Interrupt> so that if it's the first thread to get there, someone else gets to go first instead.
    If you just want to yield, do a Thread.yield() already...

    np: Uusitalo - Vesi Virtaa Veri (Karhunainen)

  • AC (unregistered)

    All right, I hate to be "that guy", but I really don't see the WTF here.

    First, there's nothing "strange" about routing all HTTP requests through actions. This is known as the Front-Controller pattern, and is commonly used for (Java) web apps. They were probably using struts or a clone of it, as request handlers there all extend from a base class "Action".

    Having Actions extend from other Actions can be useful for reusing common code (as evidenced by the DelayableAction here), though it's probably better to have a utility class than to have to give up your one base class to get the delay functionality (in a single-inheritance environment).

    Using Thread.sleep() is a little WTF-y, as you're not really supposed to mess with Threads directly (assuming they're running in a JEE container). It gets the job done, though, and is a lot simpler than trying to use some kind of timer functionality. The only real downside is it violates the spec, so you have to re-test for each container you deploy to.

    Then there's the question of why it's there. As others have pointed out, this is almost certainly to prevent brute-force attacks, as it's on the login and signup page. The beauty of the way it's implemented (and probably the reason it was done this way) is that Actions can override getProcessingDelay() to include arbitrarily-complex logic, such as increasing the time based on the number of attempts. For now, they just implemented the simple method, as they didn't see the need for more complex.

    All-in-all, sounds like pretty nice code. He wasn't sure why the Login action was taking so long, looked at the LoginAction class, and saw that it extended DelayableAction, and defined a delay. Once they had decided to remove the delay, all it took was redefining the base class and/or setting processingDelay to zero. What more can you ask for?

    "Removing the feature didn't break anything, so now it runs a lot faster."

    A sign of a well-designed system, if you ask me.

  • (cs)
    Removing the feature didn't break anything, so now it runs a lot faster.

    Stupid!

    That was what is called a bonus guarantee. When it's time to impress the boss again, you shave off a second or two and boast about how you improved performance by 70%.

    And now you've broken it and need to find something else to justify your job.

  • CynicalTyler (unregistered)

    This is the least WTFy of all the WTFs I've seen here. At least the design was all nicely Object Oriented and there was a clear separation of concerns. Don't see what Paul was complaining about, I would kill to be solving problems this nicely organized. KILL!

  • Old fart (unregistered)

    Reminds me of what we used to do twenty-five years ago at the Large Government Agency when we ran on the IBM mainframe using the CICS transaction processing system. Everytime we opened a new CICS region for production, it would run lightening fast at first, incrementally slowing as more and more applications were added to the region.

    So we introduced an artificial five-second delay in response time when we deployed the application. As response times became longer, we dialed back the delay to keep it around five seconds. This put a stop to user complaints about degrading response times that had plagued the IT department in the earlier days.

    The lesson learned was that it's less about response times and more about managing customer expectations.

  • T.J. (unregistered)

    I'm guilty of this myself (to an extent). When working with ajax interactions, such as form submits, some people get confused when the response is immediate. As such, I display a 'loading' gif while waiting for the response, and delay it to 1000ms if the response comes back that fast.

  • bramster (unregistered) in reply to akatherder
    akatherder:
    Herman:
    We had a webapplication once with a 10 second javascript 'delay' that would let your PC count to ten million while showing a 'please wait' screen.

    I saw it was completely useless and removed it, because it served absolutely no purpose. Now you would go instantly from screen A to B!

    A day later my boss received a phonecall from one of the managers with the complaint that the 'please wait' screen was gone. A few minutes later he told me to put it back.

    That reminds me of the time, I saw this guy limping. I asked if he twisted an ankle or hurt his leg. He said he just had a pebble in his shoe. I asked if I could have his shoe and dumped the pebble out. He starting walking away and asked for his pebble back.

    It was his wife's way of ensuring his fidelity. A pebble in is shoe and he's limp all day

  • Software Monkey (unregistered) in reply to Steve Syfuhs
    Steve Syfuhs:
    Maybe he slept with the boss (or the bosses wife) and stuck the code in there as sabotage.

    Why not assume it was the bosses husband??

  • Forte (unregistered)

    It's not really the same thing, but back in the day I worked on a system that used a delay so users wouldn't notice the system going slower at peak usage. At peak times it took about 8 seconds to process an order, but most of the time it took about 0 seconds. The delay would make it wait 10 seconds regardless. It was stupid, but it made for happy users. They liked it predicable more than they liked it fast.

  • CoyneT (unregistered) in reply to knackwurst
    knackwurst:
    maybe it'll be super-duper-fast if they use negative numbers in the wait.cfg?

    I bet if they're negative enough, the account could actually be created before you click the button.

    ...but then what if you decide not to click the button? Hmmmm...

  • flo (unregistered) in reply to Dennito

    What's so clever about this, it's not even properly implemented! It uses a fixed value from a config while if I read that correctly, also a brute-force protection would delay subsequent login attempts, not the first, and from what I gathered from the post it seems more like it just makes the actual login go slow, but this in no way prevents someone from trying to login again and again.

  • Ken B (unregistered)
    Whatever the reason for the feature, it wasn't necessary. Removing the feature didn't break anything, so now it runs a lot faster.
    Silly newbie programmer. Everyone knows that he was supposed to simply decrease the delay. And a few months later, decrease it again. Repeat. This way, he can get credit several times for his "optimizations" that made the application faster.
  • Real-modo (unregistered) in reply to Andy
    Andy:
    The best way to fix a bug in a multi-threaded application is to throw in a bunch of random delays, and pray that your application never actually has to do two things at once.
    Hey Andy, the sarcasm melted my screen!
  • MT Guy (unregistered) in reply to Andy

    This is exactly right. Putting in a static delay does nothing to alleviate parallelism, nor the rate at which subsequent calls are made. (500 requests wait for five seconds, then all 500 still hit the db at the same time.) The posts wondering if they've reintroduced a subtle bug are mistaken.

  • Quadeddie (unregistered)

    A co-worker put in a set javascript "processing" delay just so he could be sure users would see his repeating "dolphin jumping through a hoop" animated gif.

    It was a very WTF moment that this article reminded me of.

  • Donkey (unregistered) in reply to MT Guy
    MT Guy:
    This is exactly right. Putting in a static delay does nothing to alleviate parallelism, nor the rate at which subsequent calls are made. (500 requests wait for five seconds, then all 500 still hit the db at the same time.) The posts wondering if they've reintroduced a subtle bug are mistaken.

    I'm in a different time zone...my 5secs is different to everyone else's 5 secs....

  • dusoft (unregistered)

    what about point 5: delaying robots trying to make auto registration or spam comment sent?

    this is definitely not a WTF!

    captcha is the biggest WTF and you got it implemented!

  • Neeneko (unregistered)

    While I agree with the general assessment that this was probably either to deal with some non tread safe objects or stop brute force attacks, it is also possible that it was there for UI/psych reasons.

    Not to long ago I was asked to add a delay to a UI so that users couldn't click too quickly and thus double-click through screens without reading (or accidentally clicking twice and thus going through two screens instead of one). There is also a school of thought that states users do not think something is working hard enough if it returns quickly so adding a little delay gives a feeling of weight behind the processing. Too quick and it looks broken (or cheap). Strange but so are people.

  • (cs) in reply to Neeneko
    Neeneko:
    Not to long ago I was asked to add a delay to a UI so that users couldn't click too quickly and thus double-click through screens without reading (or accidentally clicking twice and thus going through two screens instead of one).
    The UI doesn't have separate event handlers for click and doubleclick?
  • Bankman (unregistered) in reply to Neeneko
    Neeneko:
    While I agree with the general assessment that this was probably either to deal with some non tread safe objects or stop brute force attacks, it is also possible that it was there for UI/psych reasons.

    Not to long ago I was asked to add a delay to a UI so that users couldn't click too quickly and thus double-click through screens without reading (or accidentally clicking twice and thus going through two screens instead of one). There is also a school of thought that states users do not think something is working hard enough if it returns quickly so adding a little delay gives a feeling of weight behind the processing. Too quick and it looks broken (or cheap). Strange but so are people.

    I've often wondered if some of the noises ATM's make when they are processing are fake. It's odd that an EFTPOS transaction can be authorised almost immediately, but it takes more time (and whirring noises) to even authorise money to be withdrawn from an ATM. I'm sure most people will say that the whirring is money being extracted and double checked from the cartridge, but I suspect there's a little smoke and mirrors too - I can get change in notes from automated check-outs quicker than from the ATM.

  • David (unregistered) in reply to Dennito
    Dennito:
    It's actually quite a clever way of preventing brute force logins and multiple user account creation. If getProcessingDelay() doubled after each failed login attempt, it would be a pretty effective technique.

    It would be better to have the delay after failed logins though, not successful ones.

  • (cs) in reply to RBoy
    RBoy:
    Steve H:
    Skizz:
    First!

    (Oh, god, I can't believe I've sunk so low)

    And then failed at it anyway.

    Thanks for playing, please don't come around here any more.

    You just lost.

    Hey, not my fault you didn't get it, don't get all vindicto on me.

    I lost.

  • Jeremy Friesner (unregistered) in reply to Herman
    Herman:
    A day later my boss received a phonecall from one of the managers with the complaint that the 'please wait' screen was gone. A few minutes later he told me to put it back.

    You (or your boss) should ask that manager why he thinks that removing the 'please wait' screen is bad. Either he will have a good reason (and it's possible there is one), and you will then know why that screen exists... or he won't, and at that point you can remove the useless screen.

    Never pass up an opportunity to learn something :^)

  • Jeremy Friesner (unregistered) in reply to Anonymous
    Anonymous:
    How have so many people suggested this? It's guaranteed to slow down execution, it's a maintenance nightmare just waiting to happen and let's be honest, once you've got your head around multi-threading it is trivially easy to manage threads properly without ever having to rely on fixed period blocks.

    You forgot the biggest problem with adding delays: it doesn't actually fix the underlying race condition. With the delays in, the race is still possible, just much less likely. That means that now instead of having to diagnose mysterious errors that happen once an hour, you have to diagnose mysterious errors that happen once a year. Good luck with that :^)

  • Aut (unregistered) in reply to lolwtf
    lolwtf:
    RBoy:
    Steve H:
    Skizz:
    First!

    (Oh, god, I can't believe I've sunk so low)

    And then failed at it anyway.

    Thanks for playing, please don't come around here any more.

    You just lost.

    Hey, not my fault you didn't get it, don't get all vindicto on me.

    I lost.

    I just lost the game.

    And so have you.

    Captcha: Vulputate

  • Douglas Adams (unregistered) in reply to Steve H
    Steve H:
    Skizz:
    First!

    (Oh, god, I can't believe I've sunk so low)

    And then failed at it anyway.

    Thanks for playing, please don't come around here any more.

    Whoosh!

  • (cs)

    I was annoyed by a splash screen wasting time while testing an application. Code was in place to not show the splash screen if a certain file was present, but I couldn't be bothered creating one especially since the splash screen was actually from a different application which the new application was based off, so I wanted to disable it for certain until a new splash screen had been created. But for some reason I didn't simply comment out the offending code, but rather added a new variable:

    private void splashScreen1_canShowSplash(object sender, ShowSplashArgs e)
    {
    	bool ImTestingSoDoNotShowTheSplashScreenPleaseMrNiceComputer = true;
    	if (ImTestingSoDoNotShowTheSplashScreenPleaseMrNiceComputer || new FileInfo(Environment.CurrentDirectory + "\\nosplash.txt").Exists)
    	{
    		e.Show = false;
    	}
    }
    What was I thinking?

    gets rid of offending code

  • Not as DULL as you (unregistered)

    Two RWTF's:

    1. anyone who thinks it was a good idae to do this to stop brute force attacks. The only appropriate delay for this would be after a failed attempt.

    2. Developers meeting and agreeing on a list of possible reasons.

  • (cs) in reply to Software Monkey
    Software Monkey:
    Steve Syfuhs:
    Maybe he slept with the boss (or the bosses wife) and stuck the code in there as sabotage.

    Why not assume it was the bosses husband??

    Because the majority of people are not homosexual.

  • Marshall (unregistered)

    Many years ago I was told of an early time-sharing system that didn't have the world's fastest response time but managed to keep a consistent response regardless of the number of users.

    The developers calculated the expected response when it would be fully loaded then built that delay in to the initial system. As more users were added the value of the delay was gradually reduced so that from a single user right through to fully loaded the response time was always constant.

  • (cs)

    It's hilarious watching you guys do your forensic analysis of someone else's code snippets. All very likely explanations, except...

    If it was an intentional performance degradation for later "optimization" it would not be so obvious as to be in a sleep call. Anyone loathesome enough to meter their skills is devious enough to cover their tracks.

  • db (unregistered) in reply to Andy

    One of the python developers where I work can't work out how to handle multiple threads. He actually turned off one core on his laptop so that he can run his own code. Pretty poor for 2009 when even a Nintendo DS has multiple processors.

  • anders (unregistered) in reply to Anonymous

    Someone here said "once you've got your head around multi-threading it is trivially easy to manage threads properly without ever having to rely on fixed period blocks. ".

    I just wanted to point out that a lot of well respected programmers do not agree with you. While sleeps don't really help at all, the other available primitives don't make multi threading easy, either.

    Just ask, for instance, Tim Sweeney or Donald Knuth.

  • (cs) in reply to Old fart
    Old fart:
    ...The lesson learned was that it's less about response times and more about managing customer expectations.
    Completely correct. I've put delays into code at least twice. The first was because the new app was plenty fast, but we knew that phase 2 would introduce delays, so as we phased in more code, we phased out the delays to keep things even (which is what users really like). The second was on an update window which looked very complicated but actually did very little when you hit OK button; in UAT, users were unsure if their changes had been effected or not, as the return was "too fast". Bung in a 2-second delay and everyone is happy.

Leave a comment on “Delaying the Evitable”

Log In or post as a guest

Replying to comment #:

« Return to Article