Showing posts with label try. Show all posts
Showing posts with label try. Show all posts

Thursday, May 7, 2015

Java with Try, Failure, and Success based computations


In this post I will try to borrow one of the Scala nice related computation models into the Java language.

It is about the Try/Success/Failure computation model implemented by the Scala libraries.

In Scala the Try type represents a computation that may either result in an exception, or return a successfully computed value.

More details could be found here:
http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.util.Try


In the following chunks of code I will not use any functional capabilities of the JDK 1.8.

The whole point is to be able to chain more computations which result could be either a success or a failure. At the first apparition of the failure in any of the computations the remained computations will not be applied anymore and the  failure will be propagated to the caller.

Please look at the following code snippet :

ComputationlResult<String> res = ComputationalTry.initComputation("1").bind(t0).bind(t1).getResult();

Here we pass an argument in our case the string "1" that will be processed one by one by the transformer "t0" and "t1".

We get the result of the chained computations stored in the "res" variable.

We can check if the chained computations were all successfully executed or if one of them failed. We can also extract the computed value or the cause of failure from the result.

Note also the "ITransformer" interface which presence here is needed when we do not use a functional approach.
Its only method "transform" is passed in the argument of generic type T and its function would be to apply a transformation on this argument and return the result.

Some would say that this is a monad based computation type. I wont go that far, so please regard this like a different way of chaining computations.

If you want a nice description of a monad which by the way is a simple structure and it should not be that hard to be comprehended  please watch the first lectures given by Martin Odersky on Coursera.

