I don't even know what to do with this



  •   // Wait for <thing to happen><thing to="" happen="">
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // Sometimes it doesn't happen in time; need to wait some more
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // Nope, more
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // This oughta do it
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    </thing>



  • Are there at least things to check whatever it is waiting on that got snipped or is it really just 4 of them in a row?



  • It's four of them in a row, with no intervening code.

    It's in a web service that asynchronously calls some internal system (not part of the web service). This is the point where, instead of using a blocking latch, timeout, or other typical mechanism, they just added sleeps until it always seemed to get the result from the other system in time.

    Why not just use one sleep and increase the value? Why not use a blocking call if they need to wait? Why not use a blocking call with a timeout? Or as least a separate timer thread? Why this?



  • @snoofle said:

    It's four of them in a row, with no intervening code.

    It's in a web service that asynchronously calls some internal system (not part of the web service). This is the point where, instead of using a blocking latch, timeout, or other typical mechanism, they just added sleeps until it always seemed to get the result from the other system in time.

    Why not just use one sleep and increase the value? Why not use a blocking call if they need to wait? Why not use a blocking call with a timeout? Or as least a separate timer thread? Why this?

    Why not use a synchronous call.



  • @Medezark said:

    @snoofle said:

    It's four of them in a row, with no intervening code.

    It's in a web service that asynchronously calls some internal system (not part of the web service). This is the point where, instead of using a blocking latch, timeout, or other typical mechanism, they just added sleeps until it always seemed to get the result from the other system in time.

    Why not just use one sleep and increase the value? Why not use a blocking call if they need to wait? Why not use a blocking call with a timeout? Or as least a separate timer thread? Why this?

    Why not use a synchronous call.
    Isn't that was a blocking call is?



  • @Medezark said:

    Why not use a synchronous call.

    Generic snoofle WTF outline:

    1. Locate WTF consisting of slowdown loops, "unnecessary" thread sleeps, and horribly inefficient code
    2. Attempt to fix said WTFs in an attempt to appease some inner idealistic feelings
    3. Watch in horror as cars explode, buildings fall over, and kittens die
    4. Revert code to previous 
    5. ???
    6. Profit!



  • @snoofle said:

    Why not just use one sleep and increase the value? Why not use a blocking call if they need to wait? Why not use a blocking call with a timeout? Or as least a separate timer thread? Why this?

    You only see the tree, you miss the forest. This is a system-wide optimization approach: by slicing the wait the programmer facilitates multitasking on the host.

    It's called Good Neighbour Programming.



  •  What to do? Don't touch it. You above all should know that, given the history of your client.

     



  • @RichP said:

     What to do? Don't touch it. You above all should know that, given the history of your client.
    No, he needs to fix it and charge them for the fix.  Then they will ask him to unfix it, and he will then chrage them for the unfix.



  • To be fair, snoofle's client has probably saved more on hardware, by changing inneficient code into sleeps that don't consume CPU, than he paid snoofle.



  • @snoofle said:

    Why not just use one sleep and increase the value?

    Because then they would always have to wait the full duration of the timer before catching. This way, they can catch it earlier, should it come available earlier. And then wait.



  • @Mcoder said:

    To be fair, snoofle's client has probably saved more on hardware, by changing inneficient code into sleeps that don't consume CPU, than he paid snoofle.

    I don't think you know how inexpensive hardware is compared to labor. A gold-plated server with the latest quads, 256GB RAM and internal SSDs is less than $15k (much less if you buy large volumes). Throw in a slice of enterprise-grade storage, the SAN fabric, etc, and you still get a price tag of less than $10k per year amortized over 3 years. I don't know what is snoofle rate but experienced contractors working directly for the client (no middle man) typically get something in the $20k-$30k range (per month, no amortization) - so do the math.

    Hardware is *always* cheaper than contractors. Does not mean I advocate a "throwing hardware at it" approach because you can get in situations where the system is reaching physical limitations (which appears to be the case for snoofle's client), but saving money on servers is definitely not a strong point in a business case for hiring senior contractors.



  • @snoofle said:

      // Wait for <thing to happen>
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // Sometimes it doesn't happen in time; need to wait some more
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // Nope, more
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    // This oughta do it
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}

    // Wait for <thing to happen>
    for(int i=0;i<4;++i) {
    try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    }

    Better?



  • @cdosrun said:

    @snoofle said:
    Why not just use one sleep and increase the value?

    Because then they would always have to wait the full duration of the timer before catching. This way, they can catch it earlier, should it come available earlier. And then wait.

    Are you sure about that? The impression I got from the code was that Thread.sleep() is supposed to be interrupted by the InterruptedException, so it shouldn't make any difference whether it's one call of 4 seconds, or 4 calls of 1 seconds each. (Except of course for the fact that the way it's written, if the interrupt comes "early", then the code wastes some extra time waiting.)

    Many methods that throw InterruptedException, such as sleep, are designed to cancel their current operation and return [b]immediately[/b] when an interrupt is received.


  • InterruptedException is a checked exception, just like damn near everything in Java. You have to catch it, even when you know for sure that it isn't (or shouldn't) be getting thrown.

    It's stupid and makes it hard to reason about whats actually supposed to happen.



  • @Salamander said:

    InterruptedException is a checked exception, just like damn near everything in Java. You have to catch it, even when you know for sure that it isn't (or shouldn't) be getting thrown.

    It's stupid and makes it hard to reason about whats actually supposed to happen.

    Oh I see, thanks. Still doesn't explain why 4 sleeps is better than 1 in this case.



  • @CodeSimian said:

    Still doesn't explain why 4 sleeps is better than 1 in this case.

    Right.

    Take your pick:

    • There's some other thread or process that occasionally interrupts the waiting thread, before it should stop waiting.  This way, that only eats part of the delay.  The alternative would be using a four second sleep, and capturing the remaining time each time it completes, checking to see if the result actually came in, and if it didn't, re-sleeping for the captured remaining time.  But I don't know if Java can do that; I'm a perl programmer.  It can do this.
    • There's some kind of crazy latency issue; when the synchronous call finishes, the program still needs to wait another 15 milliseconds.  You really only need two sleeps - the first one at 3345 milliseconds, the second at 15 milliseconds.  But they haven't analyzed exactly what's going on; they just found that making the first sleep 15 seconds still always resulted in a fail, but having two one second sleeps usually worked.  So then they added a third, and it was closer, and after adding the fourth, it works over 98% of the time, which should be good enough for anyone1.

    I could try pulling more stuff where those thoughts came from, but they'd be just as smelly, and I'm tired.



  • @tgape said:

    @CodeSimian said:
    Still doesn't explain why 4 sleeps is better than 1 in this case.

    Right.

    Take your pick:

    • There's some other thread or process that occasionally interrupts the waiting thread, before it should stop waiting.  This way, that only eats part of the delay.  The alternative would be using a four second sleep, and capturing the remaining time each time it completes, checking to see if the result actually came in, and if it didn't, re-sleeping for the captured remaining time.  But I don't know if Java can do that; I'm a perl programmer.  It can do this.
    • There's some kind of crazy latency issue; when the synchronous call finishes, the program still needs to wait another 15 milliseconds.  You really only need two sleeps - the first one at 3345 milliseconds, the second at 15 milliseconds.  But they haven't analyzed exactly what's going on; they just found that making the first sleep 15 seconds still always resulted in a fail, but having two one second sleeps usually worked.  So then they added a third, and it was closer, and after adding the fourth, it works over 98% of the time, which should be good enough for anyone1.

    I could try pulling more stuff where those thoughts came from, but they'd be just as smelly, and I'm tired.

    Maybe they needed a way to only interrupt PART of the sleep. Because, uh…



  • So, if the thing happens during the first sleep, then it's handled and the code goes on to sleep 3 more seconds after that?


  • Discourse touched me in a no-no place

    @tgape said:

    @CodeSimian said:
    Still doesn't explain why 4 sleeps is better than 1 in this case.

    Right.

    Take your pick:

    • There's some other thread or process that occasionally interrupts the waiting thread, before it should stop waiting.  This way, that only eats part of the delay.  The alternative would be using a four second sleep, and capturing the remaining time each time it completes, checking to see if the result actually came in, and if it didn't, re-sleeping for the captured remaining time.  But I don't know if Java can do that; I'm a perl programmer.  It can do this.
    • There's some kind of crazy latency issue; when the synchronous call finishes, the program still needs to wait another 15 milliseconds.  You really only need two sleeps - the first one at 3345 milliseconds, the second at 15 milliseconds.  But they haven't analyzed exactly what's going on; they just found that making the first sleep 15 seconds still always resulted in a fail, but having two one second sleeps usually worked.  So then they added a third, and it was closer, and after adding the fourth, it works over 98% of the time, which should be good enough for anyone1.

    I could try pulling more stuff where those thoughts came from, but they'd be just as smelly, and I'm tired.

     So tired your code threw a com.thedailywtf.MissingFootnoteException.



  •  lol. some of the code i write sometimes looks like this.

    on heavily loaded systems, sleep(1000) does NOT sleep for 100ms. for example on my 48 core system with 300 active threads and 1150 active processes, sleep(1000) sleeps for 83340ms. 

     This is the opposite and chances are its for real time systems. this is how it works.

    something happens -- this is good. java now kicks in and starts the thread

    thread goes to sleep for 1000ms but in the background that something is now busy filling the buffer. 

    thread wakes up, data is there but only partial.

    now thread goes to sleep again for 1000ms.

    buffer becomes fuller.

    wakes up, whoops not quite there yet. 

    goes to sleep.

    buffer full.

    wakes up. goes to sleep. if by some chance buffer is left unfilled now its full. the extra sleep is there as a good practice.

    thread continues processing, buffer is now nicely full and can be used. 

    this is especially useful code for cases where the data comes in over serial i/o lines. you want the thread to wake up and go back to sleep because that kicks the buffer into action. a sleep(4000) wouldnt do that.

    so the code is good -- dont change it.



  • Ya'll are a bunch of morans.

    These are four calls directly in a row. There is no action in between them. It doesn't facilitate multitasking. It doesn't kick the buffer into action.

    Just read what snoofle said.  They're just waiting until the target system gets done with their action.




Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.