28th April 2008, 08:21 am
I spent last week entirely on one issue: CDV-244 (and it’s duplicate CDV-736, which someone raised recently on a forum). I got a lot of coding done, but ultimately did not yet fix the issue. This week I need to put that aside and do some performance testing, my team owes marketing some comparative testing between versions 2.5 and 2.6 of Terracotta. So, it was another frustrating week of not actually finishing anything.
The issue itself is interesting. Serializing an object in the L1 which is not fully faulted into memory can fail if the serialization uses sun.misc.Unsafe.getObject(Object, long), which is a native method and which bypasses all of our bytecode instrumentation magic. Our solution, which is becoming somewhat of a pattern with native methods, is twofold: (1) use instrumentation to create a new wrapper method within Unsafe, called __tc_getObject, which does all of the necessary resolution of the Object arg if it is clustered, and (2) instrument any and all instrumented code which calls the original native method to call this instead. (This is similar to the way we tackled String.intern(), another native method.)
Our product manager Taylor wrote a nice simple TIM which reproduced the issue. I took that and modified it so that I could step through using Eclipse’s debugger. I also came up with one of our automated system tests which currently fails, and which I hope will prove the fix works, once the fix is done. At this point I’ve got a fix that I think should work, but the boot jar tool complains about the boot jar being invalid during startup. I’ve decompiled and tested the instrumented copy of Unsafe from within the boot jar and it is fine, so I’m not yet sure what the problem is.
Friday was the last day for my teammate Antonio, who has accepted a job with NASA. We are extremely sorry to see him go. He has been on the team for some time, he knows a lot, and has done tons of great coding. He is very smart, works hard and is a nice guy. Good luck in space, Antonio!
21st April 2008, 10:06 pm
Last week I had the opportunity to use the Extract Method refactoring. I’m generally a proponent of this refactoring – I think it’s a worthy goal to have more numerous, shorter methods, if that means that any given method is more quickly understood at a glance.
The code I had, after I had made some further complicating modifications, looked something like this.
I didn’t like the nearly-duplicate logic duplicated in the if-else block. I felt there was an extract method in there somewhere. However, it took me three times before I came up with a solution I liked, which is basically this:
I won’t bore you with the first two tries, but I’ll just say that for some reason the use of the third defaultTo arg didn’t occur to me right away, but was just what I needed to make the method calls nice and clean.
After I looked at the finished product, I was reminded that another benefit of Extract Method is that differing levels of abstraction are separated. In this case, the determination of whether WebLogic or Tomcat is in use, and what delimiter and default to use to determine the web app name, is a sort of mid-level policy. The nuts and bolts of parsing that app name out of a String instance is the lowest level of abstraction and, in my opinion, is better off not inlined into the policy code. In a similar vein, we would not want to see the implementation of String.substring() inlined into every single invocation of that method.
I don’t think my finished product is perfect. I think maybe there’s a better method name that could be used, which communicates the intent better, because it’s not perfectly obvious at a glance why the delimiter and default need to be passed to the method and what happens. But then again that’s part of the point, we don’t want to know the details. Meanwhile, on the plus side, we see that the same method is invoked in both cases, and only the arguments differ, so it’s obvious that there’s a pattern there which wasn’t necessarily obvious before.
21st April 2008, 09:36 pm
This week is already underway, but here’s what was up last week.
Mostly I worked on this issue: http://jira.terracotta.org/jira/browse/CDV-569. The gist is that Terracotta Spring has a bug when you are running as the root web app inside Tomcat – it didn’t properly parse the application name, or in this case use the reserved ROOT app name. (When running TC Spring as the root web app, within your tc-config.xml file, you would want to use ROOT, in all caps, as your application name: .)
I’ve still got a lot to learn about Terracotta Spring integration. It’s particularly hard to debug, because clustering of Spring beans happens through aspects (using Aspectwerkz mixins).
Incidentally, here are three good links to information about Terracotta Spring support.
7th April 2008, 08:15 am
At work there can be more productive weeks, and there can be less productive weeks. Last week, for me, frustratingly, was a less productive week. It was a reminder that working on multiple things at once isn’t good if you don’t get any of them done.
Part of the reason is that we are simply in that post-code-freeze mode of fixing bugs, testing, doing spring cleaning, that sort of thing. By its very nature you tend to work on a lot of little things.
During the first part of the week, I tried to help debug a seg fault we were seeing in the vm when using the ibm jdk, but I got nowhere. One of my teammates was making some progress when it was decided that other issues were higher priority.
So I switched to bug fixing. The best progress I made all week was on this issue. I have the issue reproduced in a system test, but I’m stalled on a solution and am waiting to talk it over with my team. It’s an interesting question – how should we handle read-only style methods (like Calendar.get()) which, counterintuitively, modify the internal state of the instance? In theory you should be able to use a mutable but safely-published instance in multiple threads without any synchronization, if it’s state is never changed. But, Terracotta throws a runtime exception if an attempt is made to change the state of a clustered object outside of a lock, even if that change is unexpected such as in the case of Calendar.get().
I then switched to this issue, which has to do with Terracotta integration with Spring. I’ve got the problem reproduced in a unit test, but once again I’m not entirely sure what the solution should be, so this morning I’m looking to fire up Spring and Terracotta for real and play around with various patches.
I did do my first phone-screen for Terracotta this week. I talked to a QA Engineering candidate. (Terracotta is hiring).
Here’s hoping for a more productive week this week…