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?