• Skizz (cs)

    Delaying comment by 5000ms

  • Skizz (cs)

    First!

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

  • Pony Princess (unregistered)

    1... 2... 3... 4... 5...

    Maybe it was to make room for "optimisation" later.

  • RayS (cs)

    Ah I see that WTF... they just immediately put in the fix and brought with it the speedup. What SHOULD have been done was keep it in their back pocket and only implement it just before pay review time.

  • Eric (unregistered)
    Comment held for moderation.
  • amischiefr (cs) in reply to Pony Princess
    Pony Princess:
    1... 2... 3... 4... 5...

    Maybe it was to make room for "optimisation" later.

    QFT

    This guy wanted to be a hero later no so he placed things in there to intentionally make it slow, just so that he could go and save the day later. Brilliant!!!

  • Coincoin (cs)

    Maybe to prevent brute force attacks?

    Or more likely job security. I did allocate some almost useless big buffers in an embeded application once, and when time came to optimize memory usage, I just removed them and then I was a hero. That is, until I admited a few seconds later how stupid (or drunk) I was when I first wrote the code.

  • Steve Syfuhs (unregistered)

    I am both disappointed and saddened by this post, moreso than the usual depression that hits with the reading of these. It would have been far better if it slowed waaaaay down once he removed the sleep calls. Ah well.

    Good moral though. Maybe he slept with the boss (or the bosses wife) and stuck the code in there as sabotage.

  • halcyon1234 (cs)

    Parsing error: Mismatched number of quotes detected (").

    (A)bort, (R)etry, (T)RWTF?

  • Dennito (unregistered) in reply to Coincoin

    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.

  • Robert Frapples (unregistered)

    I ran into a similar thing recently. Code I was maintaining waited several seconds before running reports launched from a web site. It used to be that several objects were not thread-safe, so the delay had to be there to ensure that the HTTP response finished before the report started. The objects were later made thread-safe, but the delay was not removed.

  • pitchingchris (cs) in reply to amischiefr
    amischiefr:
    This guy wanted to be a hero later no so he placed things in there to intentionally make it slow, just so that he could go and save the day later. Brilliant!!!

    Not so Brilliant when you leave it in there long enough for somebody else to save the day and make you look like an a!!.

  • BillyBob (unregistered)

    This isn't by chance taken from the new hotmail code base?

  • Vollhorst (unregistered)

    Well, when you sell an application (even web) to your customer you sell it "as it is". So when you later on add more functionality which makes it slower you can be sure the customer will bitch about it. Doing it this way you can later on add features and in the mean time reduce the delay so that in the end it is as fast as before so no one sees a difference in the speed. Even if it could run faster it will always run at almost the same speed. People love what they are used to.

  • KJW (unregistered)

    This surely is just a poorly implemented method of slowing down logins to prevent brute-force attacks?

    No one really puts slowdown loops in their applications, do they...?

  • _dew_ (unregistered) in reply to amischiefr
    amischiefr:
    QFT

    This guy wanted to be a hero later no so he placed things in there to intentionally make it slow, just so that he could go and save the day later. Brilliant!!!

    that's it. not so brilliant but, eh

  • TW (unregistered)

    Not sure that fixing a minor usability issue by introducing a brute-force attack vulnerability is quite the best way around things...

    It'd be better to remove the delay only for the first request for a given IP and/or username. Even better is for subsequent requests to increase the time required to the point where "normal" usage (one or two password miskeys followed by in) incurs only a small time penalty, barely noticeable on human timescales, whereas "abnormal" situations like a brute-force attack quickly reach a point where each failed attempt takes so long that even a dictionary attack is going to be a life-of-several-universes job.

  • Quango (cs) in reply to Pony Princess
    Pony Princess:
    1... 2... 3... 4... 5...

    Maybe it was to make room for "optimisation" later.

    Sadly most of my code has plenty of room for "optimisation" at a later date!

  • Lamah (unregistered) in reply to KJW
    KJW:
    This surely is just a poorly implemented method of slowing down logins to prevent brute-force attacks?

    It's a brilliantly implemented method of allowing denial of services attacks though - create thousands of threads which sleep for a long time, eating up resources.

  • Lev (unregistered)
    Comment held for moderation.
  • Code Dependent (cs)

    public void lay() { try { Bed.sleep(getGirlfriend()); } catch (InterruptedException ignored) {} }

  • [twisti] (unregistered)

    It seems much more likely that this was an idiot fix to a racing condition that probably has been unwittingly reintroduced by the moron submitter that will end up costing his company millions.

  • synp (unregistered)

    The anti-brute-force idea is possible. It's also possible that they slowed down by a constant amount to get a more uniform response time.

    If the login time is between 0.2 seconds and 3 seconds depending on network load and the number of hops, then the 3 seconds looks very slow. Add three seconds, and you get the login time to be between 3.2 and 6 seconds. Now the 6 seconds doesn't feel slow, because you're used to it taking time to log in.

  • Kiss me I'm Polish (cs)

    Oh well, I would be first if it wasn't for the login delay.

  • Osno (unregistered)

    Probably a concurrency issue. This must have been to avoid using a shared resource (the log file) from two simultaneous threads.

  • Herman (unregistered)

    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.

  • Anonymous (unregistered)

    Coincidentally, I've spent most of the day looking at completely undocumented sleep calls in our code. Interestingly enough, some of them are for a single millisecond only. Usually TDWTF is a pleasant escape from reality but today it just looks like the same crappy code I'm being forced to work on...

  • (Visitor) (unregistered)

    I vote for #4.

  • m0ffx (cs)

    I just hope the OP TESTED the change, and thoroughly. It could have been in there to fix a really subtle and nasty bug, and not documented by the person who wrote it.

    Never change stuff in production. I think that's a bad habit web developers get when their first experience is of HTML, which since it's not a programming language can't go disastrously wrong.

  • CodeReview (unregistered) in reply to Herman
    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.

    Wow. Just wow.

  • ih8u (unregistered) in reply to Coincoin
    Coincoin:
    Maybe to prevent brute force attacks?

    Or more likely job security. I did allocate some almost useless big buffers in an embeded application once, and when time came to optimize memory usage, I just removed them and then I was a hero. That is, until I admited a few seconds later how stupid (or drunk) I was when I first wrote the code.

    yes. some of us know when to shut up and accept the applause. others of us (myself included) seem to ramble on until no one in the room believes that we could have fixed the problem ... ever.

  • diaphanein (unregistered) in reply to Code Dependent
    Code Dependent:
    public void lay() { try { Bed.sleep(getGirlfriend()); } catch (InterruptedException ignored) {} }
    Fails to link: unresolved symbol "getGirlfriend"
  • roe (cs)
    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.
    Whatever the reason for the feature, it wasn't necessary. Removing the feature didn't break anything, so now it runs a lot faster.

    ... the LoginAction and SignupAction will get brute-forced a lot faster too!

  • Someone You Know (cs) in reply to amischiefr
    amischiefr:
    Pony Princess:
    1... 2... 3... 4... 5...

    Maybe it was to make room for "optimisation" later.

    QFT

    This guy wanted to be a hero later no so he placed things in there to intentionally make it slow, just so that he could go and save the day later. Brillant!!!

    FTFY.

  • akatherder (cs) in reply to CodeReview
    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.

  • diaphanein (unregistered) in reply to Osno
    Osno:
    Probably a concurrency issue. This must have been to avoid using a shared resource (the log file) from two simultaneous threads.
    That's what locks/semaphores are for. Sleeps won't fix the problem, just make it harder to debug the problem.
  • Andy (unregistered)

    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.

  • Steve H (unregistered) in reply to Skizz
    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.

  • Bob (unregistered)

    Maybe it's so you can't brute force a login? That's perfectly reasonable. (More reasonable might be to delay 0ms for the first three, then slowly ramp it up, but still).

  • kastein (cs) in reply to Anonymous
    Anonymous:
    Coincidentally, I've spent most of the day looking at completely undocumented sleep calls in our code. Interestingly enough, some of them are for a single millisecond only. Usually TDWTF is a pleasant escape from reality but today it just looks like the same crappy code I'm being forced to work on...
    I'd almost be willing to bet that this is some bad coder's attempt at releasing the remainder of the process' timeslice, as sleep() and friends only guarantee that the process will sleep for AT LEAST as long as you asked* - the man page says the system may reschedule another process instead and thus leave yours waiting for however long it wants to.

    Also... millisecond sleep? is that usleep(1000) or what? as far as I know, sleep() is measured in seconds and reduces to usleep(1000000*n) by the time it's compiled and linked.

    • unless a signal arrives. Then it'll return early, and tell you how much longer you should have slept.
  • Anon (unregistered)

    Probably an attempt to fix the max(id) + 1 problem from yesterday's post!

  • Anon (unregistered) in reply to kastein

    [quote user="kastein"][quote user="Anonymous"] Also... millisecond sleep? is that usleep(1000) or what? as far as I know, sleep() is measured in seconds and reduces to usleep(1000000*n) by the time it's compiled and linked. [/quote]

    Then you're looking at the wrong language. This looks like .NET and there Thread.Sleep is in milliseconds.

  • IByte (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.
    And you'd be wrong. As this is a web application, unless you take extra measures to prevent it, there's nothing to stop a brute-forcing bot from sending a new request, which will be handled by some other eagerly awaiting thread of the web server. So, instead of building a mildy annoying security feature, you've just made a Denial of Service attack even easier.

    CAPTCHA: Damnum, all the people who come up with these things.

  • Anonymous (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.
    Good one, but I think your joke is actually how a lot of inexperienced coders think!

    I don't normally make "the REAL WTF is..." type posts but I really have to say this: the real WTF (sorry) is all the people who think that fixed delays are a suitable solution to multi-threading concurrency issues! 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.

    Thanks.

  • brian (unregistered)

    Looks like a performance loop to me.

  • T-Biscuit (unregistered) in reply to Anonymous

    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.

  • mara (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.

    No he did not.

  • capio (unregistered) in reply to kastein
    kastein:
    Anonymous:
    Coincidentally, I've spent most of the day looking at completely undocumented sleep calls in our code. Interestingly enough, some of them are for a single millisecond only. Usually TDWTF is a pleasant escape from reality but today it just looks like the same crappy code I'm being forced to work on...
    I'd almost be willing to bet that this is some bad coder's attempt at releasing the remainder of the process' timeslice, as sleep() and friends only guarantee that the process will sleep for AT LEAST as long as you asked* - the man page says the system may reschedule another process instead and thus leave yours waiting for however long it wants to.

    Also... millisecond sleep? is that usleep(1000) or what? as far as I know, sleep() is measured in seconds and reduces to usleep(1000000*n) by the time it's compiled and linked.

    • unless a signal arrives. Then it'll return early, and tell you how much longer you should have slept.
    Thread.sleep Tis Java. So millis.
  • usitas (unregistered) in reply to Anon

    [quote user="Anon"][quote user="kastein"][quote user="Anonymous"] Also... millisecond sleep? is that usleep(1000) or what? as far as I know, sleep() is measured in seconds and reduces to usleep(1000000*n) by the time it's compiled and linked. [/quote]

    Then you're looking at the wrong language. This looks like .NET and there Thread.Sleep is in milliseconds.[/quote] Lower case "S" and "D" (in delay). Java

  • dtfinch (cs)

    I think the idea was to slow down spam bots and password crackers, and they were too lazy to have it only delay on repeated attempts.

Leave a comment on “Delaying the Evitable”

Log In or post as a guest

Replying to comment #:

« Return to Article