Archive for the ‘Rants’ Category
New Annoyance: Intermittent Internet Connections
I got to travel a little bit a few weeks ago — my mother and I went to Borsec (actually, to nearby Corbu) to meet a friend of hers (who happens to have six Dachshunds, but that’s a story for another place). One thing we were warned about was the cellphone network there is spotty (and there’s no power where they live, but we didn’t stay with them, so that was okay).
They weren’t kidding. My lovely 3G modem could only connect at GPRS speeds, and even then the connection tended to drop out every once in a while — which was how I found out many of my favorite lovely little apps have a terrible, terrible time handling intermittent Internet connections.
Now, I’ll be among the first to recognize that broadband adoption has been increasing steadily at a booming pace in the past decade or more, but that doesn’t mean literally everybody has one, or that it’s impossible to go anywhere where one is not available. For that matter, it also doesn’t mean a broadband connection — any broadband connection — is perfect: they do drop sometimes, even if only for short periods, and this needs to be taken into account by any software that purports to handle transfers over the Internet.
On top of that, there is no real excuse for not handling all this stuff well — it’s the year 2009, and Internet connections have been getting widespread for at least 14 years. And they haven’t tended to be fast, reliable ones, either. There is plenty of software that has evolved to take these factors into account. On the Linux side, I only need to point to wget as a download agent that understands this fact and will happily allow a download to be resumed, retried, or restarted, as needed, more or less automatically, and wget is available in pretty much even the most basic Ubuntu system, and very likely in most other “mainstream” Linux distributions. Certainly, it represents an external dependency, but one that can be safely relied on by pretty much any Linux software author.
Except, for instance, the authors of gPodder don’t seem to have ever heard of it. Or, if they have, none of them have bothered making use of this mature, well-written solution to download handling, and instead implemented something written in-house, probably just as a quick ‘n’ dirty hack to quickly get some kind of downloading support in place, so they can at least get to testing the software and get a feel for it. Which would be fine… if it weren’t still in there.
Now, I want to be very clear that I am not specifically harping on gPodder for this. It’s far from the only piece of software that handles downloads poorly. In fact, I would like to turn a particular eye towards Firefox on this front, since I’ve never felt comfortable with its internal download support. Or that of any other browser, for that matter.
But what I would like to say is that the problem of downloads over an unreliable TCP/IP network is a solved one, and solutions exist for it — well-tested solutions that are well-known and work at least 99.99% of the time.
So why is it possible nowadays to write a mostly new piece of software that downloads relatively large files (an episode of the Rathole Radio podcast is around 55 MB, on average), which are bound to take a long time on a slow connection (like a 3G modem forced to work at GPRS speeds), and not build in the capability of resuming an interrupted download?
Even putting aside the fact that a GPRS connection is not the most stable thing in the world (particularly in relatively mountainous areas), there are times I cannot justify leaving a system turned on for the several hours it would take to finish a download unless I were reasonably certain the download was going to finish or that I wouldn’t have to start over from byte zero if it was interrupted. Without that (in my opinion) reasonable expectation, I might as well not bother until or unless I could get to a stable connection to do it. And too bad if I really couldn’t get to that stable connection, isn’t it?
That’s odd…
Now, here’s an odd one for you, courtesy of my friend, Cristian Chilipirea (Dark Hunterj):
#include <stdio.h>
int* holy_crap()
{
/*static*/ int s;
printf("%i\n", s);
return &s;
}
main()
{
int* x = holy_crap();
*x = 2;
holy_crap();
}
So, what are we looking at? Well, if you uncomment the “static”, you get the intended effect — holy_crap(), when called for the first time, (prints “0\n” and) returns the address of its static variable; the value in that address is changed to contain a 2, and then holy_crap() prints out “2\n”. This is as intended, and it is a very silly thing to do, but it works and is legal.
And then, you comment out the static as I’ve done, and… it still works? That’s odd… In theory, at least, the allocation of a non-static local variable can take place absolutely anywhere in memory, so the address read and returned by the first call to holy_crap() could be different from the address checked and returned by the second call. Yet, on my compiler (gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)) and on Dark’s, it actually does print “2\n” on the second call to holy_crap().
Granted, gcc does complain: “warning: function returns address of local variable”, but it still works, for whatever reason.
And it gets better! Check this out:
#include <stdio.h>
int * holy_crap()
{
int s;
printf("%i\n",s);
return &s;
}
int huh_what()
{
int test;
test = 3;
}
main()
{
int* x = holy_crap();
*x = 2;
huh_what();
holy_crap();
}
This actually prints “3\n” on the second call to holy_crap()! We could probably reduce this further by removing the initial call to holy_crap() and the assignment of 2 to that pointer, but it doesn’t matter, because this is still some weird shit going on here.
Oh, and, I probably don’t need to tell you this but don’t ever rely on this happening for you! It’s very likely a combination of compiler, OS, and unoptimized compilation. I haven’t tried this in any conditions other than “gcc file.c -o file”, and I definitely do not recommend writing anything like this in any application beyond the most trivial/educational.
Still, any ideas to explain why this happens?
Going insane from work
I haven’t talked much about work on this blog and I’m not going to give too many details now, either. For a bit of background, I’m working on somebody’s many-years-old legacy code, much of it written in a mix of PHP and Perl. The code has been worked on by dozens of programmers over the years, and nobody’s really kept any documentation aside from that absolutely required (mostly inter-departmental stuff).
As a result, the code is… well, let’s just call it The Code From Hell™.
So TCFH is a mixture of really old and not-so-old, and over the years the (very many) changes have resulted in a huge amount of cruft. None of which can be removed because, there being no documentation (and very little structure to the code, thanks to a number of people’s preferred coding style of “let’s just make this fucking thing work so I can go home”), nobody knows what’s still in use and what isn’t. On top of all this, “code reuse” was, at some point, taken to mean “let’s make a copy of this thing and make a couple of small changes, making it work for this new situation”.
In conclusion, we’ve got:
- lots of versions of basically the same file with a few small changes
- many old pieces of code nobody’s ever looked at in years
- unused code
- code that’s in use, but is so convoluted (the term Spaghetti Code comes to mind) that everybody hopes it won’t break
- and very few, very confusing and mostly outdated pieces of documentation describing how some parts work (there is no complete documentation of the whole thing. If there ever was, it’s way out of date now)
And, to top it all off, I’m one of only two people remaining who still understand most of how it all fits together, and I’m the junior with only one and a half years’ experience.
On the bright side, most of the code is readable, once you understand a few basic structuring ideas that were, for the most part, adhered to.
It’s the rest of it (about 20%) that gives people nightmares of being stuck in a maze of twisty passages, all alike. I worked on that 20% today.
Let me pause now to describe a bit of the process flow: first, a user clicks a “join” link on one of our websites. The link takes them to the credit card processor, where they enter their CC details and their card is either accepted (and billed) or declined. After a successful billing, the user is sent to a handler on our servers that takes care of setting things up on our end; namely, creating the user in the database, and remembering some associated information so they can be rebilled for as long as they keep up their subscription.
Except that, on three websites, the user is not being created in the database.
The success/fail handler is one of those old pieces of code that’s been around since the dawn of time. There are multiple copies of it, as well as a number of included files which are about as old as the rest of the whole thing. I went through one of the copies today. Or I tried to.
You see, the code is part of that Code From Hell I was talking about. And even the includes are convoluted. So I thought I’d make things easier on myself by writing a script that recursively follows includes and prints them in a tree-like format (this script will be made available to others in the future; watch this space, or ask me for it, I might give it to you if you’re not a jerk).
The result? 177 included files, of which some 20 are false positives (not really includes; or commented out), about 30 are includes of the exact same file, which is used in a lot of places to provide unified logging, some 20 more includes of another file which provides some translation between an id number and the website the action originated on (lots of sites all go through the same handler; don’t ask for details unless you want to make me cry (meanie)), and some 20 or more includes of files defined by variables like $FNAME.
What none of these files seems to do is add a fucking user to the fucking database!
So I’ve basically wasted about five hours hunting for something in age-old code, still haven’t found it, my brain feels like it’s been through a grinder (multiple times), my wrist started hurting a while ago (carpal tunnel scare, though it’s since stopped), and the only success I’ve had so far today is this quick script that follows includes.
I’ve joked about taking this whole mess and rewriting it in PHP, but to be perfectly honest, I think one of these days I’m gonna go rogue and do it. Over a few weekends. And then present the result to the folks on the other end and say “Hey, guys, you know, it can be done better”. And it’ll be structured this time, dammit!
Vodafone Romania customer care — more like customer scare!
Right, so I’ve been churning a rant around in my head for the past several days, it’s time to put it to writing. This rant is about Vodafone Romania‘s customer care web application, the most disgusting pile of c… code that ever saw the light of the Internets.
Let me begin with a bit of background. I was a Connex customer before it was bought (or whatever) by Vodafone and rebranded. I’ve been a customer for at least five years, but more likely closer to 7 or 8 (neither me nor my mum remember). I was underage at the time of creating the contract, so it was made in my mother’s name, where it still is for now, so anything that requires the actual contract holder present is relatively difficult for me.
This all sets up the background for this story. A few months ago, I found myself in need of a backup Internet connection, as my primary one (which is a source of hate all on its own, but that’s another blog post) was getting flaky.
So I went to the Vodafone site, and after several attempts, managed to register to use the old customer care system, and with it, was able to disable the unused MMS support and enable a reasonably cheap Mobile Internet solution, which served me well as a backup.
However, in recent days, I’ve found this particular payment plan to be insufficient to my needs. Now, Vodafone offers a so-called “unlimited” Mobile Internet plan, but that requires the contract holder’s presence. It’s next to impossible to synchronize my schedule with my mother’s for anything like that on short notice, so I went for the next best thing — an upgrade from 25 MB included (at 4 EUR/mo) to more megabytes included — I don’t use _that_ much, on average, anyway.
And there, the troubles started.
First of all, I went to the Vodafone site to find the old customer care application was disabled, and instead there was a new one, aptly called “MyVodafone v. 2.0.1″. It’s shiny. It’s flashy (not in an Adobe way). And, best of all, it’s v. 2.0! That’s got to be better, right?
Yeah, I got fooled by that, too.
To begin with, the old interface was slow at times. It was slightly confusing (took me four or five tries to register in the first place), and the help links (linking back to the main site) were broken because of a recent site redesign. None of that, however, prevented it from doing its job correctly, as evidenced by the fact that I was able to get mobile internet to begin with.
The new interface is not so confusing. I had to re-register, presumably because the old interface used your cellphone number as a login, whereas this one calls for a login name. The registering part went great. As I said, not so confusing. That was good.
What wasn’t so good: the new application seems to be written in some bastard child of Java and Javascript, using Javascript for the internal hyperlinks instead of linking to the pages like every other normal person on the Internet. Oh, well, I think, I don’t normally disable Javascript anyway, so it doesn’t affect me.
Well, it wouldn’t affect me, if it weren’t for the small problem that the Vodafone pages tend to time out, or error out. And when that happens, you’re left at the old page, on which the link is now disabled because, hey, you already clicked it, right? Thus requiring a refresh of the page, and a lot of waiting.
Oh, yes, the waiting. Considering the fact that the front-end pages work like a fucking dream, you’d expect the customer care app to run at least decently, even though it has to keep track of logins and cookies and all that junk, right? Well, if you were expecting that (I was), be prepared to be severely disappointed.
Because of the reliance of Javascript junk and probably some configuration mismanagement, it can take up to several minutes for a page to load. And you have to wait for the whole page to load, otherwise the Javascript links aren’t going to work, or they’ll error out, or whatever other weird broken shit you could imagine can happen, will happen.
But wait, it gets better. Half of the time, the pages won’t load at all, and you’re left staring at a blank page and wondering what to do next. Go back to the previous page and try clicking the link again? Or try to click “Go” in the address bar and hope it loads this time? Good luck to you, whatever you do, ’cause whatever you do, the same thing is going to happen on the next page you load. And then the next one after that. And so on, in an infinite loop, for as long as you try to make use of this application.
This is an internal application link: “javascript:doEcareLinkSubmit(‘navigateMenu.do’,'_navigation_primaryMenu=myServices’);”. Note how it’s Javascript. Note how it calls on some stupid function that sets up (what else) a POST request to a URL, because it has to post a whole lot of data the server can’t keep track of using the normal method of having a simple cookie with a session ID, and a file or database entry on the server side which associates the required data with the ID in question. The important bit, however, is that I can’t use it without Javascript.
But that’s okay, because I can’t really use it with Javascript, either. You see, after you brave the Javascriptiness, and the immensely slow page loads, and the complete and utter junk that is the User Interface itself (undoubtedly designed by a programmer… no, wait, I mean a coder. I’m a programmer and I don’t do this shit), and finally end up at the right page to change the payment plan, and go through the four step change and “confirmation” pages, each of which needs a complete new page from the server (they couldn’t even use a bit of Ajax to speed things along), and assuming you don’t have to deal with the popup from Firefox saying “Could not establish an encrypted connection because [sic] certificate presented by www.vodafone.ro has an invalid signature” (as I said, misconfiguration)…
…even if you get through all that, the end result is being told “The changes could not be applied”, with no idea what to do next to fix it, however with a nice additional text inviting you to call customer support on the hotline, and waste some poor joe’s time with something the Web interface could’ve handled easily, but it doesn’t because it’s a huge pile of shit.
Let me repeat: the Web interface is such a completely dysfunctional pile of shit that it’s actually better to call the customer support hotline, wait on hold for however long, talk to someone for however long, than to try to use this thing.
My time costs money. The CS representative’s time also costs money. If the Web interface were done right, it would cost a lot less to do this change through it than any other way. But the Web interface isn’t done right. It’s shit. It’s a Java/Javascript nightmare with HTML that probably crawled out of a sewage tank one night and decided to sit on the Web server. It’s a slow, bug-ridden horror story where, at each click, you wonder if you’re going to get a page load (in a few minutes) or if you’re going to get an error, or a blank page, and have to figure out what to do next.
In short, this is customer scare. In the long run, I’m tempted to just abandon the phone number and change providers, because this shit just isn’t worth it. In the short run, I’m going to call customer support, and I’m not going to be bitchy, because it’s not the CS person’s fault, and I’m probably going to get what I want, after another (long or short, who knows) run-around.
This is what not to do, people. Don’t alienate your customers. This isn’t a 2.0 version, this is an 0.2. The application should never have been deployed to customers. It’s not even worthy of being called a Beta. Or an Alpha. It’s just junk, something somebody puked up one day (or multiple days, who knows?). It’s not something usable. It’s not functional. It doesn’t work. It raises my blood pressure and pisses me off, because as a Web programmer, I could write this fucking application in two days, completely alone, and it would be just as flashy and shiny, and — more importantly — it would work!
And if I, a one-man show, could do it right in a week or less, what excuse does Vodafone — a company that surely dedicates a lot of resources to their Web presence, a company that tries to pride itself on customer support — what excuse do they have in feeding their customers this shit? And why should I continue doing business with them, in these circumstances?
