Wednesday, 26 April 2017

Thread Pools

Java [Thread Pool] [Executor]: Manages pool of worker threads + contains a [queue] that keeps tasks waiting to get executed.

1) We add [Runnable] tasks to queue. From there, executor picks one task and assign to worker thread which is free.
2) Java.util.concurrent.Executor(interface) --> Java.util.concurrent.Executors(implementation).
   We use this implementation to create thread pool in java.


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimpleThreadPool
{
public static void main(String args[])
{
//Worker threads are five
// Executor(main interface) --> ExecutorService (impl) --> ThreadPoolExecutor;
ExecutorService executor = Executors.newFixedThreadPool(5);
//But submitting 10. so 5 tasks will end up in queue untill worker threads are free
//Task assignment will be taken care by pool.
for(int i=0;i<10;i++)
{
//Submitting runnable tasks
Runnable runnable = new WorkerThread(""+i);
// There is a submit method to get future object. async mode. can be used when u required to read results.
executor.execute(runnable);
}
//java app  will never end untill non-deamon threads are terminated.

executor.shutdown();
//Blocking main thread untill pool terminates.
while(!executor.isTerminated())
{

}
System.out.println("Finished all threads");
}
}


public class WorkerThread implements Runnable
{
  String command;

  WorkerThread(String command)
  {
    this.command = command;
  }

  @Override
  public void run()
  {
  System.out.println(Thread.currentThread().getName()+" Start. command = "+command);
  processCommand();
  System.out.println(Thread.currentThread().getName()+" End.");
  }
 
  private void processCommand()
  {
    try
    {
    Thread.sleep(1000);
    }
    catch(InterruptedException e)
    {
    e.printStackTrace();
    }
  }

  @Override
  public String toString()
  {
    return this.command;
  }
}

Output:
*************************************
pool-1-thread-2 Start. command = 1
pool-1-thread-5 Start. command = 4
pool-1-thread-3 Start. command = 2
pool-1-thread-4 Start. command = 3
pool-1-thread-1 Start. command = 0
pool-1-thread-1 End.
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-2 End.
pool-1-thread-4 End.
pool-1-thread-2 Start. command = 8
pool-1-thread-3 Start. command = 7
pool-1-thread-5 Start. command = 6
pool-1-thread-1 Start. command = 5
pool-1-thread-4 Start. command = 9
pool-1-thread-4 End.
pool-1-thread-2 End.
pool-1-thread-3 End.
pool-1-thread-1 End.
pool-1-thread-5 End.
Finished all threads

***************************************************************************************************************


1) ThreadPoolExecutor is more powerful than executors.
2) With threadpoolexecutor, we can provide min no.of threads to be alive,max no.of threads in pool at any given time, and RejectedExecutionHandler to handle jobs which can not fit into queue.


import java.util.concurrent.ThreadPoolExecutor;

public class MyMonitorThread implements Runnable
{
ThreadPoolExecutor executor;
private boolean run = true;
private int seconds;

    MyMonitorThread(ThreadPoolExecutor executor,int delay)
    {
      this.executor = executor;
      this.seconds = delay;
    }

    public void shutdown()
    {
    run = false;
    }

@Override
public void run()
{
       while(run)
       {
        System.out.println(String.format("[monitor] [%d/%d] Active: %d, Completed: %d,Task: %d,isShutdown: %s, isTerminated: %s",
        executor.getPoolSize(),executor.getCorePoolSize(),executor.getActiveCount(),executor.getCompletedTaskCount(),
        executor.getTaskCount(),executor.isShutdown(),executor.isTerminated()));

        try
        {
        Thread.sleep(seconds*1000);
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }
       }
}
}

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler
{
@Override
public void rejectedExecution(Runnable r,ThreadPoolExecutor executor)
{
       System.out.println(r.toString()+" is rejected.");
}
}

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class WorkerPool
{
public static void main(String args[]) throws InterruptedException
{
RejectedExecutionHandlerImpl rejectedExecutionHandlerImpl = new RejectedExecutionHandlerImpl();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//intial pool size 2,max pool size 4,keepAliveTime, for thread,worker queue size 2
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2,4,10,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2),
threadFactory,rejectedExecutionHandlerImpl);

MyMonitorThread myMonitorThread = new MyMonitorThread(executorPool,3);
Thread thread = new Thread(myMonitorThread);
thread.start();

