Grails Tip: Configuring Embedded Tomcat Instance Used in Development / Test Environments

To support quick development and testing cycles, Grails fires up an instance of embedded Tomcat at various times – say, when you do “run-app” or run the functional tests, etc.

Tomcat plugin of Grails is responsible for launching this embedded instance with the default configuration. There may come times, however, when you want to go beyond this default configuration and make specific changes – say, try different variations of the protocol it uses, play with its thread-pool settings, etc – standard Tomcat configuration that you can easily change in server.xml when you have a standalone server running.

So, how do you do it?

While the Tomcat plugin allows for some basic configuration changes through the BuildConfig script – like jvmArgs property (if you want to pass some JVM arguments), it doesn’t use / expose any server.xml, in which you can make your configuration changes. Instead what it does is that in the preStart() phase, it fires an event called ConfigureTomcat and passes it a org.apache.catalina.startup.Tomcat configuration instance that you can utilize.

You can now trap this event in your Grails application’s “scripts/_Events.groovy” script as shown below, and play with the configuration of the embedded Tomcat instance that Grails is going to fire-up.

eventConfigureTomcat = {tomcat ->
    def connector = new Connector("org.apache.coyote.http11.Http11NioProtocol")
    connector.port = System.getProperty("server.port", "8080").toInteger()
    connector.redirectPort = "8443"
    connector.protocol = "HTTP/1.1"
    connector.connectionTimeout = "20000"

    tomcat.connector = connector
    tomcat.service.addConnector connector

Cassandra Tip: How much time did that query take?

If you are using Hector library to access Cassandra DB, it’s really easy to find out how much time a mutation or read query took to get executed.

All mutation operations made through Mutator – whether single or batched – return a MutationResult object, that can provide you with the following information after the query is executed:

  • getExecutionTimeMicro() – time in microseconds it took to execute the query.
  • getHostUsed() – on which host in the Cassandra ring, the query was executed

Similary for read operations, all flavors of Query return a QueryResult object that again provides the same info as above.

Useful and consistent, isn’t it?