A day in campus IT

One day back when I was working in my campus IT job, I jotted down some notes on a day at work. I was in the middle of working on a web application that we were building to keep track of graduate student degree progress, so this is the story of a day in the life of that project. It was full of interruptions.

9:12 am. I’ve just finished getting my coffee, refilling my water bottle, and saying a gruff Hello to the guys across the hall who do desktop support. They seemed busy. All four of them: a recent arrival from California, right out of college with a bony face; an undergrad; a Ukrainian who has been here for five years; and a guy from downstate Indiana, in his late 30s, who previously worked at a cable company and now manages our group. It’s a fairly masculine environment, which I’ve talked about with the manager before, but our group is slowly becoming more diverse, which I’ve felt glad about.

Back at my desk, which is marked by three enormous computer monitors and a futuristic ergonomic keyboard, I get an email from someone who’s leaving the university: “Yes, today’s my last day.” I ask if she can do one last piece of work before she leaves, sending out an email announcing a new project. I know she’s had that item on her agenda for the past few weeks, but probably got overwhelmed and couldn’t get to it earlier.

Now I’m revising the code that calculates a currentTerm property (that is, it figures out the current academic term) for our student tracking application. I used to generate the current term using a lazy approximation, by just dividing the year evenly in 4 quarters, 3 months each:

getTerm: function(date) {
    var currentQtr = Math.ceil( (date.getMonth()+1) / 3),
    currentYear = date.getFullYear();
    return `${currentYear}-${currentQtr}`;
}

But it turned out that the start and end dates of each term varied each year, so if you want to know the current term, you really have to compare today’s date with that list of term start and end dates. Here’s how that looks in ruby:

Time.class_eval do
    def term_qtr
        target_date = self.to_date
        index = Time.term_boundaries.index do |term|
            term['to'] >= target_date
        end
        Time.term_boundaries[index]['term']
    end
end

I can refactor this to be a little more succinct. (Refactoring is jargon for revising code to be cleaner, neater, cleverer while still producing the same results.)

def term_qtr
    target_date = self.to_date
    term = Time.term_boundaries.find {|term| term['to'] >= target_date }
    term['id']
end

A few minutes later, I’ve finished wiring up my new feature to appear in the user interface (which is made in Ember.js). I’ll document how I did that. Wiring, we call it. Or gluing. Programming is full of weird metaphors

Annoyingly, in the process of doing that, I notice a new bug. If you create a new record, don’t save it, navigate somewhere else, and then navigate back to the new record, you see an error page. Grr.

That needs fixing, which I’d like to do immediately. I hate putting off bugfixes; they’re usually vaguely satisfying. But I’m also trying to answer an email mentioning a different bug, which is that a particular “year in program” field is getting miscalculated in a certain case (the case of a student who’s on leave, to be precise).

To be able to answer the email and announce that the bug is fixed, I have to do a whole bunch of separate steps:

  1. Fix the bug
  2. Re-test the application
  3. Deploy to the test server
  4. Re-run the reset_counters function on 7294 records (takes about 30 seconds)
  5. Test the results
  6. If OK, deploy to the production server (“deploy to prod” it’s called for short)
  7. Run the reset_counters function on the production data
  8. Check to make sure that everything looks OK
  9. Then, finally, notify the user that their request is complete.

As I write back to the user, I try to explain the non-technical version of why the bug happened. I never know if our users really care, but I imagine that they like to know that the computers aren’t just black boxes, that they are comprehensible, that things are basically straightforward under the hood. They usually say thanks, but I almost never see them in person, so who knows. (There’s something structurally odd about gender and information technology, which is only exacerbated by being a faceless voice that appears only in email.)

I try to keep track of everything that needs doing at my job, but it’s overwhelming. I have some post-its; I have a short todo list on my whiteboard; I have a plugin for my text editor (PlainTasks); and we have a group-wide task tracker (asana) that I try to use for anything that I’m not about to get to. I get new tasks via email, and I don’t always write them down if I think I can do them immediately.

Now it’s 11:41. The hall is quiet. My desktop is a morass of papers and gadgets, and my silverware needs washing out before lunch. I did water my plants, and the sun has come out on the little tree outside my window. Its leaves are getting that parched autumnal pre-death look.

