Wednesday, 28 May 2014

Builder Design Pattern Example

Builders are great: I've been putting them into some code recently because we're building an API but don't want to make breaking changes every time we need to modify a constructor. Backwards compatibility FTW.

I'll illustrate with a simple example.

Before builder:

With a PersonBuilder:

Now, if we want to add a nickname paramater to the person constructor, we add a corresponding withNickName(String nickname) on the builder and don't break anybody's existing code. (Saying that, of course we could achieve backwards compatibility with the telescoping pattern but that would be TOO GRIM FOR WORDS. )

Sunday, 11 May 2014

Github: Keeping a forked project up to date

I forked a project from here: https://github.com/chbatey/scassandra-java-client to a copy attached to my own account here: https://github.com/apojha/scassandra-java-client.

However, if user chbatey makes any changes to his version of the codebase, I want to keep up to date with his changes by continually merging them into my repo.

To merge changes on his repo to my copy, I added his repository as a remote repo.

Step 1: 

Navigate to where I have checked out my fork of his project.


----------------------------
Before, the only branch is my own origin/master and the only remote project is my own:
bash-3.2$ git branch -r
  origin/HEAD -> origin/master
  origin/master

bash-3.2$ git remote -v
origin git@github.com:apojha/scassandra-java-client.git (fetch)
origin git@github.com:apojha/scassandra-java-client.git (push)
----------------------------

Step 2: 

Execute the following command to add a new remote repo called 'upstream' (this name can be anything): 
git remote add upstream git@github.com:chbatey/scassandra-java-client.git


----------------------------
After, his branch has been added (upstream/master) and there is a new remote repo called upstream:

bash-3.2$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  upstream/master 

bash-3.2$ git remote -v
origin git@github.com:apojha/scassandra-java-client.git (fetch)
origin git@github.com:apojha/scassandra-java-client.git (push)
upstream git@github.com:chbatey/scassandra-java-client.git (fetch)
upstream git@github.com:chbatey/scassandra-java-client.git (push)
----------------------------


Now, if I want to pull his changes I execute the following:
git pull upstream master

which pulls any commits on 'upstream' into my master. 

Contributing to someone else's Github project: Forking and generating pull requests

Recently, I have started to work on an existing open source project in GitHub.

Assumption: you have set up git locally and have an account on Github


Forking someone else's project


Step 1: Forking 


Forking creates a copy of the other person's Github project under your own Github account. To fork, navigate to their Github project page 'https://github.com/TheirUsernameXYZ/ProjectNameABC' and click 'fork' and follow the instructions.

You should automatically be navigated to your new Github page for the repository:
https://github.com/YourName/ProjectNameABC


Step 2: Clone your own fork


You need to create a local copy of your own fork by executing 'git clone <your clone url>' at the command line.

Generating a pull request


Pull requests are used when you make changes to your copy of their repository ie you have made local changes and commit them to git. You generate a pull request to say to the original owner of the project 'Hey, I've made some commits on my copy of your project. Why don't you review these changes and merge them onto your original branch'.


Step 1: Open your project


Navigate to your own project page:
https://github.com/YourName/ProjectNameABC


Step 2: Create a new pull request


Click on 'Pull Requests' and follow the instructions 



\o/ woohoo you have contributed to another project.

The next post details how you keep your fork up to date by merging any commits they make to their original branch.


Meow


Saturday, 10 May 2014

The problem with notifyAll() : Introducing Reentrant Locks

Here is a Buffer:

Imaging that you have two producers threads calling 'put(int i)' and one consumer thread calling get().

Imaging the following sequence of events:

- Consumer calls get() and blocks waiting for lock
- Producer1 calls put(int i) and, while it is in the synchronized block, Producer2 starts and also waits for the lock currently held by Producer1. Therefore both the Consumer and Producer2 are waiting.
- Producer2 releases the lock and calls notifyAll()
- The JVM chooses to wake Producer2 first
- Producer2 enters the synchronised block, sees it cannot write and goes back to waiting.
- Then the Consumer gets the lock, enters the block in the get() method and retrieves the variable.
- etc

This is totally functional code but the problem is that the JVM wakes all the threads, both producers and consumers.  This is fine in our example but imagine we had thousands of producers and consumers; suddenly it becomes very inefficient and memory intensive to wake up all the threads, when most of them will just go straight back to waiting because their predicate is not fulfilled.

The solution? Java 5 reentrant locks!

These allow you to have different wait conditions and wake only the threads that are waiting for that particular condition.

The modified solution is shown below:



Scala with Cats: Answers to revision questions

I'm studying the 'Scala with Cats' book. I want the information to stick so I am applying a technique from 'Ultralearning...