Friday, December 5, 2008

Google Gears - features for performance web application

What does web application gets from Google Gears?
Straight and simple as google says..
- Interect with Desktop
- Use gears local server for caching.
- Store data in offline mode and synchronize when online.

Last thing is seems most interesting to me.. I can use the webpages even if i am not connected to internet. Thats cool. I used an webapp that uses google gears http://www.rememberthemilk.com
for this purpose.


[ Lightweight database on client Side ]

Gears uses SQLite for database support. And its secured, because a web application cannot access data outside of its domain. More importantly it supports fulltext search.
Using this Database API is very Simple Only two classes Database and ResultSet. Using this api is so simple i cant help copying the code. :D


// db is instance of Database
var db = google.gears.factory.create('beta.database');
db.open('my-database');
// rs is Instance of ResultSet
var rs = db.execute('select * from TestTable order by Timestamp desc');
while (rs.isValidRow()) {
alert(rs.field(0) + '@' + rs.field(1));
rs.next();
}
Its simple :). This feature is actually for storing user data in offline mode and when user is online, this information has to be synchronized. Still i am not clear enough about how synchronization should be done.

[ Another most interesting feature : LocalServer. ]
Pages and files/resources can be served in offline mode from Localserver. When localServer is configured to serve some url, it caches those files/resources with urls. Each time that url is requested localserver servers those resources/files without sending actual server request. Thats one cool thing.
How does Localserver know which urls to cache?A manifest file is used to tell the urls and version info of the urls. Local server gets the manifest file each time. And update resource from urls if it doesn't have the latest version.

[ Using Google Gears in your page. ]
* Install Google gears first http://gears.google.com/
* Download this script gear_init.js

* Include this script in the page

=: First thing you should in your page is check whether this pc has google gears installed.
if (!window.google) {

alert("gear is not here!");

location.href = "http://gears.google.com/?action=install&return=http://yoursite.com";

}


=: How do you get the api implementation of Gears? Gears provides an Factory for this.
This is how you will get the LocalServer to cache files.

var localServer = google.gears.factory.create("beta.localserver");
And get the database..
var databae = google.gears.factory.create("beta.database");

Using these localserver and database is simple and i am not going to present them... google documented them good enough.


[ Other supports from Gears]

There are other supports like httpRequest, Timer. But they are not new in Javascript programming. Actually these are implemented to be used from Gears WorkerPool

For "Interect with Desktop" They should have said file access feature..
Because their implementation gives two feature.
- Can create shortcut in pc file system.
- get a file content from the pc files system. File content is served in Blob format.

Oh here is one thing new here "Blob". That's an implementation by Google Gear.
Javascript itself doesn't have Blob support. Blob can be passed into, and returned by, a variety of Gears methods.

Other cool things in Google Gears are GeoLocation & Workerpool API. Hope to give a demonstration on those soon.
.

Monday, September 15, 2008

putting debian dependency while creating .deb by alien

A .rpm package can be converted to .deb package using following command
sudo alien --to-deb --scripts someone-0.11-4.i386.rpm
it will generate a .deb package someone_0.11-5_i386.deb

What alien cannot resolve is converting rpm dependencies to debian dependencies..

So, here is a solution.. (there might be others).. putting the dependencies manually..

1. convert the rpm package to debian package format directory. use command
sudo alien --generate --scripts ecedemo-0.11-1.noarch.rpm
this will create directory someone-0.11/ with deb package like structure.

2. now, all you have to do is change the someone-0.11/debian/control file. add whatever dependencies you like in the for "Depends: " tag.
Depends:sun-java5-jre, slapd

3. rebuild deb package from intermediate direcotory
cd someone-0.11/
sudo dpkg-buildpackage

Thursday, July 3, 2008

Logging with log4j : Options and Features


Here are some tricks and options how log4j logger can be configured.
If you are new to Apache Log4j, you should consider this post first... logging-basics-with-log4j

Separating logger.


