Category Archives: Microservices

Painful Lessons in IoC

So, if you have a background in conventional programming (and especially if you’re no spring chicken, like myself), then you usually have certain expectations of how programming flow works and how functions are called. Unfortunately, though, if you happen to wander down the path into the land of IoC, nobody will warn you that you’re about to enter a bizzaro world all its own, especially if you’re a fresh grad out of school. You might hear some casual warnings like “Hey, watch yourself out there”, but they are woefully understating the case. But you will eventually learn the lesson. Just with a few broken bones. Like what, you ask? Well, as I explained to a suffering junior colleague, these things happen.

So, as an example of IoC, let’s take the Spring framework. Like other IoC frameworks, there are various ways to provide dependency injection: setters, constructors, and (in the case of Spring) annotations like @Autowired. Even though I’m not a fan of this modern magic, it’s fine, I get it: we’re trying to make things easier, as much I think it often does the opposite. And it works, so that’s what counts. However, as we will see, all of this magic swirls in a dense flog, obfuscating all apparent common sense.

So, Spring offers a slew of annotations, and if you use a caching layer like Redis, there is a handy one called @Cacheable. So, let’s say that you take advantage of it, and in the implementation of an @Autowired interface called DojoDataAccess, you create two methods that use the @Cacheable annotation:

@Cacheable("dojoData")
public List<DojoData> getDojoDataList(List<string> ids){
    println("Cache is not being used"); 
    for (String tmpId : ids) {
        DojoData tmpData = this.getDojoData(tmpId);
    }   
    ...
}

@Cacheable("dojoData")
public List<DojoData> getDojoData(string id){
    println("Cache is not being used");
    ...
}

So, if you call the “getDojoDataList()” function with a list of IDs (through an @Autowired instance), it’ll pull each “tmpId” from the cache, since the “getDojoData()” uses the cache…right?

Charlie Murphy is right: you would be wrong.

As it turns out, the @Cacheable is only invoked when it’s being addressed through the Autowired proxy interface. “But that should work!” Yes, IoC cadet, in the normal world, that should work…but you’re in the Upside Down, where things get only scarier when you turn a corner. So, how do ya fix that in a jiffy? Well, in the case of the obvious, you’re probably saying “Don’t do it”, being all judgy…but, yes, ugly things do work: an Autowired instance inside the very implementation that supports the original Autowired instance.

@Autowired
private DojoDataAccess dataAccess; 

@Cacheable("dojoData")
public List<DojoData> getDojoDataList(List<string> ids){
    println("Cache is being used"); 
    for (String tmpId : ids) {
        DojoData tmpData = dataAccess.getDojoData(tmpId);
    }   
    ...
}

@Cacheable("dojoData")
public List<DojoData> getDojoData(string id){
    println("Cache is being used");
    ...
}

So, is that the recommended way to do things? No…but if you’re lazy and/or something needs to be fixed in the next five minutes, then it might be the right tool for the job.

But, more importantly, this kind of solution throws a wrench into all conventional thinking when it comes to programming. And this is the kind of thing that your average Joe or Joanna doesn’t even think about it while they’re walking down the road to IoC…until they step on a land mine like this one. And that’s when the broken bones come into play.

Or missing limbs, if you really need that cache to work right in your production environment.

So, remember: be careful out there.

Redis Day Comes Again

Well, it’s that time of year again, where Redis Day storms the ports of New York, brandishing corporate video that implies Redis is the only hope for humanity’s salvation. I don’t know if that’s necessarily true, but like last year, they do know how to pick a location. In any case, the first of the 2-day event was an introductory session to Redis, not really necessary for those already familiar with the platform. I opted to go out of curiosity, and I’m glad that I did.

Even though most of the day was a rehash of what I already knew, the intro did point out to me some features that had been added with the most recent version, like the UNLINK command. (I’m not known for always reading release notes.) I also learned that the “master-slave” terminology has now fallen under, as Jacobins would probably describe it, the guillotine of progress:

Actually, I’m not sure if the new “master-replica” terminology is a better set of terms. If you still use the term “master” in this scenario, doesn’t it imply that the other party is a slave? And when I think of replica in this situation, the term replicant comes to mind, and that doesn’t really sound all that much better. But I digress…

The second day of the event was more interesting. To a small extent, some of that could be attributed to the general speakers. We heard from a few people about certain business cases, as they described how Redis was used beneficially in their work. But for me, the best parts of the day were the beginning and end, when we got to hear from the brilliant creator of Redis: Salvatore Sanfilippo (a.k.a., Antirez).

Since most of the time was spent more towards the corporate pitch, it was refreshing to hear Antirez talk about all of the technical features in the newest version of Redis and how the need and implementation for these features came about. All of which was told using his interesting drawing style, which I had never seen a presenter do before. But I definitely appreciated it, since I tend to do the same thing whenever I describe anything with precision. (Even how to properly build a sandwich.) I also appreciated it since he and I probably have the same skill level of drawing:

Even though some people might tune out during these kinds of events (especially at the end, when people are looking to beat the crowd by leaving early), I enjoy the technical presentation as a breath of fresh air. Who knew that a detailed explanation on the evolution of the Redis EXPIRE command could wake me up from my imminent coma? I was just as surprised…almost as much as Antirez was when I approached him later, to thank him for leaving Sicily to speak and to ask him some questions. (Note to self: pay attention to your surroundings and never ask questions of someone when they’re waiting to use the bathroom, especially a database guru. You may not get the best answers, and you will feel a tad awkward when you realize your mistake.)

So, what did I take away from that day? Well, I could say that Redis is definitely growing its user base. Just from a glance and a shoddy memory, I’d say that the crowd was nearly double the size of last year’s event. Plus, I heard about a more diverse set of projects using Redis than ever before. From all that, I would say that it’s becoming a bigger fish in the DB sea.

So I guess the ultimate question is: who’s going to try and eat the growing fish before it gets too big? My money is on Oracle.