Archive for August, 2006
DWR Call batching
To reduce load on my current project I had a look into reducing the number of requests fired at the application server. Many pages in the application trigger multiple DWR calls resulting in Tomcat generating heavy load on the servers.
One of the sollutions I came up with is batching DWR calls, which reduces the number of calls by combining multiple calls into single requests.
Simply start and end a batch and DWR handles it all! For example:
-
function batchThreeCalls(){
-
DWREngine.beginBatch();
-
testbean.getOne(doOne);
-
testbean.getTwo(doTwo);
-
testbean.getThree(doThree);
-
DWREngine.endBatch();
-
}
Results in a single call, and a single response which is routed to the correct callbacks by DWR:
request
-
callCount=3
-
warningHandler=null
-
httpSessionId=EA9C0891376DE06E977B26CD729E59C8
-
scriptSessionId=B206674DE4A43F7E497882E9E3723F3D
-
page=/JRubyController/dwrtest.html
-
c0-scriptName=testbean
-
c0-methodName=getOne
-
c0-id=158_1156968086615
-
c1-scriptName=testbean
-
c1-methodName=getTwo
-
c1-id=1425_1156968086615
-
c2-scriptName=testbean
-
c2-methodName=getThree
-
c2-id=3057_1156968086615
response
-
//#DWR-START#
-
DWREngine._handleResponse('158_1156968086615', "1");
-
//#DWR-END#
-
//#DWR-START#
-
DWREngine._handleResponse('1425_1156968086615', "2");
-
//#DWR-END#
-
//#DWR-START#
-
DWREngine._handleResponse('3057_1156968086615', "3");
-
//#DWR-END#
More one batching can be found on the DWR site.
5 commentsJavascript compression filter
Yesterday a colleague asked me whether it is possible to automate compression of javascript code in a web application (the current project has a total of about 150kb of javascript for some of the pages). I decided to look into the issue a bit...
There are tons of offline javascript compressors/obfuscators etc. but the ones using Rhino seem to be among the best. This is mostly due to the fact that Rhino can fully interpret the code and decide whether, for instance, variables are local or not. Another good feature of Rhino is the fact that it is java based. The Dojo toolkit offers a patched version of the Rhino library which can be used safely to compres javascript offline.
I couldn't find inline (filter based) compressors... so I decided to wrap the Dojo Rhino version in a filter. Took some work to figure out how Rhino is used, but I managed to get everything to work.
Instead of pasting code here I decided to install a subversion repository, it is browseable through the web from the following URL:
http://svn.maas-frensch.com/pmutils/javascript_compressor_filter/trunk/
The project contains a minimal webapp demonstrating the use of the filter, a simple build file (be sure to configure your tomcat base-dir for compiling) and can be checked out anonymously.
If you just want to use the filter download the following files and put them in your WEB-INF/lib folder (compiled for java5!):
and add the following lines to your web.xml descriptor:
<filter> <filter-name>javascript compressor</filter-name> <filter-class>com.finalist.web.filters.JavascriptCompressorFilter</filter-class> </filter> <filter-mapping> <filter-name>javascript compressor</filter-name> <url-pattern>*.js</url-pattern> </filter-mapping>
I've tested the filter on my current, Javascript heavy project and it manages to reduce the filesizes by about 50%.. and they still work! Also it's now safe to fully document 'unwanted' but known behaviour of javascripts without the risk of accidenlty exposing it to external users.
The following example illustrates the working of the filter:
input
/** * called when the window is finished loading * registers hanlers to each 'anchor' with classname 'button' */ window.onload = function(){ var anchor = document.getElementsByTagName('A'); for(var i in anchor){ if(anchor[i].className == 'button'){ // if A has class button, register event handlers anchor[i].onmouseover = over; anchor[i].onmouseout = out; preload(anchor[i]); // preload images anchor[i].style.backgroundImage = "url('"+anchor[i].getAttribute('out')+"')"; // set default image } } }
output:
window.onload=function(){ var _1=document.getElementsByTagName("A"); for(var i in _1){ if(_1[i].className=="button"){ _1[i].onmouseover=over; _1[i].onmouseout=out; preload(_1[i]); _1[i].style.backgroundImage="url('"+_1[i].getAttribute("out")+"')"; } } };
After writing the filter I discovered DWR has some java based compression utilities as well; and it is allready on the project classpath. Maybe I'll expand the filter with configuration options for selecting the compressor to use.
2 commentsCX-310-055 (2)
Today the mailman brought me a big brown envelope containing my official, signed certificate... Although Danielle thinks Sun could have done a better job on the quality (it looks like a simple inktjet printout) I'm still proud of it; and since I haven't got other news to post, here it is!
2 comments
Rails update…
The small Rails app which I wrote for my wife broke down completely just after the installation of the new version of Rails (the 'mandatory' 1.1.5 and 1.1.6) by Dreamhost.
Couldn't get it to work at all, and no sensible logging info was produced...
At the end (took me about four hours) it started to work again, and I actually don't know which of the following actions actually helped:
- create a new Rails app using the rails version of the server, copy application files into the project
- setup FastCGI again
- start webbrick to see stuff working without fcgi (it actually worked)
- write a message to the helpdesk
- remove all temp files (like sessions, damn a LOT of sessions...)
- execute the dispatcher script using a CLI again, no errors...
- changed the she-bang line to reflect the first line of the script for starting webbrick (which worked), executed the script again... still no errors
- re-configure fcgi
Somehow this, or one of those, solved my problem...!? Being a java programmer I'm not really used to this sort of voodoo... (well o.k. I have used WebLogic as wel) ... Is there something I should read which could enlighten me in understanding what happened?
No commentsMajor security flaw in Rails?
Just after writing my previous post I noticed the following post on one of my incoming RSS feeds:
Rails 1.1.5: Mandatory security patch (and more)
From the article:
This is a MANDATORY upgrade for anyone not running on a very recent edge (which isn’t affected by this). If you have a public Rails site, you MUST upgrade to Rails 1.1.5. The security issue is severe and you do not want to be caught unpatched.
Wow... doesn't sound nice at all... lets hope dreamhost.com updates my rails version ASAP!
No commentsSpring MVC and JRuby controllers
While going through some Spring 2.0 documentation on using dynamic languages in combination with Spring I noticed an example of a Spring MVC controller written in Groovy. I fiddled arround with it a bit, the refreshable bean feature makes it really cool... now I can edit my controllers in a running application server!
Since I like Ruby I decided to combine to documentation on using JRuby and the Groovy controller example.
First, I created this ultra simple controller:
-
require 'java'
-
-
include_class 'org.springframework.web.servlet.ModelAndView'
-
include_class 'org.springframework.web.servlet.mvc.Controller'
-
-
class MyController <Controller
-
def handleRequest(request, response)
-
puts "I'm in Ruby"
-
mav = ModelAndView.new @@resultView
-
mav.addObject("key","value")
-
-
return mav
-
end
-
-
def setResultView(resultView)
-
@@resultView = resultView
-
end
-
-
def toString
-
return "MyController in Ruby"
-
end
-
end
-
-
# needed by spring
-
MyController.new
The setResultView method (l. 15) will be called from Spring (IOC) to configure to resulting view for this controller. As you can see the controller class inherits Spring MVC's Controller interface (yes, I know inheriting an interface might sound a bit strange... but Ruby doesn't actually use the interface concept). I had to implement the toString method to get rid of some nasty error messages complaining about it.
For people less familiar with Spring MVC, the ModelAndView object contains the name of the target view AND the model to be rendered in this view. The objects added by the addObject call will be exposed to the view renderer (i.e. jsp, xslt, velocity, freemarker).
The controller can be configured in the Spring MVC dispatcher xml like this:
-
<lang:jruby id="myController" refresh-check-delay="3000"
-
script-source="/WEB-INF/Ruby/MyController.rb"
-
script-interfaces="org.springframework.web.servlet.mvc.Controller">
-
<lang:property name="resultView" value="view" />
-
</lang:jruby>
Notice the Spring 2 use of namespaces, and the refresh-check-delay attribute which defines the interval in which the script file is checked for modifications. Also, as you can see we use Spring to set the 'resultView' property.
Throw in some url handler mappings and a JSP and there we go! Sweet!
At the moment I don't have a specific case for using Ruby to write spring controllers, but I really like the fact that it is actually possible!
If you want to experiment:
4 commentsInsects
I managed to get some insects to smile at my camera just long enough to get their portrets taken:
No commentsSun Certified Programmer for Java 5
Today I passed the CX310-055 exam, which means as much as:
I am a 'Sun Certified Programmer for the Java 2 SE Platform, Standard Edition 5.0'
I scored a wopping 90% (59% required)! yeah!
5 commentsDrip
While trying to relax for the upcomming exam today I took the camera out in the morning sun to take some close-ups. I think this one worked out particularly well:
No commentsEOS350D – New header
Today the Canon EOS350D we ordered arrived. During the day Danielle mailed me some nice shots she made while experimenting... soon Sjoerd's weblog will be packed with hi-res 8 megapixel SLR pictures
But after dinner I had a go, and took a couple of shots of my espresso machine. I think some of them worked out pretty well:
The new header is cropped from the first image!
BTW, I upgraded my lightbox install (the fancy image overlay) to v2. Now you can hoover over the image to get a 'next' and 'previous' button
No comments