You may need different log output behavior from different classes.
Suppose your application uses Hibernate and you want all hibernate-generated logs to go in a special file, say "app.hibernate.log". So, what you need is to define separate logger configuration for Hibernate classes.

log4j.rootLogger=DEBUG, A1, F1
...
..
log4j.logger.org.hibernate=DEBUG, H1
log4j.appender.H1=org.apache.log4j.FileAppender
log4j.appender.H1.File=logs/app.hibernate.log
....
..


That is Logger of class org.hibernate.Session , Logger class of org.hibernate.criterion.DetachedCriteria will use the configuration for log4j.logger.org.hibernate.

One more trick... if you don't want to include the hibernate log to be added in root logger, add this in config.
log4j.additivity.org.hibernate=false

Level inheritance of loggers

If logger's level is not specified, it will inherit it's parent logger's level.
if you specify org.hibernate logger like this log4j.logger.org.hibernate will inherit level of log4j.rootLogger
log4j.logger.org.hibernate=, H1
or
log4j.logger.org.hibernate=INHERITED, H1

What is appender?

If logger's level is not specified in the configuration it will inherit it's parent logger's level.

Appender is a component in log4j. Appender decides
  • where to put your log output ( file, console, ..)
    log4j.appender.C1=org.apache.log4j.ConsoleAppender
  • what is the format of your log.
    log4j.appender.C1.layout=org.apache.log4j.PatternLayout
  • to which level log output should be filtered.
    log4j.appender.E1.threshold=ERROR
You can specify these things in logger configuration.
Mind it, A logger can have multiple appenders.

Using file appender

File Appenders are used to store log output in files. There are several file appenders in log4j with different file creation policy and layout . Configuration of file appenders includes file name, file creation policy, output pattern. Here are some common issues with file appenders.

When you don't wanna loose previous log

By default, Every time you restart your program, your previous log file is removed by new log. But if you want your previous log to persist and new logs to be appended in that file, use following configuration.
log4j.appender.F1.Append=true

Manage fixed size log files.

Hmm.. you are not loosing any log, but aren't you creating enormous log file. Don't worry. You can configure appender to split log file when they grow upto a predefined size. For this, you have to use RollingFileAppender instead of FileAppender and define the threshold size of the log file.

log4j.appender.X1=org.apache.log4j.RollingFileAppender
log4j.appender.X1.MaxFileSize=10240KB
log4j.appender.X1.MaxBackupIndex=12
This configuration will create log files of at most 10MB and will not create more than 12 log files.

Manage daily log files

You want your server to create and use new log file every day. Try DailyRollingFileAppender
log4j.appender.F1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.F1.File=logs/server_daily.log
log4j.appender.F1.DatePattern='_'yyyy-MM-dd'.log'


Send mail for error logs

You want your application to notify you when it puts a log of FATAL level? ( you can do it for other levels too). You don't need to write code for sending mail. You can configure SMTPAppender to do this for you.
log4j.appender.E2=org.apache.log4j.net.SMTPAppender
log4j.appender.E2.layout=org.apache.log4j.PatternLayout
log4j.appender.E2.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n
log4j.appender.E2.SMTPHost=exchange.spectrum-bd.com
log4j.appender.E2.To=rkzico@spectrum-bd.com, ruby@spectrum-bd.com
log4j.appender.E2.From=error@spectrum-bd.com
log4j.appender.E2.threshold=ERROR


Appender Layouts

Other than pattern layout There are some nice Layouts.
An appender with HTMLLayout lets you see your log output in web browser in a table format.
sample.
log4j.rootLogger=DEBUG, htm
...
log4j.appender.htm.layout=org.apache.log4j.HTMLLayout
..


You can have your log to be saved as XML data by using XMLLayout. You can make intelligent use of this XML log information and also see log files in tools like Apache chainsaw.

Tuesday, June 24, 2008

Logging Basics with Log4j


