21 November 2013

Digging into EHCache (and TTL)

Using a caching frameworks (like Grails Cache and Grails EhCache) instead of writing the caching mechanism yourself is comfortable. You find yourself smacking @Cacheable on listing operations and get methods - and CacheEvict on the CRUD operations. Right?

But this is extremely distant from the actual implementation - so I think it's a good idea to have a close look and confirm it works as you think.

So let's investigate, using 2 techniques achieving 3 goals.

Goals are:
1. Confirming Configuration run-time
2. Watching the Cache run-time
3. Confirming TTL timers in run-time
4. Unit testing

Techniques described:
1. JMX
2. Grails Console Plugin

First you need to verify that EhCache is JMX exposed. I have this in Bootstrap.groovy.

Then, fire up jConsole

Confirming configuration

EhCache works "great" without any configuration at all - and then runs purely on defaults - which can trick you to believe your system works as you configured.

So let's see that the configuration you intended are correct. We do this by browsing in jConsole to "net.sf.ehcache" -> "CacheConfiguration" and click the cache name.

I've now verified my cache TTL has the exact value 1800 seconds (aka 30 minutes), matches my config file. Meaning my config file works.

Watching the Cache run-time

Head over to CacheStatistics in jConsole, and watch for CacheHits and CacheMiss

CacheHit means the cache did its job and returned cached results instead of invoking the annotated method. CacheMiss means the method was invoked. A high number on CacheHits is probably a sign of a healthy set up.

Confirming TTL timers
This may seem uneccesary, but I wanted to look at how this worked, so I dug into it. I couldn't find the TTL timers exposed in JMX, so I dug into the runtime using Grails Console Plugin.

So grab the CacheManager, find your cache, and ask for ExpirationTime and Creation Time.

This code on Gist

As you see, there is a perfect 30 minutes between Expiration and Creation time. Perfect.

Now sit back and wait until the ExpirationTime passes - and watch a new CacheMiss increasse in jConsole! If it does, everything is working as you intented.

Unit testing
This kind of configurations doesn't feel like a good fit for unit testing in my book. But maybe I'm wrong.


29 October 2013

Easier Killing

Who are you?

"I take the long road" -guy (this has been me for years and years)

  1. ps -ax | grep <something describing my process>
  2. look for the <pid>
  3. type kill -s 9 <pid>

"I made a shortcut" -guy

Make a clever script which uses ps | grep output, cut, awk or whatever to get the pid for the kill.

"I use the existing shortcut" -guy

pkill -9 -f  <something describing my process>

or pgrep first if I'm insecure about the regex

16 October 2013

Mocking grailsApplication

You don't have to mock grailsApplication, unless you've put yourself  in the same boat as me and like writing pure jUnit. Keep running grails test-app all the time is just annoying and slow. Note I havent tested Grails 2.3 yet, which is supposed to be faster than the predecessors.

Anyway. This "pure" approach has one downside: your service/controller aren't getting its dependencies injected for free. You have to do everything yourself.

Injecting services is easy, as you just @grails.test.mixin.Mock them in during setUp(). But there is that def grailsApplication sitting at the top of your file. How to best mock it so you don't get NullPointerException in your test? I (mostly) use grailsApplication for configuration, so there lies my need for mocking.

There are several ways of getting this done and I have two ways which I use. I can't decide on a favorite. Here they are, I'll let you decide what you like:

nested maps

