Nov 29

Somebody left a comment regarding to my Ruby Gotcha #1 post:

Since you posted this a while ago, you may have since learned of instance variables, which are preceeded by an ‘@’. If not, well here is the proper way to write your setter.

class Foo
  attr_accessor :bar
  def setNewBar=(newBar)
    @bar = newBar
  end
end

Whoever made this comment missed the point here. Yes, the above solution will work. But it’ll only work in this simple case. Whatever language you are using, it’s always a good OO practice to use accessor instead of instance variable directly. This is especially true in a language like Ruby where the instance variable is always private (although it’s very hard to demonstrate this behaviour). In our example, if you have a class that extends Foo, the subclass shouldn’t use ‘@’ to access the instance variable. Instead, it must use the attribute accessor. Then we will end up with the same problem. The correct way to deal with it is to preceed the attribute accessor with ’self’.

The more I learn Ruby the more interesting I find it is. These gotchas is also part of what makes it interesting. Watch out for more posts about them.

Nov 13

Jeff said:

“Note that each facade method has its own transaction. So if one of the task fails, it will just rollback itself, not the whole bundle.” I thought about this as well, but just assumed it had been addressed before. Maybe it hasn’t been brought up, though? I also wonder if this is one way we could get some good performance gains. If we could come up with a way of injecting one Unit of Work into multiple facade calls we could address the rollback issue, and possibly make things faster by not ditching our object caches after each facade method (transaction). For example, our battery oil process task bundle must make about 10 separate facade calls. Perhaps our workflow stuff should sit just below the facade instead of above it.

Yes, I heard that this problem is being dealt with using nested transaction supported by Toplink. But I think it might be an overkill for us. Do we really need nested transaction? Do we need to do partial commit/rollback? It doesn’t solve the duplicate lookup issue, either. It’s gonna be one more thing that ties the application to Toplink. So I like putting the workflow stuff behind the facade idea better. Actually, there is a class called InTransactionTaskBundle that does just that. It performs as same as any other TaskBundle except that it’s behind the facade and uses domain objects directly. I created this class and refactored a process bundle with about 10 tasks. The refactoring was straightforward and took only one or two hours.

Nov 07

Our project has the first release date set to be March of the next year. Currently, every team other than the one I’m in is in scenario testing or performance tuning mode. I’m not quite sure how things are going with them. But I myself can see a couple things that will bite us if they are not dealt with before or soon after the release.

Process bundle

Process bundle is a pattern we use to group tasks that need to be executed together and in order. It’s done as something like this:

class ProcessBundle {
  public void doTask() {
    FacadeFactory.getFacade().doTask1();
    FacadeFactory.getFacade().doTask2();
    .
    .
    .
  }
}

Note that each facade method has its own transaction. So if one of the task fails, it will just rollback itself, not the whole bundle. If some other process modifies the result of task 1 between the time task 1 finishes and task 2 starts, task 2 will have incorrect input. Since most of the tasks in a bundle use the same set of domain objects, we are also doing some duplicate lookup here.

Batch

So you develope a perfect, highly responsive web based enterprise application and release it to the client. What’s the first thing that’s gonna pop up? The client wants a batch process like the one they had in the good old mainframe system! That just throws the whole perfectionism away, doesn’t it? But you gotta face the reality. A batch process is even more important in a web environment. Say our application takes 5 minutes to process 100 wells. It’s not unusual for our client to process thousands of wells at a time. Being an optimistic person as I am, I say it’ll take half a hour to process those wells. Now you are facing a web browser or session timeout issue. What if somebody clicks the Back or Refresh button? Most of the enterprise level web applications will face the same problem. What do you do? Well, first you implement a job queue. Then you create a super responsive web page to monitor and maintain it.

That’s my thought. Welcome any comment.

preload preload preload