Saturday, September 11, 2010

Not one thread, but many threads to do my work

It's often the case where our code executes in a single thread of execution. Take for an example a web application running on a servlet container. Sure the container is multi-threaded, but as far as one request is concerned, it's one thread that executes all code in its path to complete the request.
This is the norm and is usually sufficient for most cases. Then there are certain use cases where once the application is put together (or during designing it, if one pays good attention to design that is) you feel that part of the logic is simply waiting for their turn of the thread execution although they are perfectly capable in running without any dependency.

Take for an example a search solution that searches multiple data sources in order to present the results to the end-user. Assume that the data sources are one or more relational databases, an index of some sort (think lucene) an external search service. The search solution is expected to take in a user search term and search across all of these data sources and provide an aggregated set of results. And that's exactly what the code would do. The code would search each data source at a time, and say perhaps wrap the results in a common value object and would aggregate them so that they are ready for the user. So in the typical single thread execution path, the thread would execute each search one at a time and finally run them through the aggregation. Concurrently speaking though, this seems a bit wasteful. Each search against a data source has no dependency to each other. The only element that's dependent in this execution path is the aggregation which needs all results for it to do its magic. This means if we run all searches concurrently and then pass them to the aggregator we have a good chance of saving some time.
First thing that would dawn upon about this approach is - multiple threads. We want the search to spawn multiple threads on which each of the data sources would be searched on, and pass the results to an aggregation logic. Hence achieving concurrent execution of searches of which benefits can be very noticeable.

Messing around with multiple threads however, is something most avoid doing due to inherent complexities. Thread pooling, thread termination, synchronisation, deadlocks, resource sharing are a few of those complexities that a developer focused on application development might tend to stay away. But with the inclusion of the java concurrent package in the JDK, things just got simpler. Thanks to Doug Lea, the java.util.concurrent package which includes out of the box thread pooling, queues, mutexes, efficient thread initialisation and destruction, efficient locking etc are basically a comprehensive set of building blocks for application developers to easily introduce concurrency into the application flow.

While the above use case is an ideal candidate for an application developer to adopt a concurrent execution model in the application, a simple framework at - https://code.google.com/p/concurrent-it/ is a simple usage of the API on how to achieve concurrency. This was put together to achieve concurrent tasks in various use cases in a recent project. The code is quite straight forward and a test provided along with this is doing nothing but computing a fibonaci series and factorials. The computations however are exhausted so that its heavy in response times.

Touching the gist of it, the main building blocks employed of the java.util.concurrent package are briefly discussed here.

ExecutorService:
An ExecutorService provides means of initiating, managing and shutting down threads. The jdk provides several implementations of this and a factory utility called Executors provides the necessary utility methods to create them. The API documentation of the different types of ExecutorService is a good point of references (as always). Typically you would gain access to an ExecutorService will be as follows;

ExecutorService execService = Executors.newCachedThreadPool(); 
This would give you an ExecutorService which has a cached thread pool.