The departing person gets back to me, and I start writing comments on her draft announcement message. Then I poke around a little more in my application, and find some weird blank records. I delete them, and add some documentation explaining that they were all blank, and deserved to be deleted. I’m not forced to write this sort of documentation, I find it helpful for my sanity to keep track of ad hoc changes to production data.

An utterly unrelated request comes in. Our course scheduling system needs a new start time. Apparently no one has ever scheduled a Tuesday/Thursday 8:30am start time before.

A different, utterly unrelated request generates several emails back and forth, about a student whose name is spelled inconsistently in different systems. I try to reach someone in the central identity management IT office who might know more, but he doesn’t answer my instant message. It’s a rare morning when I’m not distracted by instant messaging. IM is like 75% of my human contact with my coworkers. It’s not that humanizing, in the end, but it does retain traces of humor and ricochet at times.

Electronic clutter drives me insane. A clean screen feels comforting.

I find a post-it that I wrote but now don’t understand. “Deploy! prefix”. What could that mean? I’ll throw it away, on the theory that it is probably obsolete.

Now I take a look at the error that I found earlier, the one that crops up when adding new records in my application. It looks like it is trying to load a record with no ID from the server; the server complains that you can’t load something with no ID; and this generates an error screen in the client. It looks like it’s trying to undo changes to a record that was never saved, so I take a minute to fix the bug where the application is trying to reload an unsaved record. That part of the bug is easy to fix, but the error remains.

It’s 12:25, and I should really eat lunch, but I really want to fix this bug, before I have to do dull data imports yet again. I lower my adjustable-height desk and slump down in the chair.

12:40: Too hungry to not eat, started eating at my desk while poking around for the bugfix.

1:07 Still haven’t fixed my bug, but found Ember Data issue 3678 on GitHub, which seems to be pretty much the same problem. I write a note on the issue ticket, hoping that someone from the project team can help me out.

1:17 I finally fixed my bug. It turned out to work poorly to reload() a hasMany association that contained a new record. (I don’t have time right now to explain what this means.) I added a check for that. Committed my code. Too bad my comments on the GitHub issue now (from above) may or may not be useful. It’s 1:26. Time to go outside.

2:25 Back at my desk, I’m staring at a data import from the old student database to the new one. I almost know it all by heart, but I do have a checklist to run through.

Circles spin. Click the same button for UTF-8 encoding over and over. Finish. Don’t save my custom export settings. I’m using a Windows Access database running on my Mac, inside VirtualBox. Boxes inside boxes. Virtualized everything, but you forget it’s virtual after a while. Virtual control alt delete. Virtual error and hangups. Spinning icons that don’t stop. In the end, I get bored waiting and press “Power off.” Virtual “Power Off,” that is. Restart. Open all the virtual stuff up again. This time it works: “Fin Aid Table” exported!

All 17 tables exported. I have to post-process one of them: you open it up in Excel, save as UTF-16 text, close, open it up in BBEdit (a plain text editor), change the file encoding type to UTF-8, save again. Switch virtual desktops back to the one that has my application code loaded up. All the while, I’m listening to some piano music that I recorded earlier this year. The electric piano has a beautiful round tone, punctuated irregularly by the creaking of furniture in the room when I was recording.

Stupid problems with the data import that I’m half inured to. Can’t find fellowship contract with import id 0. Can’t look up final status for “Transferred” (it should be “Transfer”). Beginning import of access_degree_applications at 2015-09-30 15:40:46… Text flies by on the console, dozens of lines per second. 0 failures, on to the next one. Stultifying. But vaguely electrifying. My back starts to hurt, and so do my wrists. Now I’m listening to some 80s pop music that I think no one but me would ever like. No one is trying to reach me, except a few more random emails that scroll across my screen. It’s not really a busy day, exactly, but it feels somehow stressed. As always. Too much to do. Too much to do isn’t a crisis, it’s our state of being. I’ve been staying a little late lately and skipping lunch. It’s always a dumb choice, since no one even asks me to. I just do it.

When I look over the records of import errors, I find that some of them have been fixed by my project collaborators. That’s nice, but now new import errors naturally crop up. It’s like weeding. Never done. Except that you don’t get a garden at the end.

4:26pm. Feeling overwhelmed by nonsense. Tiny errors. New errors that replaced old ones. Wishing I had cleaned my desk. My supervisor IMs me to ask about a human resources question.

5:00 The workday ends.