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 :)

Sunday, 22 April 2018

Git Merge Strategies Part 1: Rebasing

Git Rebase




Git provides two merge strategies: 

1. Merge : It does a 3-way merge in case of diverse history. {it can also do a fast-forward merge, if histories were linear.}. Dont worry about history and some technical terms for now, you are fine trust me!! We will talk about it in an entirely different blog.

2. Rebase : It's like saying take all my local commits and fetch the origin new changes and apply my local commits now one by one to the tip of the origin branch.

Use case: 

1. If your working on the centralized workflow. and following is the situation. 

a. Origin master has  1--2--3 commits.
b. You checkout the branch and start writing your local commits i.e "a--b--c" on top of 3 locally. Note: You haven't push them on origin. Its worth noticing that right now your Base is "3" commit.
c. Now somebody pushed commit 4 and 5. So now the master looks like 1--2--3--4--5.
d. Now when you will try to push your 3 commits  a--b--c on the master. The git will throw an error message. Saying that the remote has some new changes which your local branch doesn't have.

Now comes the action: Now to pull the origin changes and merge them into your local branch you have two ways to do it.

1. Git pull [which is a combo of "git fetch" and "git merge"]. Remember "Merge" is one of the ways to bring the code and its a 3-way merge strategy which will endup generating an auto-generated commit. Which in cases, is un-necessary and will make your official project history very dirty with time.

Commands to issue:
git pull
// now push to the remote
git push

End result of this method: 1--2--3--4--5--6--a--b--b--merge_autogenerated_commit

2. Rebasing comes to rescue here, Its simply saying like, "Put all my local commits aside and bring the remote new changes and then apply my commits on top of it, one by one."
Note: Conflict merging is out of scope of this discusstion for now.

Commands to issue:
git pull --rebase
git push



Recap:

1. When you just want to pull the remote part of the same branch:
git pull --rebase origin <branchname>  : You can skip the origin <branchname part if branch tracking is already setup.>

2. When  your on a feature branch and you want to rebase on the master. ie. when you want to rebase on another branch
git rebase <source-branch> <sink-branch> : current branch is optional, when you give the branch name it becomes a combo command of git checkout <sink-branch> and then git rebase <source-branch>

e.g If you are on feature-a branch and want to rebase this branch with the top of master. then the command will look like
git rebase master

if you are not checkout out on feature-a branch then you can issue a combo command
git rebase master feature-a


Some technical insight:

Rebase guarantees fast-forward merging because the history of the two branches we want to merge shall be rebased before merging the commits hene generating a linear history.



There are advances rebasing too, but probably you won't use it everyday life. So I will just not re-iterate it, please visit the following links to learn more.
Source:
https://git-scm.com/docs/git-rebase
https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase


Friday, 4 November 2016

Configure multiple ssh keys on a pc.

https://gist.github.com/jexchan/2351996

1. Create your SSH

ssh-keygen -t rsa -C "your_email@gmail.com"
enter filename: id_rsa_jai

2. Add your keys to SSH Directory

ssh-add ~/.ssh/id_rsa_jai

3.Check all saved ssh keys to verify

ssh-add -l

4. Modify SSH Config
cd ~/.ssh/
touch config
vi config


Then add the configuration code:

# Jai Account.
Host github.com-jai
HostName github.com
User git
IdentifyFile ~/.ssh/id_rsa_jai

# Vipin Account.
Host github.com-vipin
HostName github.com
User git
IdentifyFile ~/.ssh/id_rsa_vipin

5. Add the Newly created ssh.pub file's data to your github.com account.


6. Finally add the .pub file of the newly crated ssh to the gitub account on the portal.

for mac: $ pbcopy < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard

7. You're done:

Now clone your repo like:
git clone git@github.com-jai:jpandit/att-demo-android.git


This will pickup Jai's Account's SSH Credentials BECAUSE OF THE HOST WE WROTE IN THE FILE




Tuesday, 27 August 2013

Jenkins Master/Slave Configuration.


Jenkins Master/Slave Configuration.

Taking our jenkins setup in concern.

We have a Jenkins instance installed on a Ubuntu 10.04 LTS machine. This machine is good enough to build Android projects through Ant build script. But  in order to build iOS Application and Windows application where the build has dependencies with the OS. We cannot build these application on our Linux
i.e we need to have a Mac and Windows machines resp to build their application.

So we would need to have separate slave machines which will help the master machine to build specific tied projects at their end.

To configure the master/slave configuration.

1. Create a new node
Home page->Manage Jenkins->Manage Nodes->New Node
New node configuration:
a. enter name
b. select dump slave and click ok.
c. enter slave name
d. enter number of executors on the slave machine.
e. usage : for ties jobs.
f. Launch method : Java web start.
g. Availibility : online as much as possible.

Now on the home page you will see a new node with the given name at the left side pane with a offline symbol. Now that you have a new node, all you need to do is to connect this new node.