public void setUp() {
  service = MyService() //service is a global variable for the entire test.
  service.grailsApplication = [config:[myApp:[jms:[firstQueue:"firstQueue"]]]]

This works best if you have really few properties. Maybe just one. But it's a one-liner, which I like.


public void setUp() {
  service = MyService()
  def mockConfig = new ConfigObject()
  service.grailsApplication = [config: mockConfig]

I know deep down that ConfigObject is the proper way of doing this - but it's more stuff to write.

Which do you like best?

14 October 2013

Groovy / Grails / GORM - File Name Too Long

Yet another "File Name Too Long" workaround :-(

Normal day - was just gonna add one more check to my nice .where{} closure. But when I did, everything blew up in my face - and I'm sitting here with no eyebrows.

The file will no longer compiles!

#grails test-app
/home/finn/src/stratos/stratos/target/classes/no/nsb/stratos/MyService$_updateAllWithChanges_closure5_closure7_closure8_closure9_closure10_closure12_closure14_closure16.class (File name too long)

When I commented back in the validTo everything went melt-down.

List gsmList = DistributionText.where {
  status.enabled==true &&
  status.ok==false &&
  status.validFrom <= new Date() && 

//status.validTo >= new Date() &&
  status.station != null &&
  channelCode=="FOO" &&
  language == "eng"

I can't figure out why this happens! The filename isn't over the Linux file length limit. 

I've seen this before when JSON marshalling really deep objects. (the workaroud then, was to create a map from intended object, and serialize the map instead)

So, what to do when you really don't understand the error in front of you? Escape! So I that's what I did - I rewrote to rewrote to Hibernate Criterion.

List<DistributionText> gsmList = DistributionText.createCriteria().list {
status {
  eq("enabled", true)
  eq("ok", false)
  le("validFrom", new Date())
  ge("validTo", new Date())
eq("channelCode", "FOO")
eq("language", "eng")

I kinda like better the Groovy DSL/where to this Hibernate syntax, so if you find out how to get around the File Name Too Long, please leave a comment.

16 April 2013

Unit testing potential thread leakage

So you've bewildered yourself into the dark world of pain threads, and you wanna make sure your app doesn't leak threads.

I found I had to calm my nerves by having tonnes of these Spock tests covering my Thread spawning.

I took my actual code, pasted it into this blog, stripped and rewrote it to cut straight to the point.

This silly service only illustrates the two methods for starting and stopping threads. This sample only spawns 1 thread but the point here are tests below.

To be sure your startJobs actually creates your thread(s), you should have a test confirming that first.

And here is the test looking for leakage:

The whole idea is finding the threads by your given thread name. And yes, i know Thread.sleep isn't ideal, and I may not need it, but it just feels reasonable to make sure the thread gets a little time to get going.

Side note: I learned that you have to cancel both the Timer and the TimerTask. If you only cancel the Timer, you'll have to wait for the GC to clean up the thread, and your test will fail.

26 March 2013

grails run-app and tomcat jmx

Want the standard Tomcat JMX exposed during development (grails run-app) ?

Add this to your Config.groovy:
grails.tomcat.jvmArgs=["-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.port=8099", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false"]

Fire up jconsole and hit localhost:8099.

</note to future self blog entry>

25 March 2013

Unit test your logging

I have a few log statements which are really important for me in production. Without them, I would be screwed when tracking whats actually going on. So I decided that this important code shouldn't be left out in the cold.

Here is a trivial example. Lets say the "Replacing address" log statement in the following code is really important when stuff hits the fan.

void setAddress(Address adr) {
  log.info "Replacing address ${this.address} with ${adr} on ${this}"
  this.address = adr
  log.debug "Updated{person} with new address"

def log = []
def collectLog = {String message -> log << message}
def finn = new Person(name:'finn', new Address(streetname:'homeless'))
finn.metaClass.log = [debug:collectLog, info:collectLog, error: collectLog]
finn.address = new Address(streetname:'Slottsplassen 1')
assert log.find {String msg -> msg.contains "Replacing address homeless with Slottsplassen 1 on Finn"}

The code turned out simpler than I feared when I initially decided I need to test my logging. Joy!

25 February 2013

When I say Jump, Jenkins asks how high

... if you want even faster feedback than waiting for Jenkins to poll your stuff

- In project config within Jenkins. Check: "Trigger builds remotely", add a token, like "foobar" into the textbox.

- SSH to your SVN-server and find the project home within svnroot.

- Here is my post-commit hook:
finn@subversionserver:/var/svnroot/myproject/hooks$ cat post-commit
/usr/bin/wget -O /dev/null --auth-no-challenge --http-user=finn --http-password=JENKINS_PASSWORD http://jenkinsserver:8080/view/Finn/job/myproject/build?token=foobar

If you don't have authentication on Jenkins, remove --http-user and --http-password

12 February 2013

uhm, there is a ~/.ssh/config file?

How did I miss this for all these years I've used ssh?

~/.ssh/config lets you type 
#ssh home
instead of
#finn@84.215.xxx.xxx -p 10001

Here is the ~/.ssh/config
Host home
HostName 84.215.xxx.xxx
Port 10001
User finn

Combine this passwordless ssh with
ssh-copy-id -i ~/.ssh/id_rsa.pub finn@84.215.xxx.xxx
and phoning home is pretty effortless.

... another one of those note-to-future-Finn (tm) posts which I'll copy and paste stuff from.

29 January 2013

HOWTO: Grails / GORM + Oracle Schema

By simply adding schema to your domain classes, you won't be able to get it working in h2 afterwards. Here is how you fix that.

1. Update all your domain classes

class Person {
        String name
static mapping = {
table name: 'PERSON', schema:"MYSCHEMA"

2. Update all your datasource

environments {
    development {
        dataSource {
            dbCreate = "create-drop"

repeat that for the test environment also.

Putting this in writing because I wish I had this blog post a while ago.

18 January 2013

Cheat sheet: ssh + screen + irssi

Cheat Sheet: SSH + IRSSI + SCREEN 

1. ssh user@myserver
2. screen -r  resumes your screen. screen starts a new one, then type irssi
3. /server irc.freenode.org to connect to the server. /join #channelName to join a channel
4. /wc leaves a channel.
5. <ctrl+a d> detaches screen, type exit to leave your ssh session