Callable:
The Callable interface is similar to the Runnable interface (in the thread api). So implementors of this interface can run on a different thread. The differentiator from the Runnable is that Callable will return a value and may throw an exception (if there's one to be thrown ofcourse).

public class Processor implements Callable {
 
   // implementing the contracted methods
    public AsyncResult call() throws ConcurrentException {
        // implementaitons placed here.
    }
}

Like the run() method of the Runnable interface, the Callable interface has a call() method that implementors are contracted to implement. As per the example above, our implementation returns a AsyncResult type when call() is called. And the call() method is invoked by the ExecutorService. And this implementation can be thought of a task that you'd want to be executed in its own thread.

Putting all together:
Now we've got our task that we want to be invoked in a separate thread (The Callable implementation) and we've got an ExecutorService that dishes our threads and manages the thread execution. Now to kick it all off all we have to do is;

List  tasks = // build a new list of Processor objects
 
List results = execService.invokeAll(tasks);


The invokeAll(Collection) method takes care of submitting all tasks (Processor objects in our case) for execution across multiple threads concurrently. As mentioned above, the call() method is consulted to kick off the execution of each of those threads.

Future:
The next important thing about the invokeAll(Collection) method call is its return value - Future objects. A Future is an holder of the result for an asynchronous process. This is quite a powerful concept where we can now take control of result of multiple threads. A simple get() method provides the means retrieving the desired result. As listed above, the type of the result is what the call() method returns. The get() method however would block if necessary. Thus the result of each task is accessible and can be put to use there after.

Putting all together:
A quick look how all of these lines in respect to the main thread of execution and the multiple threads spawned by the ExecutorService

List  tasks = // build a new list of Processor objects // main thread
List results = execService.invokeAll(tasks); // main thread spawns multiple thread

for (Future<AsyncResult> result : results) {
    AysncResult res = result.get() // main thread. Would block if necessary
    // do something with the result 
}
That's it. Using these building blocks from the API we have a nice straight-forward way to invoke our work concurrently. While the usage of the API is simple, applying concurrency needs to be done carefully. It needs to be thought of while designing the application and testing in terms of load, stress for thread and resource utilisation is a must. Also once implemented, a run through a profiler for how each thread behaves should be in the list of things todo as well. Also worth noting is that the tooling support is not quite mature as yet for the concurrent programming model (i.e. debugging).

The example contains a test that demonstrates the usage of the simple framework and it's accessible here - https://code.google.com/p/concurrent-it/. The test in the example shows the perhaps the most easiest advantage on using the java.util.concurrent package, which is speed-up through parallelism.

Tuesday, March 16, 2010

ThreadLocal - What's it for

ThreadLocal provides a mechanism of storing objects for the current execution of thread. What this means is that you can stick in a object into a ThreadLocal and expect it to be available at any point during the the executing thread. This comes in handy when you have to make some object made available between different layers (i.e. presentation->business->data access) without making them part of the api. For example implementing cross cutting concerns such as security, transactions make use of the ThreadLocal to access transactional, security contexts between layers, without cluttering the application APIs with non-application specific details.


What happens in the ThreadLocal
ThreadLocal holds a custom hash map that holds objects as values and the current thread as the key. This custom map (ThreadLocalMap) is local to the ThreadLocal and is not exposed as part of the API. So it's basically a HashMap carried through the current thread of execution. That's all to it in a nut-shell as to what goes inside the ThreadLocal.


How to make use of a ThreadLocal
A ThreadLocal is generally used through a custom implementation which holds the ThreadLocal. The custom implementation should have a static field of the type ThreadLocal and would generally expose static accessors to store and retrieve objects to and from the ThreadLocal.
Assume you want to store a FooContext object in the ThreadLocal as part of your application.
Following is an example of a basic implementation to use the ThreadLocal;

public class ThreadLocalHolder {

    private static ThreadLocal store = new ThreadLocal();

    public static void set(FooContext context) {
        store.set(context);
    }

    public static FooContext get() {
        store.get();
    }
}

To see how this is used consider a Business layer object called FooBusinessObject and a DAO callled BarDao. You want some method in the business object to initialise a FooContext, do some work and call the DAO. You then want to be able to access the FooContext you created without making part of the API of the DAO. 

public class FooBusinessObject {

    private BarDao barDao;

    public void doFoo() {
        // Some logic that builds a FooContext
        FooContext context = new FooContext();

        // sticks the context into the ThreadLocal.
        ThreadLocalHolder.set(context); 

        // Do more work....
        barDao.processBar();
    }
}

public class BarDao {

    public void processBar() {
        // Get the context from the thread-local
        FooContext context = ThreadLocalHolder.get();

        // do some work...
    }
}  

That's all that's needed to be able to store and retrieve objects in the ThreadLocal. ThreadLocal is used in many frameworks and is a popular choice for use cases of sharing cross cutting objects during the execution of a thread. 


Is there any danger involved?
There are potential dangers that you could face by using ThreadLocals though. However these dangers are not because of merely using the ThreadLocal, but because its not used properly (as with many other things as well). The issues are apparent when we work on a managed environment, such as a application server that maintains a thread pool dishing out threads for incoming requests. This means one request would get hold of a thread, finish the work involved and then the application server reclaims the thread back to the pool. Now if you stuck an object in the ThreadLocal, it doesn't get removed when the thread returns to the pool unless this is cleaned out. So you've now mixed the state of a thread that finished into another executing thread. 
So as part of using this properly, the thread local needs to be cleared out before the execution ends. This is ideally done in a finally block where the ThreadLocal is nullified. 
The above addition to the ThreadLocalHolder exposes a clear method that cleans out the ThreadLocal for this thread.

public class ThreadLocalHolder {

    private static ThreadLocal store = new ThreadLocal();

    public static void set(FooContext context) {
        store.set(context);
    }

    public static FooContext get() {
        store.get();
    }

    public static void clear() {
        store.set(null);
    }
}
And this is cleared as follows;

public class FooBusinessObject {

    private BarDao barDao;

    public void doFoo() {
        try {
            // Some logic that builds a FooContext
            FooContext context = new FooContext();

            // sticks the context into the ThreadLocal.
            ThreadLocalHolder.set(context);            

            // Do more work....
            barDao.processBar();
        }
        finally {
            // clean up
            ThreadLocalHolder.clear();
        }
    }
}

ThreadLocal usage is a very useful technique to provide per thread contextual information. Used properly it's a valuable method that will come handy where applicable. 

Friday, March 5, 2010

Spring Security - A peak under the hood

When I was introduced to spring security last year, I wanted to know what's going on under-the-hood. So I went to the best source to get the information I needed - The Source code. While I did my follow through, run-time step through of the framework, I made notes partially in my notebook and partially in my head (not ideal I know). However this knowledge has helped me do some customisation I'm currently working on and thought I should do a brain (and notepad) dump so that I can come back to this if needed again. So here goes..

Basics on configuring spring security
Configuring spring security for a web-application;
- Add the DelegatingFilterProxy filter in your web.xml
Configure this filter with a filter name 'springSecurityFilterChain'. Reason for this is discussed briefly later in this rant.
- Enable the filter for all requests. You can choose certain url patterns not to go through the filter.
Even if you don't do this, the spring security configuration allows skipping security certain url patterns.
- Create a separate spring configuration which holds all the security configurations.
It's cleaner and easier to maintain the security configurations if its kept separate.
- Make sure the spring security configuration is loaded as part of the context.
- Configure the spring security configuration to suite your requirements
At this point I'm going to leave the configuration details out of this notes. Instead we take a turn towards some of the internals on what goes under the hood of the framework.

The gist of it
The concept of the framework is to;
Define a set of roles(or authorities),
Define a set of resources (in the form of url patterns) and
Apply restrictions to the resources based on the permissions defined. The permissions are based on the roles(or authorities) applicable to a particular user and whether those roles(or authorities) have access to a resource or not.
This could be thought of as a 50k foot view on what spring security provides. Obviously there's much more that the framework provides. But I'd like to think that this is the gist of it.
Now getting onto a bit of details...

Some analogy to start off
At the core of Spring security, servlet filters and the HttpSession is employed to work it's magic. If accessing a secured web resource is analogous to going into a secured room of a building through few doors and coming back to the starting point through the same route, then the filters would be the doors. And there will be some action performed going through and coming out of each of these doors. These actions would remember what happened through these doors by holding it in some sort of a log record - this would be the HttpSession. Finally a check is done if the user is allowed to get in or not and sends the user back on the same route with a success or failure response.
Hence IMHO I believe to understand what spring security does, its useful to know what these filters are, how and what they do.

What's the DelegatingFilterProxy
The entry point to the spring security framework starts from one filter - DelegatingFilterProxy. The filter it self doesn't have a lot going on. As the name describes it, it's just a 'delegating' filter. It initializes looking for a target bean to delegate the filter chain. DelegatingFilterProxy, supports a init-param called 'targetBeanName'. This defines what bean it should delegate to. This is of course optional to configure. By default it would use the filter-name given in the filter config for this filter. And internally it delegates to the 'FilterProxyChain' filter. It finds the 'FilterProxyChain' by means of the filter name and that would need to be 'springSecurityFilterChain'. Once the delegator is worked out, the delegation happens..

What happens when the delegation begins
The FilterChainProxy gets to work when the delegation begins. It uses a pre-initialised map which holds information about a bunch of filters to execute. The filter chain continues invoking all filters defined in the map. Spring security has a pre-defined set of filters registered for the chain by default. This can be changed if needed. However if the default is accepted, the following filters will be in the chain of execution;

  • FilterChainProxy
  • SecurityContextPersistenceFilter
  • SecurityContextHolderAwareRequestFilter
  • ExceptionTranslationFilter
  • ChannelProcessingFilter
So the obvious curiosity at this point would be to know who/what initialises this map of default list of filters. The answer lies in the HttpSecurityBeanDefinitionParser.parse(Element element, ParserContext parserContext) method. This is part of the spring security configuration components. This rather long method registering the above filters (including the FilterProxyChain filter).
Now that the FilterProxyChain has kicked off the chain, each filter performs their responsibilities. The internals of all these filters are best understood by looking at them. However there's one particular filter worth discussing - SecurityContextPersistenceFilter. This filter has a special place in the framework. Before diving into this filter though there's a more important component to pay attention to, which is the SecurityContext.

What is the SecurityContext
The SecurityContext is a simple yet powerful interface that provides a mechanism to store and access Authenticaiton details during a executing thread. Spring security populates and depends on the SecurityContext at its core. When a person is authenticated their authentication details are held in the SecurityContext. The simple interface sets and returns an Authentication instance which extends the characteristics of java security's Pricipal. The application can decide what gets stored in the Authentication instance.
An explanation of the SecurityContext cannot be completed without the mention of the SecurityContextHolder.
As the definition states, SecurityContext presents minimum security information associated with the current thread of execution. The minimum security information is presented by the Authenticaion object it exposes as discussed above. The SecurityContextHolder holds the responsibility of attaching a SecurityContext with the current thread of execution. It does this by employing the ThreadLocal. The SecurityContext provides (as of the time of writing) 3 modes/strategies to attach a SecurityContext to the current thread of execution.
  • ThreadLocal
  • InheritableThreadLocal
  • Global
ThreadLocal; as it suggests implements a standard ThreadLocal implementation of the JDK. ThreadLocalSecurityContextHolderStrategy demonstrates a standard ThreadLocal implementation and holds the SecurityContext in the current thread. This is also the default strategy used if none is explicitly provided.
InheritableThreadLocal; as the API defines it, is a inheritable implementation (InheritableThreadLocalSecurityContextHolderStrategy) of the ThreadLocal. Provides sharing and overriding values between parent and child threads where applicable.
Global; Is a static field based implementation (GlobalSecurityContextHolderStrategy). Hence the SecurityContext held on this strategy is shared by all instances on the jvm. As the code documentation states, this is generally used for rich client applications.
The SecurityContextHolder employs one of this strategies to attach the SecurityContext onto the thread. It provides an API to create, store and clean-up the SecurityContext for any of these strategies used. And the strategy employed is always initialised once (with the exception of some one explicitly setting the strategy) for the jvm.
Now that the SecurityContext is dealt with, we shift attention back to the SecurityContextPeristenceFilter.

Back to the SecurityContextPersistenceFilter
As discussed above, this filter is invoked in the filter chain process and more importantly is the first as well. It's important that this is invoked as this sets up the core needed for others to do their work. This filter makes sure the SecurityContextHolder has the SecurityContext to be attached to the thread.
It also uses the HttpSession (via a HttpSessionSecurityContextRepository) to hold the SecurityContext within the user's HttpSession, so that the SecurityContext can be shared between requests. The repository implementation that manipulates the session creates a session if a current session does not exist based on the configuration attribute 'allowSessionCreation'. This by default is true. As a result you might end up with a lot of HttpSession objects within your heap. This usually is not a problem. But if heap space is of concern then you might want to consider turning off the new session creation option by setting 'allowSessionCreation' to 'false'. However this opens up several other impacts and one would have to ensure that anyone using the SecurityContextHolder should not depend on the SecurityContext being persisted between web-requests. However applicatoins need to ensure that the minimum data is held in the Authentication instances so that the session wont get too heavy.
So this filter focuses on persisting the SecurityContext through the SecurityContextHolder for rest of the filters/components to do their work. One might raise a concern on the approach of storing these values in the HttpSession and thread-local. As discussed above, choosing not to store it in the HttpSession is an option, but one that should be used cautiously. As for the ThreadLocal, concerns would pile up on situations where thread pools are employed to serve web requests in an application server and the cleansing of these ThreadLocals. Spring security takes care of this by ensuring that TheadLocals are only used in the life time of the thread serving a request. The populated ThreadLocal is cleaned up before the thread returns to the pool.
So, one-by-one in the chain, these filters perform their duties to enforce security for the application. Understanding these filters makes it easy to trace down problems and provide your own extensions. May the source be with you!!!