Friday, October 23, 2009

XWiki plugin on app engine

Using xwiki plugin in your grails application on app engine?
Then you'll need to delete core.jar from the deployment folder
‹app-name›/target/war/WEB-INF/lib

Wednesday, October 21, 2009

JVM Coldstart on Google App Engine

When your application sitting on app engine has been idling for a while, app engine tends to shutdown the jvm instance containing your app, presumably to conserve limited resources.

I find that a problem because getting the application initially started up can be a slow and expensive process.

But the problem can be solved with cron jobs that call a url in your application at set intervals, thereby keeping your jvm all nice and warmed up.

Check out the documentation on the site.

All you've got to do is:
create cron.xml and place it in your WEB-INF folder


<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/recache</url>
<description>Repopulate the cache every 2  minutes</description>

<schedule>every 2 minutes</schedule>
</cron>
<cron>
<url>/weeklyreport</url>
<description>Mail out a weekly report</description>
<schedule>every monday 08:30</schedule>
<timezone>America/New_York</timezone>
</cron>
</cronentries>

Tuesday, October 20, 2009

Slow Progress and issues

Progress has been a little slow lately,
a couple of hiccups to address:

  • Populating more than one cache during bootstrapping seems to overwrite the previous cache with the latter cache.
  • Google's url based security configured via google.appengine.security.requireLogin seems to remove parameters from url to redirect to target url.

Wednesday, October 7, 2009

JCache in App Engine and Grails

Caching is a great way to improve performance in any application, the less hits to the db for common tasks the greater the performance gain.

And here's how to do so in Java on Google's App Engine and Grails.

Google exposes their memcache caching system via the JCache interface

first of all you may wanna start with the javadocs here.

Since CacheManager is a singleton you can save some code by exposing it as a bean.
in resources.groovy:
cacheManager(javax.cache.CacheManager){
 it.factoryMethod = "getInstance"
}


Now you will need to initialize the cache, this has to be done only once so i do it in Bootstrap.groovy


class BootStrap {
 def cacheManager;
 def init = { servletContext ->
  CacheFactory cacheFactory = cacheManager.getCacheFactory();
  def cache = cacheFactory.createCache([:]);
  cacheManager.registerCache("cache",cache);
 }
}

See below for a practical example of using the cache:

class ForumController {
 def entityManager;
 def list = {
  def cache = cacheManager.getCache("cache")
  def forums;
  if(cache.get("allForums")){
   forums = cache.get("allForums");
  }
  else{
   forums = //your code to get all forums
   //please note the collect enclosure.
   cache.put("allForums",forums.collect{it});
  }
  ["forums":forums]
 }
}



One small caveat, you can store a collection of objects in the cache but it will need to be a ArrayList, so:
cache.put("allForums",Forum.list())
will not work, you will have to do
cache.put("allForums",Forum.list().collect{it})

Thursday, October 1, 2009

Exposing google UserService as a bean in Grails

Here's a how to expose the google's com.google.appengine.api.users.UserService as a bean in your application.

In resources.groovy

beans = {
 userService(com.google.appengine.api.users.UserServiceFactory){
  it.factoryMethod = "getUserService"
 }
}

I use the service in a taglib to expose some useful methods as tags.


class GoogleUserTagLib {
    def userService;
   
    def isUserAdmin = {attrs, body ->
        try{
            if( userService.isUserAdmin() ){
                out << body();
            }
            else{
                out << "NOT ADMIN"
            }
        }
        catch(e){
            out << "";
        }
    }

    def isUserLoggedIn = {attrs, body ->
        try{
            if( userService.isUserLoggedIn() ){
                out << body();
            }
            else{
                out << "";
            }
        }
        catch(e){
            out << "";
        }
    }

    def isUserNotLoggedIn = {attrs, body ->
        try{
            if( !userService.isUserLoggedIn() ){
                out << body();
            }
            else{
                out << "";
            }
        }
        catch(e){
            out << "";
        }
    }

    def loginURL = {attrs, body ->
        def destinationURL = attrs.url;
        def authDomain = attrs.domain ?: null;
        def url = "";

        if(authDomain){
            url = userService.createLoginURL(destinationURL,authDomain);
        }
        else{
            url = userService.createLoginURL(destinationURL);
        }
        out << url;
    }

    def logoutURL = {attrs, body ->
        def destinationURL = attrs.url;
        def authDomain = attrs.authDomain;
        def url = "";

        if(authDomain){
            url = userService.createLogoutURL(destinationURL,authDomain);
        }
        else{
            url = userService.createLogoutURL(destinationURL);
        }
        out << url;
    }
}

so now you can do ‹g:isUserLoggedIn›YOU ARE LOGGED IN‹/g:isUserLoggedIn›