Wednesday, 30 October 2019

Horizontal Scaling Vs Vertical Scaling

Q: Why do we need to scale a system, what is Scaling and Scalability?
Answer: When we provide a software solution, inevitably at some point the number of users of that particular product will increase. Putting more pressure of the system in terms of hardware computational limits, size etc on the backend to fulfill the increased demand.
In such situation we definitely need to grow our backend system bigger to be able to meet those requirement. This is called scaling of the system. The effort needed to scale the solution is called Scalability, ie how easy/hard is it to scale the system. Now a well designed solution should be easily scalable.

Q: How do we actually Scale?
Answer: Now that we know what is scaling lets talk about how is it done in the real world software solutions. There are majorly two ways to scale a system. 1. Horizontal scaling 2. Vertical scaling.

1. Vertical Scaling: In this, you basically make your machine bigger, possibly by adding faster CPU, more memory or drive etc. To be able to handle more requests faster. But point is you stick to the same machine.

2. Horizontal Scaling: Here, you simply get one more machine in parallel and have both of the machines handle the requests.

Its like, if you want to lift more weight: You either build muscles to be able to lift that or you ask your friend to help you lift that weight.

Both of these strategies has give and take.


Pros and Cons of each approach.


  1. We need a Load balancer to distribute the load among the horizontally scaled system . Where as this problem doesn't exist in vertical scaling system.
  2. Horizontally scaled system are Resilient, ie. If one of the box/machine/computer fails due to hardware/software/power failure. other System can take charge to fulfill the requests. Where as in Vertically scaled system its the single point of failure, if your bigger and only machine dies, entire system is down! 
  3. In Horizontally scaled system we have to deal with all of the complications of distributed systems, like data consistency which can be crucial when performing financial transactions etc. Where are in Vertically scaled system, there is only one computer and everything is happening within itself only. So no such challenges.
  4. Horizontal systems scale further more easily, its simply adding more machines. Vertically scaled systems at some point will reach the hardware limits of being able to handle requests.
So in real world, we use a hybrid solution i.e Buy single bigger machines vertically scaled and then have multiple of them in parallel to Horizontally scale the system! 

Leave comments if you liked this read :)

Tuesday, 29 October 2019

Kotlin Class Properties and Backing Field. An Insight

Lets deep dive and understand the Kotlin class properties and backing fields!

Its a deep dive and expect understanding of 'class property', 'backing field' in Kotlin. If you don't know then please first read the official 1 page documentation for the same.

Official link: https://kotlinlang.org/docs/reference/properties.html#backing-fields.
And I am sure you will visit this page again with a bunch of question while trying to wrap your understanding around it. And this is the reason that I wrote this blog to help fill those gaps.  

Question that I am going to answer:

1. We needed to provide Initializer while defining the property. Why? Are there cases where we don't have to provide Initializer to be able to compile code? What happening behind the scenes? 

Answer: Kotlin Initializer assigns the value to the automatically generated backing field for the property. So that means, If there is no backing field [in some cases] then we don't need to provide the initializer too!  So that lands us at question#2

2. When do Kotlin generate Backing field, and when not ?

1. If you use at least one of the default accessor method i.e getter or setter Then Kotlin is going to generate a backing field for that property. Contrary, If you happen to override both of get() and set()[When applicable] methods. Then backing field is not generated.

2. If you happen to use 'field' keyword in the overridden accessor methods. Then Kotlin generates the backing field  and you will have to provide initializer when defining the property. 

e.g. 

class Test{
    

       //No backing field generated. Because all of the accessors were overridden and 'field' is not used in overridden methods. Hence Notice we didn't even need to provide the initializer, cuz it has not purpose anymore and hence its a compilation error.

        var hasField : Boolean
          get() = false
          set(value){}

     // Backing field not generated, because all of the accessors were overridden. Yes All, because read-only property defined using 'val' keyword doesn't have setter. And 'field' is not used. Hence backing field is not generated and so we cannot provide initializer. 

        val hasValField : Boolean
             get() = false 

      // Backing field is generated. And hence we needed to provide initializer to compile the code. 

       val example2: Boolean = true
          get() = field > 100

    // Backing field is generated because setter is not overridden and hence we need to provide Initializer.

     var example3: Boolean = true
        get() = true;

// Backing field is generated, because we used 'field' in the accessor methods. Hence we must provide the initializer.

    var example4: Boolean = true
      get() = true
      set(value){field = value} 

}

3. Why do Backing field exist? 

Answer: Its because of the way Kotlin works! Lets take an example.

class Test{
     var foo = false
        get() = foo
}

You may think this code will work, but you will sendup in 'StackOverFlowException'. Android studio should be able to report this problem,

Whats the problem?
The call get() = foo, while trying to return foo from the getter the Kotlin will implicitly call the get() again, so get() calls get() and keep doing that recursively, and when you go out of runtime stack memory. The program will crash!

So the easiest workaround to fix this code is

class Test{
     var foo = false
        get() = field
}

Because remember from above 'field' is implicitly created backing field and assigned 'false' by the property initializer provided.

another example to work with Setter method

class Test{
     var foo = false
        get() = field
        set(value) {field = value}
}


And Thats it!! Feeling little confident? Answer this question in comments :)