2. Connect the slave machie :
a. Go to the slave machine for example a Mac if you want to make slave machine for building iOS apps.
b. open the jenkins in browser.
c. click on the new node that is showing offline.
d. Click on the "Launch" java web start icon.
NOTE: Initially you would get error as the .jnlp file you have downloaded doesn't contain the correct jenkins server instance path. So you would need to edit it and then again run it by double clicking the file.
e. It will open up a little popup showing "connected" text.
f. After the slave has been connected you could actually see the slave machine online which was showing offline with the defined number of executors you set in its configuration.
g. in windows machine you could also install this java application as a service so that in case of a reboot of windows slave machine the slave can run this application and again connect itself.
h. to install as service just go to the java web application: file->install as service.
and you are done. To double check do to start->services->search "jenkins" -> openup the service and configure it if required.
Double check the connect mode is set to automatic.

3. Jobs Configuration to run on the slave:
As our slave machines are configured to run only tied jobs. Now we need to specifically tie to jobs to always execute on the slave machines. For that.
a. create a new job or go to the configuration page of a existing job
b. Below the description section there is a check box saying "Restrict where this project can be run". So check it and enter the name of the slave machine where the job should run.
c. click save.
From now onwards the job will be executed on the slave machine.


That's it!!

Review board windows client setup

After once we have successfully setup a review board server(which is not part of this post) we need to setup our client machine to be able to create diffs and upload it onto the review board server for review.

Here i am covering how to setup windows client developer machine

1. Install Python2.7.3 : download form here - http://www.python.org/download/releases/2.7.3/

Reviewboard doesn't support 3.x versions of python to work properly.

2. Install python setuptools:
a. goto - https://pypi.python.org/pypi/setuptools/1.1#installation-instructions
b. search for "ez_setup.py"
c. right click and save the file.
d. run this script. It is suppose to download and install the proper version of the setuptools.

Note: You may run in a situation where the script could fail due to lack of administrator permissions.
And you would not get a option to run the script as admin. To enable that you would need to do certain registry tweaks manually. Follow the link - http://www.howtogeek.com/howto/windows-vista/add-run-as-administrator-to-any-file-type-in-windows-vista/

e. after successful installation you could see easy_install.exe under the C:\Python27\Scripts location.
f. add "C:\Python27" and "C:\Python27\Scripts" for easy access.

3. Install RBTools:
a. open command prompt
b. type = easy_install -U RBTools
c. It will install the RBTools for you.

Usage:

a. Checkout the code.
b. create a .reviewboardrc file and add line  - REVIEWBOARD_URL = 'http://reviewboardpath.com' 
c. type post-review - it should create the diff and upload it to the review board server now.

NOTE: If you see a error like "The current directory does not contain a checkout from a supported source code repository". Then in windows one of the most common cause would be that you dont have command line svn installed. It looks like post-review cannot communicate to the svn server through TortoiseSVN.

 

Monday, 19 August 2013

JavaScript Data Types.

Learning JavaScript is not a bad idea as this language is the future or both web and windows applications. Lets start by looking at the data types in a nutshell.

JavaScript has the following data types:

1. Numbers
2. Strings
3. Boolean
4. Arrays
5. Object
6. null
7. undefined

Lets talk about them briefly.

1. Numbers - There is only one number type, i.e there is no separate integer, float etc.
This number is a 64-bit floating point. Which is also called IEEE-754(aka "Double").

There is a special value called NaN(Not a Number)
a. It is a result of undefined or erroneous operation. e.g divide something by zero results in NaN.
b. Toxic: any arithmetic operation with NAN as input will result NaN as output.
c. NaN is not equal to anything including NaN. i.e NaN ==NaN is false NaN is not lesser or greater then NaN :). Even when NaN is not a number but its data type is a Number.

Functions to convert string into numbers.
  •  Number(value):
It converts the value into a number.
It results NaN if it has a problem.
Similar to '+' prefix operator

  • parseInt(value, 10) e.g parseInt("55", 10)
  • + prefix operator. e.g +"55"

2. Strings: It is a sequence of  0 or more 16-bit characters.
There is no separate Character type. i.e characters are represented as strings with length 1.
Strings are Immutable.
Similar Strings are equal ( == )
String literal can use single or double quotes.
String is a object and it has lot of methods to perform on strings i.e
a. charAt
b. concat
c. match ....etc

3. Boolean:  There are two values true or false.
There is a Boolean function i.e Boolean(value) which returns true if the value is truthy and false if its falsy
It is similar to !! prefix operator.

Falsy values:
  • false
  • null
  • undefined
  • "" (empty string)
  • 0
  • NaN
Truthy Values: All other values including objects are truthy. "0" ,"false" are also truthy. They are strings.

4. null - A value that isn't anything.

5. undefined :
a.  It is the default value for a variable. i.e if you declare a variable but don't initialize it. Then its value will be undefined.

6. Object: 
  1. Its a unification of objects and hash-table.
  2. new object() produces an empty container of  name-value pairs.
  3. A name can be any string, and a value can be any value except undefined
  4. Members can be accessed with dot notation. 
  5. An object is delimited by curly braces. Inside these braces we define the object's properties in the form of key value pairs.
Object is defined like:
var person={firstname:"Jai", lastname:"Pandit", id:5566};
or
var person = new object()
// now add properties to the object.
person.firstname = "Jai"
person.lastname = "Pandit"
person.id = "5566"

7. Arrays :

The following code creates an Array called cars:
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
or (condensed array):
var cars=new Array("Saab","Volvo","BMW");