Sunday, October 24, 2010

Scala exercise 4: circuit breaker pattern

Introduction


This is the fourth exercise in my Scala exercises series. If you haven’t seen it before, you may want to start from exercise 1: template method, exercise 2: observer design pattern and exercise 3: decorator and composite design patterns. Below is exercise 4: circuit breaker pattern.
Problem: Create a console program that reads commands from the user. If the command is "q", it will query a hard-coded URL (e.g., http://localhost:1234) and print the result to the console. If the command is "x", it will exit. Below is a sample session:
Enter: q
Hello <-- this is the content at the URL
Enter: q
Hello <-- ditto
Enter: x
Exiting

In practice, if the remote server is overloaded, out of order or the firewall is mis-configured, every time you try to access the URL, it may take up to several minutes for your client to timeout or receive an error. It would also place unnecessary load on that server which possibly is already overloaded. Therefore, a better way to do it is, if the server returns an error (or does that for a consecutive number of times), your client will not try to access it anymore (treat it as an error immediately), until the administrator resets it. This is called the "circuit breaker" pattern.
Now, your task is to implement this behavior by filling in the code below. There is also a new command "r" to reset the circuit breaker. For simplicity, you'll stop calling the server as long as one exception is caught.


//it extends the CircuitBreaker trait to obtain the functionality. Unit is the return
//type of the code block to be protected by the circuit breaker.
object HttpClient extends CircuitBreaker[Unit] {
def main(args: Array[String]) {
while (true) {
print("Enter: ")
try {
readLine match {
case "q" => queryHttpServer
case "r" => reset
case "x" => {
println("Exiting")
return
}
case _ => println("Unknown command")
}
} catch {
case e: Exception => e.printStackTrace
}
}
}

def queryHttpServer {
//run the code block in the protect() method
protect {
... //get the content at http://localhost:1234
}
}
}

trait CircuitBreaker[T] {
var isOpen = false

//run the code block only if the circuit breaker is not open. If it is,
//thrown an CircuitOpenException immediately.
def protect(codeBlock: ...): T = {
...
}

def reset {
println("Resetting the circuit")
isOpen = false
}
}

class CircuitOpenException extends Exception

In addition, for your own testing, you can create a simple HTTP server with netcat. Just run:
  echo -e "HTTP/1.0 200 OK\n\nHello\n" | nc -l 1234

It will quit after serving one request. So, you need to run it again to serve multiple requests.
Try to do it now! Then, click here to see the answer.

Saturday, October 16, 2010

Scala exercise 3: decorator and composite design patterns

Introduction


This is the third  exercise in my Scala exercises series. If you haven’t seen it before, you may want to start from exercise 1: template method and exercise 2: observer design pattern. Below is exercise 3: decorator and composite design patterns.
Problem: In most UI frameworks including JSF, Wicket or Swing, you will need to provide a callback/listener object to handle requests from the user. Typically in such a callback, if there are some errors, you'd like to display a specific error message instead of propagating it to the framework, otherwise the framework would simply display a generic error to the user.
To hand code such a callback, you may do it like:

new Callback() {
def onCallback(ev: Any) {
try {
//perform the business logic here
} catch {
case e: LoginException => {
//assuming that error() will display the error
error("failed to login")
}
case e: SQLException => {
error("error accessing the database")
}
}
}
}

The problem with this approach is that there is a lot of boilerplate code there, while most usually we only want to say for exception class E1, display some error message M1:

new ErrorHandlingCallback(
//classOf[Foo] is the same as Foo.class in Java
classOf[LoginException], "failed to login",
classOf[SQLException], "...") {
def performBusinessLogic(ev: Any) {
//perform the business logic here
}
}

But what if you'd like to extract some information from the exception and include it into the error message or would like to do something special? Then, ideally, you should be able to specify a function as the error handler:

new ErrorHandlingCallback(
classOf[LoginException], "failed to login",
classOf[SQLException], "...",
(e: Exception) => doSomething(e)) {
def performBusinessLogic(ev: Any) {
//perform the business logic here
}
}

Finally, you should be able to pre-define an object to handle the commonly seen exceptions:

//ideally you should be able to "add" the error
//handlers together to get a compound error
//handler
val defaultErrorHandler =
(classOf[IOException], "I/O error") +
(classOf[Exception], "Unknown catch all error")

new ErrorHandlingCallback(
classOf[LoginException], "failed to login",
...,
defaultErrorHandler) {
def performBusinessLogic(ev: Any) {
//perform the business logic here
}
}

Your task is to complete the code below and create the other necessary classes as needed:

trait Callback {
def onCallback(ev: Any)
}

abstract class ErrorHandlingCallback(errorHandler: ErrorHandler) extends Callback {
//overload the constructor to take multiple error handlers (the star does that)
def this(errorHandlers: ErrorHandler*) = ...

def performBusinessLogic(ev: Any)

def onCallback(ev: Any) {
...
}
}

object ErrorHandlerUtil {
//allow you to use a function as an error handler
implicit def fromFunc(f: Exception => Boolean): ErrorHandler = ...
//allow you to use a pair (error class, error message) as an error handler
implicit def fromPair(p: (Class[_ <: Exception], String)): ErrorHandler = ...
}

Then, the following code should compile and run:

object ErrorHandlerTest {
//in order to use the implicit conversion methods, you
//must import these objects so that those methods can
//be invoked without a prefix.
import ErrorHandlerUtil._

def main(args: Array[String]) {
//assume that this is the default error handler in this context
//classOf[Foo] is the same as Foo.class in Java
val defaultErrorHandler = (classOf[IOException], "I/O error") + (classOf[Exception], "Unknown catch all error")
//create a decorator to handle additional errors
val decorator = new ErrorHandlingCallback(
//convert a pair to an error handler
(classOf[IndexOutOfBoundsException], "index out of bound"),
//ditto
(classOf[NullPointerException], "hit a null pointer"),
//you can define a custom error handler using a function to, say,
//access the info in the exception (not just its class).
(e: Exception) => if (e.getMessage.contains("xyz")) {
println(e.getMessage)
true //indicate that it has been handled
} else false,
//specify the default error handler here
defaultErrorHandler) {
def performBusinessLogic(ev: Any) {
println("called")
ev match {
//do nothing. No error.
case "foo" =>
//try to access the 100th element of an array which has only 3 elements
case "bar" => Array[Int](1, 2, 3).apply(100)
//Try to call a method on null
case "baz" => null.equals("oops!")
//throw a custom exception
case "baz2" => throw new RuntimeException("I am xyz!")
//divided by zero (something unexpected to test the ultimate fallback)
case "baz3" => 100 / 0
}
}
}
decorator.onCallback("foo")
decorator.onCallback("bar")
decorator.onCallback("baz")
decorator.onCallback("baz2")
decorator.onCallback("baz3")
}
}

Try to do it now! Then, click here to see the answer.

Sunday, October 10, 2010

Scala exercise 2: observer design pattern

Introduction


This is the second exercise in my Scala exercises series. If you haven't seen it before, you may want to start from exercise 1: template method. Below is exercise 2: observer design pattern.

Problem: Complete a Scala trait Observed (shown below) to represent the subject being observed and the Scala trait Observer to represent an observer. The Observed object allows one or more Observers to register with it. Later, it can fire an event and notify all such Observers. The code is like (where E is the type of the event to be fired):


trait Observed[E] {
def addObserver(o: Observer[E]) ...
def notifyObservers(ev: E) ...
}

trait Observer[E] {
def eventOccurred(ev: E)
}

Then use these traits to implement Java bean "bounded properties", e.g., to allow others to get notified when properties of a Book instance is changed:

//Let others observe changes to its properties
case class Book(var title: String, var price: Double) extends Observed[PropertyChangeEvent] {
def setTitle(title: String) {
val oldTitle = this.title
this.title = title
//Notify the observers
...
}
def setPrice(price: Double) {
val oldPrice = this.price
this.price = price
//Notify the observers
...
}
}

//A sample observer class
class Foo extends Observer[PropertyChangeEvent] {
//Just print some info after a property has been changed
def eventOccurred(ev: PropertyChangeEvent) = {
printf("Foo: %s of %s has changed from %s to %s\n", ev.getPropertyName, ev.getSource, ev.getOldValue, ev.getNewValue)
}
}

object BeanTest {
def main(args: Array[String]) {
val b1 = new Book("Scala programming", 35.95)
val foo = new Foo
b1.addObserver(foo) //Register the observer
b1.setTitle("Thinking in Scala")  //foo should get an event
b1.setPrice(39.95) //ditto
b1.setTitle("Effective Scala") //ditto
}
}

The above code should print:
Foo: title of Book(Thinking in Scala,35.95) has changed from Scala programming to Thinking in Scala
Foo: price of Book(Thinking in Scala,39.95) has changed from 35.95 to 39.95
Foo: title of Book(Effective Scala,39.95) has changed from Thinking in Scala to Effective Scala

Try to do it now! Then, click here to see the answer.

Saturday, October 2, 2010

Scala exercise 1: template method design pattern

Introduction


As part of my studying with Scala, I have tried to find some exercises to do but most are either too simple or too "academic". So, I decided to create a series of Scala exercises to implement the well known design patterns in an industrial context. Here is the first one: template method.

Problem: Create a Scala class JdbcTemplate that has two template methods: execute() and load(). They will execute a SQL statement and load the query results using JDBC respectively. The methods should open and close the connection, create and close the statement and etc. so that the caller doesn't need to worry about those. For example, the client could use your code like this:


object Test {
def main(args: Array[String]) {
Class.forName("org.h2.Driver")
val t = new JdbcTemplate
val ds = () => DriverManager.getConnection("jdbc:h2:~/test")
t.execute(ds, "drop table products if exists")
t.execute(ds, "create table products (id long primary key, name varchar(128))")
val insertSql = "insert into products values(?, ?)"
t.execute(ds, insertSql, List(100, "p1")) //the list is the parameters
t.execute(ds, insertSql, List(101, "p2")) //ditto
val ps = t.load[Product](ds, "select * from products", Nil,
{ //this function maps a record into an object
(rs) => new Product(rs.getLong("id"), rs.getString("name"))
})
println(ps)
}
}

//make it a case class so that it can be printed to the console nicely
case class Product(val id: Long, val name: String) {
}

To make it run, you need to include the h2 database into your classpath. If you use Maven, just add the following to pom.xml:


<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.143</version>
</dependency>

Note that I am not suggesting that you do this in production code; you'd probably want to use an ORM framework.

Click here to see the answer.