Why use a smart logging tool...

  • We can put log output to different presentations like console, log file.
  • We can categorize log entries to several level of importance and purpose (Debug/ Info/ Error). And then restrict log output to a certain level when we want.
  • Logger provides time, class, other information in log output.
  • You can personalize the format of log output.
  • And many other…

How to put log4j logging in my code…

  • Configuration: Before using Logger class for logging, you need to load configuraion in your program. Otherwise your log will not be printed or put anywhere.

    • write a config file "myApp.log.config". Following is a simple configuration to show log in console and store in a file "test.log"

      log4j.rootLogger=DEBUG, A1, F1

      log4j.appender.A1=org.apache.log4j.ConsoleAppender

      log4j.appender.A1.layout=org.apache.log4j.PatternLayout

      log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x -%m%n

      log4j.appender.F1=org.apache.log4j.FileAppender

      log4j.appender.F1.File=${user.home}/test.log

      log4j.appender.F1.layout=org.apache.log4j.PatternLayout

      log4j.appender.F1.layout.ConversionPattern=%p %t %c - %m%n
      details of configuration...

    • Load the configuration from code

      PropertyConfigurator.configure("myApp.log.cofig");

  • Log Now! You are ready to log.
    • Get the Logger class
    Logger logger = Logger.getLogger( this.getClass() );
    Logger logger = Logger.getLogger( MyClass.class );
    Logger logger = Logger.getLogger( "ClassName" );

    • Log your message in appropriate level
    logger.debug ( "No of content loaded : " + lenContentList );
    logger.error( "Error occurred while parsing", execption );
    logger.fatal( "Failed to connect the server" );

Appropriate use of logging levels

Here is a guideline for deciding the logging level when you put a message in the log.

  • FATAL: at which point your application or part of application is no longer functional to serve.
    • Crash of the application.
    • Crash the relevant sub-component.
  • ERROR
    • Usually when a Java exception occurs.
    • Processing of a request is postponed due to some error.
    • Processing a request has not cover all features.
  • WARN: indicates minor problems
    • Factors external to the application. Such as missing or inconsistent input parameters supplied by user.
    • Improper initialization, configuration etc.
  • INFO:
    • Significant non-error events in the normal life cycle of the application.
    • When a request is successfully processed in your application.
  • DEBUG
    • Printing value of a variable or object property in log .
    • Non-error events in the normal life cycle of the application
  • TRACE
    • Usually used for timing information.

Wednesday, June 18, 2008

JMeter : Running a flock of your client program

You want to have a performance test of your server.
So, you need to run a flock of client programs and see how server handles them.

What you can do is put some people in testing.. ( not that good idea )
another way is.. you can use some test tool like JMeter to run a good number of your client program copies.




Say, Your main concern is to r
un you client by WowClient.start();
You use main method of ClientKicker class to load configuration and start the client.



The Shepherd.


Now, you move this responsibility of running the client to a sampler class say WowClientSampler which extends JavaSamplerClient. So, it has to implement four functions. JMeter ( the shephard ) can call a flock of this WowClientSampler through these functions.




When we introduce this WowClientSampler with JMeter

  • JMeter runs a number of WowClientSampler (test).
  • On separate thread it runs one instance of WowClientSampler.
  • JMeter can iterate each test a number of times on a thread.
public class WowClientSampler implements JavaSamplerClient {

public SampleResult runTest(JavaSamplerContext arg0) {
// Client is to be kicked from this function
// JMeter calls this function on every iteration.
....
Client.start();
}

public void setupTest(JavaSamplerContext arg0) {
// this function loads initials configuration and setup.
// this is called once in every thread at start of the test.
....
}

public void teardownTest(JavaSamplerContext arg0) {
// this function can be used to free up resource at end of test
// this is called once in every thread at start of the test.
....
}

public Arguments getDefaultParameters() {
// TODO:
....
}
}

How to deal with shepherd?

What you have ...
  • your WowClient in client.jar
  • your other libraries needed by WowClient are dpnd1.jar, logging.jar
  • You have downloaded JMeter from apache site.. download jmeter and extracted to folder jmeter
