Thursday, October 30, 2014

Lubuntu vs Xubuntu 14.10

I am religious upgrading my Linux distribution when a new version of Ubuntu is released. In 14.10, I've decided to jump onto the Xubuntu bandwagon, having seen that monitor handling is still bad in Lubuntu. I've downloaded both 64bit images from torrent and got the idea to leave my machine on and see which distribution comes out on top after 1 week. Interesting way to track popularity, by torrent upload ratios that is.

Here are the results:



A few observations:
1. Lubuntu is more popular, albeit with a substantially smaller ISO image. The actual data amount uploaded for Lubuntu was 34GB, while Xubuntu had 41GB uploaded. Still, the ratio is a more relevant metric and it renders Lubuntu more popular.
2. The activity on both dwindled significantly by day 7.
3. The Lubuntu to Xubuntu ratio on distrowatch (today) is 1.54 in favour of Lubuntu. The ratio I see is 1.16 in favour of Lubuntu.

Tuesday, June 26, 2012

Dependency injection for beginners


Dependency injection for beginners

Dependency injection, also known as Inversion of control is an often used term in the Java community. It may sound sophisticated, even scary, to beginners. This article aims to explain what dependency injection is in the simplest way possible. The goal is for every Java developer to understand what this term is all about.

Dependency injection is a way of developing software that makes it _testable_, i.e. by leveraging dependency injection, you allow your classes to be tested. We achieve that by passing (injecting) dependencies. That's really the main idea behind dependency injection.

The simplest example illustrating the concept:

1. Code without dependency injection
public void processPerson(Integer personId) {
  DatabaseConnection con = ConnectionManager.getConnection("localhost:4342");
  ResultSet rs = con.execute("select * from Person where personId=" + personId);
  Person person = new Person();
  person.setName(rs.get(0));
  person.setSurname(rs.get(1));
  if (person.getName()==null) {
    person.setName("unknown");
  }
}

Is this code testable? Sure it is. But in order to test it, you need to have a SQL database running on your machine with exact data that fits your test (i.e. a person with specific data and personId). This has a number of issues:
- your tests are many lines long and hard to write
- your tests are slow because a the test methods need to read from the database
- your tests become flaky because they rely on data stored in the database. If that data changes (or the database login changes for example), your tests will behave incorrectly
The last point is the most serious one because everything might be working nicely for a while and your tests can fail for no apparent reason after a while.

The code above has a dependency on the database connection which is created within the method. This makes the method very hard to test as we can't change the behavior of the database connection, i.e. it will always connect to an database server.

1. Code with dependency injection
public void processPerson(Integer personId, IConnection connection) {
  ResultSet rs = connection.execute("select * from Person where personId=" + personId);
  Person person = new Person();
  person.setName(rs.get(0));
  person.setSurname(rs.get(1));
  if (person.getName()==null) {
    person.setName("unknown");
  }
}

This code requires the connection (the dependency for the method to work properly) to be injected. From a testing perspective this is great, because we can create a test implementation of the IConnection interface, like so:

class TestConnection implements IConnection {
  public ResultSet execute(String sql) {
    String name = null;
    String surname = "TestSurname";
    ResultSet rs = new ResultSet(name, surname);
    return rs;
  }
}

...and it would hence simulate a Person with null set as name and "TestSurname" set as surname.

Advantages of dependency injection:
- external dependencies become transparent and they are no longer hidden in the business logic
- makes code testable by enabling to change the behavior of external dependencies
- tests are super fast as you create small objects isolated from the external environment
- tests are deterministic (i.e. no longer flaky) because no matter what happens in the environment, you'll get the same results from your tests

P.S.: I realize that senior software developers wouldn't write such code as I used in my example. It breaks the separation of concerns principle because the processPerson method deals with both retrieving the person and executing some business logic on the person. This should not happen in a clean OO design. I deliberately crafted the above code, as experience tells me many many developers would write such code and hence it's a good way to demonstrate dependency injection on it.


Wednesday, June 20, 2012

Paging in Google App Engine


Paging in Google App Engine


I've spent the past couple of days spending my time trying to figure out how to do proper paging in Google App Engine. Once I have a workable solution, I'll open the stuff out on google code as I see lots of people struggling with this.

The goal: create a simple but powerful paging solution for GAE, with the following features:
- forward and backward paging, support for first page and last page
- sorting by (a subset) of fields (one order only at a time)
- having a filtering criteria in a like fashion (e.g. typing 'Tom' will filter and only display persons with name starting 'Tom')
- keep track of total number of pages

Design decissions:
- do NOT use limit/offset as it doesn't scale. Instead rely on cursors
- use sharding to keep the total number of pages updated
- accept compromises, but aim for the best performance/scalability

The obstacle (i.e. last bastion):
I feel the only problem left is when I have a filtering criteria (e.g. name begins with 'Tom') and a sorting criteria on a different property.

e.g. Person [name, age]
Filter by name 'Tom*'
Sort by age

Reading through the documentation, I thought I've found the solution:
Query q = new Query("Person");
q.addFilter("name", FilterOperator.GREATER_THAN_OR_EQUAL, nameFilter);
q.addFilter("name", FilterOperator.LESS_THEN, nameFilter + "\uFFFD");
q.addSort("name", SortDirection.ASCENDING);
q.addSort("age", SortDirection.ASCENDING);

I thought this would return:
Tom2 18
Tom1 20

Unfortunately, this returns
Tom1 20
Tom2 18
as the query is first filtered by name, then by age as a secondary key.

The only solution I can think of is to put the whole filter result into a Java structure, sort by using a comparator and then pick the records I want to display. But this has an additional problem that my cursor logic disappears. Which then kinda means I have 2 logical paths for solving paging. Which might be the ultimate solution, but I wonder if anyone smarter has a better idea.

Any ideas welcome.

Thanks,
Matyas