terça-feira, 23 de fevereiro de 2016

CDI - Conversation Scoped Bean

What's great about conversation beans?
It allows to maintain the same conversation (state) between distinct page requests although it has a smaller scope than session context. That happens because conversation scoped beans have a specific number of requests while session scoped beans have unlimited requests making it much heavier. The bean will stay active until it times out.

What's NOT so great about conversation beans?
BusyConversationException: when two requests arrive at the server simultaneously or in short succession. Conversation scoped beans along with AJAX are a very dangerous solution! However, this is a possible solution.

How to implement it?
You need to add a beans.xml file and place it in /WEB-INF directory.

Sample of beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

Sample of a Conversation scoped bean:

@Named
@ConversationScoped
public class MyConversationBean implements Serializable {
@Inject
    Conversation conversation;
}


Why does the conversation scoped bean has to be serializable?
Session and conversation scoped beans live for longer periods of time and the container while managing its resources might need to free some of it. Then, the container persists the bean into some sort of persistent media type or physical storage. Whenever the bean is needed agan, the container fetchs the bean and restores its state.

Why does the conversation scoped bean has the @ConversationScoped annotation?
This annotation tells the container that this bean will maintained while conversation is running.

Why do you have to inject the Conversation object reference?
The Conversation object manages the conversation context by using begin() and end() methods.

Why does the conversation scoped bean has the @Named annotation?
This annotation allows you to access the bean using Expression Language in JSF pages.

What are conversation scoped bean states?
There are two possible states: transient or long-running. When injected, the conversation is transient. Mark the conversation as long-running (when an actual conversation starts) by calling Conversation.begin() and back to transient by Conversation.end(). However, when trying to begin() a long-running conversation or when trying to end() a transient conversation an IllegalStateException is thrown.

Do conversation scoped beans propagate?
According to here, conversation automatically propagates in redirections and JSF faces requests, for instance, form submission. It does not propagate with non-faces requests like navigation via link.

The conversation can be forced to propagate in a non-faces request by including cid as a request parameter (therefore cid is a reserved parameter name). The cid lets the container know which conversation to load.

If the conversation is automatically propagated, cid is added to the URL by the container.

If you want to avoid conversation propagation, use the conversationPropagation request parameter (introduced in CDI 1.1).

Do conversation scoped beans timeout?
When no conversation is propagated to a JSF request, the request is associated with a new transient conversation. All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries. In the following cases, a propagated long-running conversation cannot be restored and reassociated with the request:

When the HTTP servlet session is invalidated, all long-running conversation contexts created during the current session are destroyed, after the servlet service() method completes.
The container is permitted to arbitrarily destroy any long-running conversation that is associated with no current JSF request, in order to conserve resources.

The timeout is the period of inactivity before the conversation is destroyed (as opposed to the amount of time the conversation is active).
The Conversation object provides a method to set the timeout. This is a hint to the container, which is free to ignore the setting.

           conversation.setTimeout(timeoutInMillis);


Useful resources:
JBoss ConversationScoped
JBoss Conversation Propagation
CDI bean scopes
CDI and conversation scope


segunda-feira, 15 de fevereiro de 2016

Fail-fast vs Fail-safe

Ever wondered why some collections throw ConcurrentModificationException and others don't? Basically, iterators from java.util package throw ConcurrentModificationException if you change it while iterating over it but iterators from java.util.concurrent package do not.
If you check JDK you can easily figure out why!

We're talking about two different behaviours here: fail-fast and fail-safe!

Fail-fast behaviour fails as soon as it realizes that the Collection has been changed since the iteration began. Which means that if a thread is iterating over a Collection and you try to remove, add or update one element an exception will be thrown.
But how does this Collection know it has been changed? ArrayList, Vector and HashSet are examples of Collections with fail-fast behaviour and they all extend AbstractList. AbstractList keeps a variable set to 0 that is incremented whenever you update/add/remove your iterator. If you start iterating over it and meanwhile it realizes that modCount has changed, ConcurrentModificationException is thrown.

Fail-safe does not raise any exception because it iterates over a clone of the Collection you want to iterate rather than the original one. CopyOnWriteArrayList and ConcurrentHashMap are both examples of Collections with fail-safe behaviour. However, there are two major issues with fail-safe behaviour:
- Memory overhead to keep the Collections copy;
- No guarantee that the data is up to date since the original data stucture might be changed meanwhile.