What you need to do...
  • put client.jar in jmeter/lib/ext ( this is
  • put you dependency libraries ( dpnd1.jar, logging.jar ) in jmeter/lib.
  • run jmeter/bin/jmeter or jmeer/bin/jmeter.bat
  • Jmeter test run window appears
  • Test Plan > Add > Thread Group
  • Thread Group > Add > Sampler > Java Request
  • Here you can find your WowClientSampler in a combo box.
  • Select you test class ( WowClientSampler ). Select other parameters
  • Run Menu > Start.
  • Do you find JMeter is making a flood of your client program.. :D

Configuration parameter's
  • Number of threads (users) - how many threads you want to run. each thread will be represent one instance of your client program.
  • Ramp-up time - In this period, all of you threads will be up and running.
  • Loop count - how many times each thread will run the client program.

Sunday, June 15, 2008

Approaching patterns: Our mistakes

By definition patterns are to give solution of design problems.
Sometimes we don’t understand context and intent of problem that a design pattern conveys. Then we start using this pattern in a wrong way, in a wrong place, sometimes we got over enthusiastic about patterns. That results in a bad design.

Only mistake we did is we didn’t approached the pattern in right way. So it is very important how we meet Mr. X pattern. Definitely, we have to follow a pattern for studying a design pattern : D

Big Mistake :
Almost Every writer describes the purpose of the pattern in the first line. And readers push it hard to understand this very first sentence. And this causes the greatest disaster. (Applicable for newbies).

Bigger Mistake :
After understanding the purpose... (I don’t how many people get this actually) we directly move into the class diagram that shows the solution of the design problem. (Wow man, I got the problem in one sentence and solution in one diagram… I know 60% of the design pattern). Now let’s go through some example and then Mr. X pattern will be transparent to me.

This approach works for a few patterns (for Mr. Factory, Mr. Singleton…)

But reality is.. When we face real life problems….

  • They are sometimes so hidden that you cannot get into it in right time.
  • Some patterns are so related that you cannot distinguish.
  • There are alternative patterns for almost same problem.
  • Sometimes you are so enthusiastic about patterns, that you decide I must use this pattern then put the cork in wrong bottle.

Okay, don’t take it so hard. I have some pattern on learning pattern.

Did you wash your hand before eating?? You have to learn and realize some basic concepts to a good extent before you move to design patterns. If you are serious about a good design, you are gonna consider your pillar. Preferably, you should have nice understanding with OO concepts, interface, abstract, delegation. Can you please revise although you learnt what is interface?

(Poth pothiker srishti korena) Pedestrians create the path. Don’t try to map pattern names with problem definition at first. First face the problem, solve it your own way. Then look for the actual solution what pattern gurus do? That is how you become capable of solving a problem with help of Mr. X Pattern.

Are you doing well? Now, you have to consider these…

Ratul and Zico are twins. Both of them in love with Emmy? Nope. There are some patterns that are very common in structure but different in their use and intent. ( Strategy & Bridge Pattern )

On whom will you take the bet in wrestling? The agile one or the strong one? You will find many problems that have multiple solutions. You have to choose the right one so that you can appreciate yourself in the long run. ( Template Vs Strategy Pattern)

Dr. Zekyl &Mr Hyde. Get double minded. Convince yourself when you use a pattern in your design. When you have your own logic for why you’ll use this pattern, try to argue with yourself why you shouldn’t use this pattern. Believe me, this ensures that you don’t misuse patterns and you realize the intent of the pattern in the long run.

How about a cherry on your ice-cream. You may have understood the naive version of a pattern. There may exist improvements of the pattern. You can handle your problem smartly when you have known different version of Patterns. ( applying hook on Template pattern)

Now, if you ask me about a good design pattern book to start with, I will not tell GOF book. For starter “Head First Design patterns” is cool. And when you learn a design pattern don’t forget to google them.