I am somewhat running out of similes. Should I say the hamster wheel is spinning like crazy? But that somehow obscures the fact that it’s the hamster–i.e. me–that makes it spin. Or is forced to. Can hamsters ever just die because the wheel is spinning too fast? Like, get a heart attack? But then again the hamster might just stop the wheel and get off. Can I?
Last week we spent two full days on the second assignment for the distributed systems practicum. You know, the roleplaying mystery with containers. The deeper we went into it, the more it became obvious that the task was really a bottomless hole. It all sounded so innocently pragmatic–you should be able to form a group, invite people to it, send them assignments for tasks to solve, and they should reply with the results.
Only in actually working on these things it became obvious that the simple descriptions hid an ant’s hill of functions necessary to implement them. To start with, everything has to work from two sides–invite people to a group, and be invited; reply to to an invitation, and deal with an accepted invitation. The same with assignments–assign, and accept an assignment; return the assignment, and handle one being returned. Add the fact that in order for all this to work, there needs to be a persistent service in addition to the user client in which a user is only reachable when actually logged in. So in fact every user function implemented needs one logical function in the service and one in the client, and both of these actually mean one method in the business logic and one in the ReST (HTTP communication) interface … so you see how the simplest things multiply out of all proportion. In fact, we made it worse by allowing shortcuts for communication between clients registered with the same service. This makes eminent sense–save an HTTP call–but necessitated a switch in every function, and confused the hell out of us because between the outgoing and the incoming function the users switched roles.
Inviting users to a group was further complicated by the requirement that the server reply should be delayed until the invitee had either accepted or declined the invitation. Implementing this necessitated using threads in the ReST interface to make the entire interaction from client to server to client asynchronous. Never mind that this is completely nonsensical, because the server reply–a HTTP status code like 200 (OK) or 404 (not found) is intended to reflect a technical status of the server and hence to come immediately on receiving the request, rather than await human interaction. But we made it work and I am still surprised at that.
And combine figuring this out and debugging it with the technical obstacles of running this on an finicky server with a rather unpredictable, ill-documented interface, and maybe you can see how this took us a day and a half. We attended the practicum in the hope of having it done while we were there, but no such luck. It was 40 minutes after the meeting closed when we could finally solve the first quest that required group cooperation. A triumphant moment after all our pains–except that we still had to implement the election algorithm for choosing a new group leader which by the by, again, is actually a technical procedure for finding a new coordinator node in a distributed system. That took us another half day.
In fact I think we overdid it, at least in trying to find a clean, programmatical solution for a general user interface for all the different quests. For every new twist and turn of the quests needed an expansion of our command-line interface. It had started out rather simple, but now often has a dozen different options at each juncture. I think the assignment had never been meant that way, or if it had, then the assistant who came up with this nightmare hadn’t been thinking hard enough what would be needed to make it possible.
After we could finally do elections, I tried completing the next quest where they were required, but couldn’t make it work. I asked the assistant for a hint, and it came out you needed to do a post with a token included, a format that, again, hadn’t yet occurred in the entire quest line. I almost despaired. It’s as if he would do everything to make it impossible to find a clean general solution to this chain of assignments. Rather, hacking and muddling with typing URLs and copying tokens by hand seems to be both simpler and more rewarding. In fact, what made our hard work particularly galling is the fact that the two others in our studying group got a solution accepted in which they could do almost none of the mechanisms required by the assignment properly–for instance, they could not properly return an assignment, but just sent the token in a message. But they solved the quest, with a fraction of our work, and were the only group to get their solution checked off in the second meeting.
I think we forgot that, as the saying at UAS goes, good programmers are lazy programmers.
Still, I made another change to the interface and completed the fourth quest. By now, it’s become a matter of pride to stick to our good, if expensive, solution.
But that was yesterday, and the day after tomorrow we have to present our solution to the third assignment for architecture of information systems. This is where we had to write microservices for a ferrying business in three teams of two. Now the task is to deploy them to the cloud and write integration tests. And at least I am totally lost there.
Fortunately my present programming partner is a lot more deploy-and-container-savvy. For me it’s a positive nightmare. There is a runner on Gitlab that deploys the services, and then it also has to run a project that checks if they are there, then run the integration tests, and somehow report the results back to Gitlab, and that’s a lot of voodoo with namespaces and yaml files and a load of other things that sound like complete gibberish to me. Hopefully not only to me.
But there’s a lot of leeway there for my previous programming partner, who wrote the service we have to communicate and integration-test with, to play the patronizing know-it-all in his usual overbearing way. We had a meeting last week and one yesterday, and in both I relived all the conflicts I had had with him in earlier terms. In the first, he simply refused to actually read the assignment which described the approach to integration testing in quite some detail, and blithely imposed a hack on us that I never quite understood, then happily proceeded to write a shell script that did something completely incomprehensible while brushing off all my concerns that I had not the slightest idea what we were doing and how I should get tests to work in the environment he forced on us.
In the second meeting yesterday we returned to the procedure prescribed by the actual assignment (though that’s equally incomprehensible to me), and started writing a test project. That necessitated an understanding on common test data and the assignment sheet even said so. In fact, all I needed to write my tests were two IDs–two numbers–that had to be in the data on the service written by my previous programming partner so I could request the objects they identified. Yet for an hour he steadfastly refused to give me these numbers. Instead he suggested I might just figure out how to reach his service and get the IDs from it programmatically. What gall! We were talking about two integers that he had personally written in his code and could look up and share in a second. Instead he had me do a guessing game. I finally told him off and got the numbers.
And then my present programming partner and I fought for three hours with getting the testing project that somebody from the third team had already started using Kotlin (a different language for the Java Virtual Machine) to work on my IDE. Three hours just to be able to start working on an assignment we will need to have done in 48 hours; and I can’t do anything tomorrow for I have lecture and practicum all day. And what’s worse, it totally defeated us. My IDE would never recognize the Gradle (build tool) setup. Accordingly neither would it download the libraries needed to resolve the imported functions. I deleted and re-cloned the project about two dozen times, I tried every dirty hack in the book, and still it wouldn’t let me do anything. My programming partner finally built a clean Java/Spring project, than added the Kotlin code, and that mysteriously made it work on his machine, but not mine. I was ready to throw the computer out of the window, then jump after it. Except as you know the windows on the 10th floor won’t open.
And in that mood a co-student informed me that the exam for the compulsory choice module on process mining had just been moved from the second exam week to the first. So that now I will have all exams in the first week on three consecutive days–the oral architecture exam on Tuesday, then process mining on Wednesday, and distributed systems on Thursday, both written and probably quite nasty. With no exam in the second week, studying time for the exams will be seriously curtailed, and three in a row will be extremely stressful to say the least. Not to mention that the one or two days immediately before an exam, when you can concentrate on the contents of that single course with a clear mind, are almost indispensable for success in the exam. With three exams on three days, there won’t be any of that. I will have to study for three exams in parallel, right up to the first one, and still that studying will be three days old on the day of the third exam.
It’s seriously depressing and feels entirely unfair. Doesn’t anyone stop to think? Of our needs, I mean? And you can bet the bank that there’s nothing behind this sudden and depressing change except a professor’s wish to leave for vacation a week earlier.
But what a fitting end for a term that has been the most crazy so far.