- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Alvin should follow some kind of communication course. His Stare:tm: just won't cut it.
Admin
Depressing, because it reminds me of what happened here a few months ago.
We had to add a layer of security on our app which was based on allowing individual tools in the app to appear or not depending on whether the user had the specific permission. This was held as a bunch of text keys in the user profile object. For my part of the app I hid the fiddly testing of the key defining the tool against the user pemissions in a method with a simple one-parameter API, so the security check could be implemented as a simple flag test.
But this went against the way the rest of the team had done it, which was to implement the complicated and fiddly authorisation test as a pile of if statements hardcoded in place at each point where a tool was invoked.
We can't have this, declared the project manager, that's two different ways of implementing the security layer. We must make it consistent. Fine, says I, we'll get them to implement the method I wrote. No you won't, said the project manager, they won't change their code. You'll have to change yours.
I came close to quitting that day. Then I decided, no I don't care. Someone else is going to inherit this big pile of ordure and they can maintain it.
Admin
Yes, and they will blame you for that weirdness. That's why you care.
Admin
Correct, mostly. You made the change, you own it. Make sure to document why it was done this way. Of course, if you leave, you're thinking it's not my problem... until it gets posted here on the CodeSOD.
Admin
I know such persons.. My most beloved answer: "Don't change, it works!"
Admin
Buffering.
#after writing a bunch of stuff to a file $MYHANDLE->flush; close(MYHANDLE);
Admin
Some people are just stubborn
Admin
Sure, it worked on YOUR computer. But a computer running some brain-dead antivirus software might have patched the system close() API to NOT close the file right away, it might want to scan the file for bad actors before releasing the file to the wild.
Years ago a friend of mine wondered why it was taking 30 minutes to download like five mail messages. It turned out he had 2 or 3 different anti-virus programs on his computer and they fought each other for several minutes over each mail message file. Maybe something similar going on in this WTF-like thing. Not that a sleep(6) is a good solution either.
Admin
He's in a shop full of retards. In that situation, you're blamed no matter what you do or don't do. Best option is to start looking because that blame train is coming down the track whether you like it or not.
Admin
Were the sleep statements analogous to a "speed-up loop" or an artificial delay?
Admin
TRWTF is using CVS in... when was the original article published? 2012? Wow.
Admin
Using "Sleep" is this case is a symptom of an other things going crazy. In such cases, the scanner has to be blamed. The scanner has to be fixed or banned..
Admin
Speaking as someone who once worked on such a thing, I can say that such behaviour would indeed be brain-dead. The way I did it, the application issued the relevant file operation, and the scan was done in-line:
Application requests open-for-read or execute: AV interceptor opens file, checks content, closes file, lets the application's call continue, OR fails it.
Application requests close when the file was open-for-write: AV interceptor lets the application's call continue, then once the file is closed, opens it, checks content, and closes it.
And yes, if the file is opened for read-and-write, it gets checked once on open and once on close.
Addendum 2018-11-21 09:24: EDIT: key point: the application doesn't regain control until after the interceptor has finished.
Admin
Funny thing is, the way you initially wrote it implied the exact "brain-dead" behavior that would necessitate sleep() calls after closing the file...
Admin
Well, the thing is he wasn't totally wrong, just ignorant. The close function only closes the filehandle, it doesn't sync the file to disk. If Alvin really wanted to be as sure as he could be that the file was saved, he would have said:
die "cannot sync file: $!" unless MYHANDLE->sync; die "cannot close file: $!" unless close MYHANDLE;
Admin
Based on experience, if the system has asynchronous operations running in multiple threads then the sleep(5) might be implemented as a poor way of making sure that system part B doesn't trip over system part A. There are many, many better ways to do it but its feasible that the sleep(5) was actually preventing some cross-talk issues.
Admin
Everyone understands that mandated stupidity supersedes correctness and common sense at all times.
When faced with that situation, I put the following comment before MY code: "This shorter, more efficient code works. However, I was INSTRUCTED by Boss-name to change it to the code that follows because of littany-of-reasons". Then I leave my code commented, put the mandated stupidity immediately thereafter and finish with the comment "End of forced stupidity".
At least that way, the person who inherits the mess doesn't think you're an idiot.
Admin
oh, "The Stare" made me think of this cartoon scene: https://www.youtube.com/watch?v=Q_h8lokNM6U (FYI, John Delancey does the voice of Discord)
Admin
That ambiguity is why I made the addendum.
Admin
There's certainly quite a history of layers of OSes and device drivers and disk controllers not actually writing the contents to truly permanent storage despite the high level application having issued a "no kidding: flush this to truly permanent storage" API call. Instead they immediately return a code saying they did just that then later lazy-write the results to the next layer down who immediately returns a code saying ... It's lies all the way down. The Old New Thing has had several posts over the years on exactly this issue.
Our resident guru/ninja/idiot may be thinking that by idling for awhile, he's letting all the optimistic liars catch up and by the end of the sleep his precious data really will be (99.9% probability) in truly permanent storage. Safe in that (assumed) knowledge he can then proceed to the next part of his workload. It's a dumb "solution" to a real if misunderstood-by-Alex problem.
Or more likely they've got some large scale race condition in their app they're papering over without understanding the actual logical issue or the underlying code cause, much less the correct solution.
Admin
My current job has stuff in CVS, SVN and Git.
Admin
"Perl is a language for getting your job done," six seconds later than the "next-best"" language.
Admin
"doSomething(foo) unless condition;"
I find this construction very useful as it follow the logical thinking when the emphasis must be on the action, not on the condition; it makes the script very elegant and easy to understand because it follows a natural flow.
Everything could be written with "if" and "goto". But we have "while" and "for" loops in almost every languages. And we have "case" statements, etc. It is only normal that there is not only one way to express things.
There is the "while" loop and the "repeat until" loop. The syntax above is just the same for a condition.
Admin
As long as it's that simple, and not a massive code block and/or multiple conditions. Using Boolean logic in an
unless
is fraught with danger. The general rule for postfix conditional is simple simple.A single function call (maximum one parameter) or
return
with a single condition is fine.unless
can be clearer thanif
in many casesAdmin
Let me guess, the sleep() call parameter is actually the number of times he had to re-add it after some well-meaning but naive intern tried to correct it?
Admin
Sigh. When the next rookie comes and tries to break the application it will just increment to sleep(7); "Um… why is that sleep there? " ... sleep(8); "Um… why is that sleep there? " ... sleep(9); etc
Admin
Yes, the "enforced stupidity" comment technique would work ... but there are many, many places where this needs to be implemented, and (for various reasons) the commentability of the IDE I am using (it's, er, none too standard) makes this exercise itself a messy and tedious business.
Admin
I mean, it's an indicator of an obvious race condition. Sleep calls are not a way of fixing it, it's a way of bypassing it. If it works and you're fine with the performance, sure, leave it be. But you have to accept the fact that the problem with your code is not the 15 second performance loss. Otherwise you're being stupid twice.
Admin
Either this story is dumb or Alvin is. Who the hell can't take a diff which looks like a bunch of:
-sleep(6);
and say "if we take this out everything gets faster but $idiot insists it has to go work that way. Oh and here's the documentation which says the exact opposite."