RPi resurrection – Pt. III – Plex Media Server

The third good use one could put the Pi to, and use it thoroughly is as a Media Server. And that’s where Plex comes into the picture! I know, it’s nothing new — since probably the inception of RPi, there have been numerous such apps and OSs which have done the same — XBMC ports, Kodi, and likewise. But I have had mixed experiences with them — beyond the initial “aha!”, the experience wasn’t what one could “delightful!” in the long run. I think the biggest hassle for me was loading the media, to start with. This was followed by other aspects, like account management, supported formats (or the lack of it), and what not.

Continue reading RPi resurrection – Pt. III – Plex Media Server

RPi resurrection – Pt. II – NFS

The second good use you could put your Pi, more so if you have unused external HDDs lying around, is to make an NFS out of it! I’ll spare mirroring the details here, there are many good references on how to go about creating a Samba server. For example, this one.

Since my laptop’s storage is limited, oftentimes it started complaining, as soon as any space-consuming operation started. At that point, I often had to make some hard life choices! :), you know, of the “shall I keep the big file or zap it!” kinds.

Continue reading RPi resurrection – Pt. II – NFS

RPi resurrection – Pt. I – Pi-hole

Couple months ago, got to know about the Pi-hole project. It’s an ad-block server that can you can configure at the network level. That is, it can be configured as the DNS in your home router.

Of course, the benefit of network-wide ad-blocking is that it does its job in all of your home devices. If however, your router does not allow configuring a DNS — then you’d have to configure the DNS on a per-device level. While it may sound painful, but trust me, it’s worth it!

Continue reading RPi resurrection – Pt. I – Pi-hole

“Apology-based computing”

I came across this phrase sometime back, and was instantly intrigued by it. So, like any good samaritan, let me share what I could make of it for the larger good of humankind! While I present my assessment, I’ll also highlight aspects that make it very viable in most of the computing contexts. We will also delve into how this phrase, at some level, dabbles with the aspects of modern day computing like eventual consistency, the tradeoff between performance and correctness, and Amdahl’s law.

First, let’s get to understand what the phrase means.

Continue reading “Apology-based computing”

Microsoft++

Although, maybe, I am obligated to be loyal to AWS for various reasons (my work is AWS-centric, plus the fact that it facilitated my foray in the cloud), but still, over the short span of time that I have been in this field — I am getting increasingly impressed with Microsoft. Their documentation on aspects like cloud design patterns, microservices, etc., is simply impeccable — to say the least!

Moreover, since I am a huge fan of MOOC websites like Coursera, edX, etc, not very long ago, I came across a very nice course on edX, being offered by Microsoft, called Architecting Distributed Cloud Applications, which, again, I loved!

Apart from cloud-specific courses, they have a lot of other, general CS courses in the offing, which are also pretty good.

Overall, I think MS has come of age under Mr. Nadela, and is delivering how it should. Kudos to the teams, who keep such useful artefacts updated, as well as open to the world.

After all, the age of silos is long gone, and collaboration is the key!

Hosting a WordPress blog on AWS (for free!)

Much of what I write is a compilation of what I found on the Internet, esp. Pēteris Ņikiforovs’s post. I am indebted to him, as I heavily benefitted from his post while trying to get WP working. However, since that article is a bit dated, and cannot be used verbatim — I decided to jot this post down.

It is assumed that one would be having the domain name handy (e.g. myblogsite.com or foobar.io), before proceeding with the installation. In this post, let’s go ahead with foobar.io.

Continue reading Hosting a WordPress blog on AWS (for free!)

Streaming (only) audio using an old AppleTV (and a few nuances, thereof)

Oh, the ever-unsettled human!

In this age of wireless everything, I chose to stay ‘wired’ for a long time, especially when it came to music. Reason: although I don’t (can’t) claim to be an audiophile, I do appreciate hi-fidelity (hi-fi) music. Hi-fi audio is soothing even at high amplitudes, and I think good tracks deserve a listening, and not just a hearing! In other words, I am not a .mp3 guy, but more of a .wav (or .flac, if you please) person. Uncompressed/lossless audio rules!

My audio rig is a simple (non-wireless) amp and a pair of monitors, and it pretty much serves my purpose.

Continue reading Streaming (only) audio using an old AppleTV (and a few nuances, thereof)

The ‘L’ in SOLID

Uncle Bob‘s aptly coined SOLID Design Principles form the basis of a robust software application. Today, I want to talk about one of those principles, the Liskov’s Substitution Principle (LSP) because it’s easy to deviate from, and a few conscious design choices can prevent us from doing so.

In the simplest terms, LSP suggests that:

Any change that makes a subtype not replaceable for a supertype, should be avoided.

Suppose, we have a class hierarchy like so:

At the first glance, the relationships here seem fine, but if we carry out an IS-A test, the issue becomes obvious: that Tea isn’t necessarily a CaffeinatedDrink (for instance: there’s decaf!).

Continue reading The ‘L’ in SOLID

Smarter ValueObjects & an (even more) elegant Builder

Value Objects (VOs) are prevalent and needed in traditional Java programming. They’re almost everywhere —  to hold information within a process, for message-passing, and various other areas.

Apart from having getters and setters for the properties, on several occasions, there’s a requirement for these VOs to implement equals() and hashCode(). Developers usually hand-write these methods or use the modern IDE templates to generate them. This works fine initially or until there’s a need to update the VOs with one or more additional properties.

With an update, the baggage that comes with new properties includes:

  • a new set of getters and setters,
  • updates required to equals(), hashCode(), and,
  • update required to toString(),if needed