for(int i=0;i<10;i++)
{
           executorPool.execute(new WorkerThread("cmd"+i));
}

Thread.sleep(30000);
executorPool.shutdown();
Thread.sleep(5000);
myMonitorThread.shutdown();
}
}

ScheduledThreadPoolExecutor --> to schedule tasks periodically.
CachedThreadPoolExecutor --> To spawn unlimited threads if free ones are not available. not recommended.
FixedTreadPoolExecutor --> Limited threads.
***************************************************************************************************************

1) ThreadPoolExecutor(which is subclass of Executor and ExecutorService) class has 4 constructors,but due to their complexity, the java concurrency API provides the 'Executors' class to construct the executor.

2) Shoutdown waits unitl running + pending tasks completion. Won't allow new tasks.
3) AwaitTermination can be used to block calling method untill termination happens or timeout happens.

http://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice
http://howtodoinjava.com/core-java/multi-threading/java-thread-pool-executor-example/
https://dzone.com/articles/scalable-java-thread-pool-executor

Thursday, 13 April 2017

Gauva-Retryer

Retrier:  The guava-retrying module provides a [general purpose method] for retrying java arbitary code with specific stop,retry and exception handling capabilities that are enhanced by Gauva's predicate matching.

1) API calls,Network calls are failing are normal part of our programs. We handle them in Application specific ways.
2) Many times,we need to [retry] the operations before logging it as failure.
3) Data Fetcher ----------> Remote Server
   For demonstration, we have a Remote Server from where we need to fetch the data.
   It could be [streaming] the data or a [REST API] call or any other [RPC] call.

   static class UrlFetcher implements Callable<Boolean>{
     private String url;
     private String opMode;

     UrlFetcher(String url,String opMode){
      this.url = url;
      this.opMode = opMode;
     }

     @Override
     public Boolean call() throws Exception{
      if("fail".equals(opMode)){
       throw new TimeoutException("Connection timed out");
      }

      return true;
     }
   }

   Retryer<Boolean> retrier = RetryerBuilder.<Boolean>newBuilder()
                              .RetryIfExceptionOfType(TimeoutException.class)
                              .retryIfRuntimeException()
                              .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                              .build();

  try{
    retrier.call(new UrlFetcher("http://www.google.com","normal"));
    retrier.call(new UrlFetcher("http://www.google.com","fail"));
  } catch(RetryException e){
        e.printStackTrace();
  } catch(ExecutionException e){
        e.printStackTrace();
  }

 4) a) We need to create retryer using builder.
    b) We can specify the conditons on which to retry.
    c) Here we have specified RuntimeException and TimeoutException, if there is any exception,it won't retry.
    d) We also need to specify strategy to stop. Here we have specified,retry 3 times and then abort.

5) Wait Strategy:
------------------
1) Here we retried immediately after failure, what if we want to change the behaviour.
.withWaitStrategy(WaitStrategies.exponentailWait(1000,5,TimeUnit.SECONDS))

Tuesday, 11 April 2017

Maven Notes

  Maven:    No need to write build script and manage dependencies
----------
Project management and comprehension tool based on concept of [POM] --> Project Object Model.

Maven -Manages--> [Build,Dependecies,SCMs] Releases,distribution, Reporting and Documentation.

a) Maven provides developers a [complete build life cycle framework].
b) Maven uses [**standard directory layout and ** default build cycle].
c) Maven project structure and contents are mentioned in pom.xml[project object model].
d) When Maven project created, maven creates a standard project structure, deveopers are required only to place files in those folders.

e) ${basedir}/src/main/java/ -> Source code.
   ${basedir}/src/main/resources --> resources.
   ${basedir}/src/test --> Test code.
   ${basedir}/src/test/resources --> Test resources.
   ${basedir}/src/target --> distibutable jar.
   ${basedir}/src/target/classes --> compiled class files.

7) In order to build the project, maven provides developers options to mention [life-cycle goals] and [project dependencies](in pom.xml).

8) Export M2_HOME=export M2_HOME=/usr/local/apache-maven/apache-maven-3.3.3 and add bin folder to PATH to run maven build from anywhere in sys.

9)POM.xml -> It's XML file
  a) Always resides in [base directory] of project.
  b) While executing maven task/goal, maven looks for pom.xml in current directory.
  c) POM might contains below information:
     a) project dependencies b) plugins(compiler plugin etc) c) goals(custom goals) d) build profiles (dev,prod,test) e) project version(under project element witch is root element) f) developers d) mailing list

     We can modify, project folder structure

