Saturday, February 20, 2010

Quartz Admin JSP

We use quartz for scheduling jobs on tomcat nodes, the job runs on a frequency rather then a set time so its helpful to know when is the next time the job will be fired and for testing purposes its good if we can fire the job manually instead of waiting for the trigger to happen as some jobs runs only once a day. I wrote this small JSP that exactly allows to do the same.

Here is the sample code for jsp for googlers like me
<%@page import="org.quartz.ee.servlet.QuartzInitializerServlet" %>
<%@page import="org.quartz.impl.StdSchedulerFactory" %>
<%@page import="org.quartz.*" %>
<%@page import="java.util.*" %>
<%
    String jobNameToRun=request.getParameter("jobNameToRun");
    String groupNameToRun=request.getParameter("groupNameToRun");
    String btnTrigger=request.getParameter("btnTrigger");
    StdSchedulerFactory factory = (StdSchedulerFactory)  pageContext.getServletContext().getAttribute(QuartzInitializerServlet.QUARTZ_FACTORY_KEY);
    Scheduler scheduler = factory.getScheduler();
    if("Trigger Now".equals(btnTrigger)) {
         scheduler.triggerJob(jobNameToRun, groupNameToRun);
%>
    Job <%=jobNameToRun%> triggered.<BR>
<%
    }

    for(String groupName : scheduler.getJobGroupNames()) {
%>
    <p>GroupName:<%=groupName%></p><br>
    <table border="1">
    <tr><td><b>JobName</b></td><td><b>Next Fire Time</b></td><td>&nbsp;</td></tr>
<%
        for(String jobName : scheduler.getJobNames(groupName)) {
            Trigger[] triggers = scheduler.getTriggersOfJob(jobName, groupName);
            Date nextFireTime = triggers[0].getNextFireTime();
%>      
        <tr><td><%=jobName%></td><td><%=nextFireTime%></td><td><form><input type="hidden" name="groupNameToRun" value="<%=groupName%>"/><input type="hidden" name="jobNameToRun" value="<%=jobName%>"/><input type="submit" name="btnTrigger" value="Trigger Now"/></form></tr>
<%      }
%>
    </table>
<%
    }
%>

Friday, February 19, 2010

Logging DWR method parameters

just set org.directwebremoting=debug in log4j.xml and you should see all parameters like shown below.

 DEBUG 2010-02-19 19:41:45,981 http-4280-Processor69 org.directwebremoting.dwrp.BaseCallMarshaller - Environment:  c0-e10=boolean:false, c0-e11=string:true, c0-e12=boolean:true, c0-e13=string:8, c0-e14=boolean:false, c0-e1=boolean:true, c0-e15=boolean:false, c0-e2=boolean:true, c0-e16=string:5, c0-e3=string:https%3A%2F%2Fkp.foo.com, c0-e4=string:5, c0-e6=boolean:true, c0-e5=boolean:false, c0-e8=boolean:true, c0-e7=string:true, c0-e9=string:8,

Monday, February 8, 2010

Firefox3 and Caching HTTPS content

We use HTTPS for our website because it caters to data for SMBs, I primarily use Firefox browser and it was not caching static content. I was ignorant because when I googled for caching HTTPS content I found various posts that told that content over HTTPS cant be cached. Surprising thing was that IE8 was caching the content and as I dont use IE much I didn't noticed it. Luckily I started used JAWR for DWR JS aggregation and recently I added ExtJS and prototype to it. Surprisingly after doing it the initial load became fast by 1-2 sec and I was surprised. Upon firing up Fiddler I was surprised to see that Firefox is not even making call for the aggregated JS. Ultimately I figured out that it was Cache-Control:Public header that was making all the difference. JAWR was setting Cache-Control: public, max-age=315360000, post-check=315360000, pre-check=315360000 and we were setting Cache-Control:Private, max-age=315360000. That's it done!! we changed the headers and now Initial load on second login is fast even after you close the browser.  When Cache-Control is private Firefox uses memory based caching and when Cache-Control is public Firefox uses disk based caching for HTTPS based content. You can type url about:cache to confirm this.

fyi this doesn't mean we don't need to focus on removing the no of http requests any more or looking for a CDN solution because according to a study by Yahoo surprisingly 40-60% requests are done from an empty cache. http://www.yuiblog.com/blog/2007/01/04/performance-research-part-2/. It just buys us some more time to automate some of the things like sprite creation and others in meanwhile.

AtomicInteger

Found this interesting class AtomicInteger that allows you to access primitives in a highly concurrent environment. I ran into an issue when I had to implement a throttling filter to allow only certain no of request in the app for a particular functionality to guarantee a certain level of QOS, my earlier code was

public class BackupThrottlingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            activeBackupRequests ++;
            if(activeBackupRequests > 50) {
                BackupFileUploadServlet.sendServiceUnavailableResponse((HttpServletResponse) response);
                return;
            }
            chain.doFilter(request, response);
        }
        finally {
            activeBackupRequests--;
        }
    }
    private static int activeBackupRequests;
}

Ran into an issue with this as its not synchronized so I had an option to use volatile or synchronized ,but synchronized is a killer as it would block but then I read about the new AtomicInteger class that allows you to abstract all this and allow highly concurrent operations on primitives


public class BackupThrottlingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            activeBackupRequests.incrementAndGet();
            if (activeBackupRequests.get() > 50) {
                BackupFileUploadServlet.sendServiceUnavailableResponse((HttpServletResponse) response);
                return;
            }
            chain.doFilter(request, response);
        } finally {
            activeBackupRequests.decrementAndGet();
        }
    }
    private static AtomicInteger activeBackupRequests = new AtomicInteger(0);
}

Tuesday, February 2, 2010

Should I use CDN or not?

I was doing some comparison of home page loading of my company's website and one competitor's homepage loading. The competitor website loads in a snap and ours take some secs before it shows up. Here are some of the stats from YSlow for mine and competitor's site.










Now as I can see that competitor is making more images/JS then my company's site but it loads in a snap. I can notice three differences
  1. They are using a CDN so images are being downloaded from a local server near Dallas
  2. Their total download size for Java scripts and image are 1/3 then ours.
  3. ours is HTTPS and their site is HTTP. We can't change to HTTP as we cater to SMB and security transmission is a key for us.
I am working with the team to reduce the size of Javascript download and cut it by half. Earlier we were using YUI for tree and ExtJS for table. We recently moved to ExtJS tree as it performs much better then YUI in IE and when you have large no of  children nodes. There are few remaining pieces of code that still rely on YUI so removing them will cut the size of JS download by half. The size of images are also double the size of competitor mainly because our website has went through so many revisions that the sprites are becoming Fatty and we are not removing unused images out of those, plus some stupid decisions by developers to create a new sprite with common images has also caused issues. I had already tried smushing images and got the maximum juice out of them I guess I will have to go through a big cleanup.

But in the interim I am in dilemma to use CDN or not? Even locally within the intranet the home page load is sluggish so it has to be the size of download. Will try to reduce the size of download and see the timings?  If I can match the competitor's Kilobytes downloaded then I can think of using the CDN or not.