Single Code Line - What is it?

First of all, what is Single Code Line?
Single Code Line consists in having only one version at a time. That means that you won't have different branches with different features and you'll avoid the whole messy merge-this-branch-with-the-other task. Adding new features does not require a new branch: it is incrementally added to the existing version.
Having only one branch at a time really makes continuous integration a lot easier. On the other hand, if for some reason you want to release an older version (let's say your client requests) you'll not be able to.

Many branches simultaneously being developed are a risk factor because merging can generate new bugs and there's always a need to test the merge itself (unit testing and TDD are handy). Besides that, if you're working in an Agile team having different people working in different branches contradicts the collective code ownership (http://guide.agilealliance.org/guide/cco.html).

Recently I read here that Workday adopted this technique along with weekly releases and they made some really good points (I'm not going to focus on the weekly releases points in this post but it's worth checking the link):
- How bad is it when you are developing in a new branch and suddenly you have to correct something in the production branch? You have to correct in the master, merge with the new branch and test in both!
- It's the end of the features that are developed and have to grow beards before going to production! If there's only one version, chances are no features will be forgotten along the way in branch number 43.

I think that Single Code Line is very useful when your release dates are not very apart from each other. This way, if/when the client wants to change something, there's not been a lot of work upon the release. If the releases dates are very apart, the client will notice a lot of changes simultaneously and chances are that there will be more corrections to the branch or even some undos. Since there is no previous branch, it might get a little messy.

However, specially if you are maintaining code, Single Code Line might not be a good solution. Release dates are often more apart and if the client demands an older version you won't be able to deliver.

My ideal solution would be a hybrid between branches control and Single Code Line. Maintaining a lot of branches is confusing and error-prone but Single Code Line doesn't allow you to save the last "stable" version. What I think is a great solution would be Single Code Line along with one more branch:  the previous production version. Everybody would work upon only one branch (the latest stable production version), no feature would be forgotten along the way and tests cases would only incide in one branch (no merges, etc...). On the other hand, the last production version would be saved in another branch in case the client requests a rollback until the new branch that's been developing is released and accepted. No more than two branches allowed.


sexta-feira, 12 de fevereiro de 2016

Show progress bar while downloading file in Primefaces

I wanted to show a progress bar while downloading a file. The progress bar requires AJAX to display but the the file can't be downloaded (saved to disk) using AJAX.

Firstly, you can download a file using AJAX, however it will be kept in memory. JavaScript cannot access the users disk for security reasons.

So how do you solve this paradox?

The solution was to create a cookie that was set to true server-side when the file download process was complete. In client-side the cookie is polled every 150ms and when it's set to true it stops showing the progress bar. This solution was provided by BalusC in here.


Step 1 - Create progress bar:

<p:dialog widgetVar="progressLoader" id="divProgress" modal="true" draggable="false" resizable="false" showHeader="false">
<p:graphicImage library="img" name="ajax-loader.gif"/>
</p:dialog>


Step 2 - Create functions that show and hide the progress bar in JavaScript:
       function showProgress() {
         PF('progressLoader').show();
       }
       function closeLoader() {
         PF('progressLoader').hide();
       }

Step 3 - When the download is complete, set a custom cookie to true in JAVA:

 // set cookie cookie.file.exporting (you can pick your own name) to true (in order to close progress indicator client-side)

FacesContext.getCurrentInstance().getExternalContext().addResponseCookie("cookie.file.exporting", "true", Collections.emptyMap());


Step 4 - The link to download calls a JS function when clicked:

<h:commandLink id="exportAll" styleClass="image" action="#{controller.export()}"onclick="monitorExporting(showProgress, closeLoader);">
<h:graphicImage styleClass="image" library="img" name="img_icone_exportar.png"/>
</h:commandLink>


Step 5 - Create JS function that polls the cookie and shows and hides the progress bar:

function monitorExporting(start, complete) {   
         if(PrimeFaces.cookiesEnabled()) {
             if(start) {
                 start();
             }
             window.fileExportingMonitor = setInterval(function() {
                 var exportingComplete = PrimeFaces.getCookie('cookie.file.exporting');
                 if(exportingComplete === 'true') {
                     if(complete) {
                         complete();
                      }
                      clearInterval(window.fileExportingMonitor);
                      PrimeFaces.setCookie('cookie.file.exporting', null);
                }
            }, 150);
    }
}