**d) Before creating POM, we need to come up with project group(groupid),project name(artifact) and version for [unique] identification of project in repository.

  e) It's allowed only one POM file per project.
  f) All POMs inherit from a parent POM known as super POM.
  g) Maven provides different archtypes to ssupport diff project structures.

Build Life cycle:
-------------------

Build Life Cycle Contains Phases --> Phases contains Goals

1) Typical build cycle contains following phases:
   a) prepare-resources (Resource copying can be customized in this phase.) b) compile (just compile source) c) package (build jar/war file) d) install (upload artifacts to local/remote repository)

2) Every phase has pre and post phases to register goals.

c) Maven has 3 standard life cycles: a) clean b) default or build d) site (Documentation)

d) Goal is a specific task which contributes to the build.
e) Order of invocation matters

   clean phase -> dependency goal -> package phase
   mvn clean dependency:copy-dependencies package
         |         |                         |
       Phase ->   Goal                 ->   Phase

f) Default/Build life cycle : Has 23 phases

Build Profiles:
----------------
a) Build profiles can be used to distinguish build definations for diff env like prod,dev and UAT
b) Build profiles are three types:
   Per Project -> Defined in project pom.xml
   Per User -> Defined in Users/username/.m2/settings.xml
   Global -> %M2_HOME%/conf/settings.xml

   mvn phase -Pprod
c) Profile can be activated in pom.xml using activeProfiles tag.

Repository:
----------------
a) Repository is a place, all project jars,library jars,plugins resides.
b) 3 types: Local,Central and Remote
Local: i)   Gets created in %USER_HOME% folder.
       ii)  Maven keeps all project dependencies in local repository when mvn build runs.
       iii) Path can be overridden by mentioning path in settings.xml in %M2_HOME%/conf folder.

Central: Provoded by maven community; http://repo1.maven.org/maven/

Remote: Developers own custom library

Order of reference for dependencies: Local -> Central -> Remote

Plugins:
------------

1) Maven is actually plugin execution framework where every task is done by plugins
2) Ex: Creating jar file,create war file,compile source code,unit testing code,create documentation and project reports
3) Plugins usually provides multiple goals can be executed like this: [mvn plugin-name:goal-name]
   For ex: Java project can be compiled by using mvn-compiler-plugin's mvn compiler:compile
4) PLugins are two types: Build plugins (under /build) and reporting plugins(under /reporting)
5) in POM.xml <plugins><plugin><executions><execution><goals><goal></goal><goals><configuration><tasks></tasks></configuration><executions><execution></plugin></plugins>

Creating Projects:
-------------------
1) Maven uses archtype plugin to create projects.

External Dependencies:
-----------------------

We can add lib folder with jars to maven to refer when those jars are not found in all 3 repos.
<dependency><groupid></groupid><artifactid></artifactid><version></version><scope>system</scope><systempath></systempath></dependency>

-U to force maven to download latest dependencies

****** if version contains snapshot, it means maven fetch copy from repo for every build. unlike normal version case
Build automation: Kick off build of dependent projects, once current build is done successfully.
This can be acieved by modifying pom.xml or else using continuous integration(CI) hudson
Whenever SVN check in happens, it will trigger build and then triggers dependent builds.

Transitive Dependencies Discovery:
----------------------------------------------
It is pretty often a case, when a library say A depends upon other library say B. In case another project C want to use A then that project requires to use library B too.

Maven helps to avoid such requirement to discover all the libraries required. Maven does so by reading project files(pom.xml) of dependencies, figure out their dependencies and so on.

We only need to define [direct dependency] in each project pom. Maven handles the rest automatically.

Common dependencies can be placed at single place using concept of parent pom.Dependencies

Scope Description
compile This scope indicates that dependency is available in classpath of project. It is default scope.
provided This scope indicates that dependency is to be provided by JDK or web-Server/Container at runtime
runtime This scope indicates that dependency is not required for compilation, but is required during execution.
test This scope indicates that the dependency is only available for the test compilation and execution phases.
system This scope indicates that you have to provide the system path.
import This scope is only used when dependency is of type pom. This scopes indicates that the specified POM should be replaced with the dependencies in that POM's <dependencyManagement> section.

mvn dependency:tree