This is, of course, cumbersome, error-prone, and the simple VO soon starts looking like an airplane cockpit!

Google’s AutoValue framework is a smart approach to address this issue. With just a couple of annotations, almost all of the “junk” is done away with, and the class becomes smarter — any future property updates, including getters, setters, as well as equals()*, hashCode()** and toString() are all handled automagically!

The VO then just looks like a basic set of properties of the given type, like so:

import com.google.auto.value.AutoValue;

@AutoValue
abstract class CartItem {
    abstract int itemCode();

    abstract int quantity();

    abstract int price();

    static CartItem create(int itemCode, int quantity, int price) {
        return new AutoValue_CartItem(itemCode, quantity, price);
    }
}

Note the default presence of a static factory method create(), as suggested in Effective Java [Bloch, 2017], Item 2.

The use of this annotated VO would be no different from a typical one. For instance, the CartItem defined above would have a simple invocation like this:

@Test
public void create() throws Exception {
    CartItem item1 = CartItem.create(10,33, 12);
    CartItem item2 = CartItem.create(10,33, 12);

    assertEquals(item1, item2); // this would be true
}

Apart from the default support for a static factory, AutoValue also supports Builder classes, within the VOs. Armed with this knowledge, let’s take another jab at the example in my previous post on Builders.
We continue with the same Cake example and add the required annotations and modifiers. The updated version of the class would then be:

import com.google.auto.value.AutoValue;

@AutoValue
abstract class Cake {
    // Required params
    abstract int flour();
    abstract int bakingPowder();

    // Optional params
    abstract int eggs();
    abstract int sugar();
    abstract int oil();

    static Maker builder(int flourCups, int bkngPwdr) {
        // return builder instance with defaults for non-required field
        return new AutoValue_Cake.Builder().flour(flourCups).bakingPowder(bkngPwdr).eggs(0).sugar(0).oil(0);
    }

    @AutoValue.Builder
    abstract static class Maker {
        abstract Maker flour(int flourCups);
        abstract Maker bakingPowder(int bkngPwdr);
        abstract Maker eggs(int eggCount);
        abstract Maker sugar(int sugarMg);     
        abstract Maker oil(int oilOz);

        abstract Cake build();
    }
}

Observe that:

  • the member Builder class (named Maker here) just needs to be marked with @AutoValue.Builder annotation, and the framework takes care of everything else
  • in the parent class, we could also have had a no-arg builder() method but we specifically want to have only one way of building this class — with the required params
  • as shown above, the optional parameters should be set to their default values since we want the flexibility of choosing only the relevant optional params. [With non-primitive members, @Nullable can be used.]

Just to complete the discussion, here is an example of the ease with which this new builder can be invoked:

@Test
public void makeCakes() {

    // Build a cake without oil
    Cake cakeNoOil = Cake.builder(2, 3).sugar(2).eggs(2).build();

    assertNotNull(cakeNoOil);

    // Check that it has 0 oil
    assertEquals(0, cakeNoOil.oil()); // default

    // Make cake with oil
    Cake cakeWOil = Cake.builder(2, 3).sugar(2).oil(1).eggs(2).build();

    // Obviously, both the cakes are different
    assertNotEquals(cakeNoOil, cakeWOil); // valid

    // Another cake that's same as cake w/ oil
    Cake anotherCakeWOil = Cake.builder(2, 3).sugar(2).oil(1)
            .eggs(2).build();

    assertEquals(cakeWOil, anotherCakeWOil); // valid
}

There are many other fine-grained things that can be done while using AutoValue, like specifying getters for specific properties or customizing toString(), etc.

It’s impressive how AutoValue facilitates writing and static factory methods and builders quickly — taking the headache out of defining and updating VOs.

[Full implementation of the abovementioned example is here.]

Further reading:

  1. AutoValue with Builders
  2. Project Lombok also addresses the VO update issue, along with other things

* Effective Java [Bloch, 2017], Item 10
** Effective Java [Bloch, 2017], Item 11

Books: Java

EffectiveJava-Bloch

When I was writing the last post, I realized how much I used to be in awe of Effective Java [Bloch, 2017]. It was a book that covered what no other did. It wasn’t just coding — there’re plenty of books where one could learn “Your first Java Program” and beyond, and throw an air punch. It wasn’t also about language syntax and semantics — Java Complete Reference [Schildt, 2017] fitted the bill there*, or OOPs (every other Java book started with OOPs concepts). Rather, Effective Java covered the basics of writing elegant Java code, and as a by-product, also underlined how easy was it to be swayed away by ‘convention’. I wouldn’t recommend it as a Java learner’s first book. But it should very well be one’s second Java book and the one that she/he would keep revisiting throughout the programming career.

Ever since I’ve picked it up again, it’s become tough to keep it aside. With each of its topic, I realize, over time, how much have I drifted away from the delight of writing good code, and how much do I need to still learn.
Go read it now if you haven’t had a chance yet. What’s more, the much-awaited 3/E, which covers Java 7, 8 and 9, is out now!

While on this topic, let me talk about another one of my favourite books on Java — Thinking in Java [Eckel, 1998].

ThinkingInJava-Eckel

This is the book which I considered as a Java developer’s Bible at one point in time. Since there are no new editions after the 4/E, the syntactical parts might be a bit obsolete now. But still, in my opinion, it’s the best book to get one’s (Java & OOPS) fundamentals in place.

* I have always found Java Complete Reference a bit too elaborate to my liking. Most of which is about the language syntax and semantics. All of that might have been useful in the early days of the Internet when it wasn’t that easy to look up things online. But I doubt if that’s needed now.