Concurrency issues using SEAM-Wicket for facebook app
mole Jul 29, 2009 1:43 PMWe build a quite successfull facebook prototype based on the example
from the wicket wiki (http://cwiki.apache.org/WICKET/facebook-integration.html)
and factored out the fetching of facebook session parameters to a separate
SEAM component witch uses a SEAM @Observer(org.jboss.seam.wicket.beforeRequest
).
Essentially, we just grab the Facebook Credentials (session key and/or authtoken)
and store it in EVENT Scope inside a custom FacebookRequestContext Bean (a POJO, not a SEAM Bean) which we use to instantiate a com.google.code.facebookapi.IFacebookRestClient later on.
@Name("facebookRequestContextManager")
@Scope(ScopeType.EVENT)
@AutoCreate
public class FacebookRequestContextManager {
        
        /** this member holds the facebook session id for this request */
        @Out(scope=ScopeType.EVENT)
        private FacebookRequestContext facebookRequestContext;
        
        @Observer("org.jboss.seam.wicket.beforeRequest")
        public void onBeforeWebRequest(){
                // did facebook send us the sessionId?
                String fbSessionParamName = FacebookParam.SESSION_KEY.toString();
                String fbAuthTokenParamName = "auth_token";
                
                HttpServletRequest wicketHttpServletRequest = ((ServletWebRequest)WebRequestCycle.get().getRequest()).getHttpServletRequest();
                String fbAuthToken = wicketHttpServletRequest.getParameter(fbAuthTokenParamName);
                String fbSessionId = wicketHttpServletRequest.getParameter(fbSessionParamName);
                
                Session.get().setLocale(Locale.US);
                        
                if( StringUtils.isEmpty(fbSessionId) ){
                        // we have no facebook session, so we need one!
                        if( !StringUtils.isEmpty(fbAuthToken)){
                                // let the facebook service convert this authtoken into a valid session id:
                                FacebookFacade facebookFacade = (FacebookFacade) Component.getInstance("FacebookFacade");
                                try {
                                        fbSessionId = facebookFacade.authenticateSession( fbAuthToken );
                                } catch (RuntimeException _e) {
                                        //ignore this: we'll throw the exception down there.... 
                                }
                        }
                }
                if( fbSessionId==null ){
                        // send user to facebook login to initiate a new fb session
                        throw new FacebookAuthenticationException("auth failed");
                }
                facebookRequestContext = new FacebookRequestContext( fbSessionId );
        }
        
}Things worked fine until we started serving several thousand customers
per day. Under pressure, unfriendly things started to happen: Instead
of giving each request Scope a separate FacebookRequestContext object, all our users
got the same single instance (holding the very same session key) assigned. A rather
puzzling customer experience ...
Assuming a concurrency issue: Any clues what might be not thread safe with this construct?
 
     
     
     
    