[It might be just a coincidence, but for some reason after Martin's lecture on monads it seems that some light was shed on this topic]

Here is the link:  Principles of Reactive Programming


And here is the whole code:

       

public class ComputationalTry<T> { 

  final private ComputationlResult<T> result;
 
 static public <P> ComputationalTry<P> initComputation(P argument)
 {
  return new ComputationalTry<P>(argument);
 }
 
 private ComputationalTry(T param)
 {
  this.result = new ComputationalSuccess<T>(param);
 }
 
 private ComputationalTry(ComputationlResult<T> result)
 {
  this.result= result;
 } 
 
 private ComputationlResult<T> applyTransformer(T t, ITransformer<T> transformer) {
  try
  {
   return new ComputationalSuccess<T>(transformer.transform(t));
  }
  catch (Exception throwable)
  {
   return new ComputationalFailure<T, Exception>(throwable);
  }
 }
 
 public ComputationalTry<T> bind(ITransformer<T> transformer)
 {  
  if (result.isSuccess())
  {
   ComputationlResult<T> resultAfterTransf = this.applyTransformer(result.getResult(), transformer);   
   return new ComputationalTry<T>(resultAfterTransf);
  }
  else
  {   
   return new ComputationalTry<T>(result);
  }
 } 
 
 public ComputationlResult<T> getResult()
 {
  return this.result;
 }
}


public class ComputationalFailure<T, E extends Throwable> implements ComputationlResult<T> {
 
 public ComputationalFailure(E exception)
 {
  this.exception = exception;
 }

  final private E exception;
 
 @Override
 public T getResult() {
  return null;
 }

  @Override
 public E getError() {
  return exception;
 }

  @Override
 public boolean isSuccess() {
  return false;
 }
 
}


public class ComputationalSuccess<T> implements ComputationlResult<T> {
 
 public ComputationalSuccess(T result)
 {
  this.result = result;
 }
 
 final private T result;

  @Override
 public T getResult() {
  return result;
 }

  @Override
 public Throwable getError() {
  return null;
 }
 
 @Override
 public boolean isSuccess() {
  return true;
 }
}


public interface ComputationlResult<T> {
 
 T getResult();
 
 <E extends Throwable> E getError();
 
 boolean isSuccess();
 
}


public interface ITransformer<T> {
 
 public T transform(T t);
 
}


public class Test {

 public static void main(String[] args) {
  
  ITransformer<String> t0 = new ITransformer<String>() {
   @Override
   public String transform(String t) {
    //return t + t;
    throw new RuntimeException("some exception 1");    
   }
  };

  ITransformer<String> t1 = new ITransformer<String>() {
   @Override
   public String transform(String t) {
    return "<" + t + ">";
    //throw new RuntimeException("some exception 2");
   }
  };
  
  ComputationlResult<String> res = ComputationalTry.initComputation("1").bind(t0).bind(t1).getResult();
  
  System.out.println(res);
  
  if (res.isSuccess())
  {
   System.out.println(res.getResult());
  }
  else
  {
   System.out.println(res.getError());
  }
 }
}
       
 
Thank you for bearing with me. Any suggestions are much appreciated.

Tuesday, November 5, 2013

Scala Actors. Handling messages using Try, Success, Failure

In this short post I will try to show a general method that could be used to handle actor messages. I want to also mention that this is not specifically related to actor supervision or other Akka actor advanced topics.

Let's say that we have an actor that is supposed to receive some events.

We want that this actor to be able to handle the received events in a generic way, so it should catch the exceptions occurring inside the actual handlers and it should also know to handle them accordingly.

I will provide you with a possible implementation that is using the Try Scala type.
More information about it can be found here:
http://www.scala-lang.org/api/current/index.html#scala.util.Try

First, we should introduce a class hierarchy for the types of events our actor is going to receive, send back to its senders, or forward to other actors:

  1. Msg any event received by our actor should extend this class
  2. ResponseMsg - any response sent by the actor back or forwarded to another actor should also extend this event
  3. SuccessMsg, FailureMsg - these are the messages used to wrap the results in case of a successful or a failed execution that might happen inside our actor event handlers

abstract class Msg
abstract class ResponseMsg
abstract class SuccessMsg extends ResponseMsg
abstract class FailureMsg extends ResponseMsg

Now, I will define the actual GenericActorHandler trait:

import akka.actor.{ Actor, ActorRef, ActorSystem, Props }
import scala.util.{ Try, Success, Failure }
trait GenericActorHandler extends Actor {
  def handleTryWithReply[S <: SuccessMsg, F <: FailureMsg](fun: => Try[S], createFailureMsg: Throwable => F): Unit = {
    fun match {
      case Success(successResp) =>
        sender ! successResp
      case Failure(e) =>
        sender ! createFailureMsg(e)
    }
  }
  def handleTryWithForward[M <: Msg, F <: FailureMsg](fun: => Try[(ActorRef, M)], createFailureMsg: Throwable => F): Unit = {
    fun match {
      case Success(actorMsgTuple) =>
        actorMsgTuple._1 forward actorMsgTuple._2
      case Failure(e) =>
        
actorMsgTuple._1 forward createFailureMsg(e)
    }
  }
}


Here is an example of an actor that mixes in the GenericActorHandler actor:

import akka.actor.{ActorRef, Props }
import scala.util.{ Try, Success, Failure }

class CalculatorActor extends GenericHandlerActor {
  def receive = {
    case evt: AddEvt =>
      handleTryWithReply(handleAddEvt(evt), ex => FailureAddEvt(ex.getMessage))
    case evt: DivideEvt =>
      handleTryWithReply(handleDivideEvt(evt), ex => FailureDivideEvt(ex.getMessage))
  }

  private def handleAddEvt(evt: AddEvt ): Try[SuccessAddEvt] =
    Try {
      SuccessAddEvt( evt.a + evt.b)
    }

  private def handleDivideEvt(evt: DivideEvt ): Try[SuccessDivideEvt] =
    Try {
     SuccessDivideEvt(evt.a / evt.b)
    }

and here are the events or messages our calculator actor is handling:

case class AddEvt (a: Int, b: Int) extends Msg
case class SuccessAddEvt(result: Int) extends SuccessMsg
case class FailureAddEvt(reason: String) extends FailureMsg 

case class DivideEvt (a: Int, b: Int) extends Msg
case class SuccessDivideEvt(result: Int) extends SuccessMsg
case class FailureDivideEvt(reason: String) extends FailureMsg
Assuming, that we send DivideEvt(10, 0) to our actor. This event  will be handled by handleDivideEvt. In this case its computation will fail when trying to divide by 0.
The actor will still be able to send back to its sender the exception wrapped inside the FailureDivideEvt response.