Hi all!

Well, I've been using, along with my development team, Struts2 since version 
2.0.1, and
recently moved to 2.0.5.

Everything seems allright with Struts2 performance, however, we've been doing 
tests
just before shipping into production (in just a week) and have found the 
following:

1) Parameters interceptor when receiving high load got really slow per request.
I don't know if it has something to do with the OGNL Values Stack. Any feedback
in this point would be great.

Anyway, we had to develop a lightweight Parameters Interceptor of our own 
(which I attach),
and improved significantly the number of responses per second. Of course, it 
doesn't use
OGNL Value Stack and not supports Wrapper Arrays. However, String, and Integer 
arrays are supported.
Long, Float or other Basic Type Wrappers Arrays are of easy implementation.

2) Well, besides Struts2 we use Spring (and Hibernate). Tracking the times of 
response per request
on each step, we found that Struts2 creates a Response object (as far as I 
know, always of the class
org.apache.struts2.dispatcher.ServletDispatcherResult). Anyway, in every 
request, Struts2 attempts to get
an object from the ObjectFactory (in this case Spring), with the name 
org.apache.struts2.dispatcher.ServletDispatcherResult, which of course, doesn't 
exist unless you
define it in your beans definition file, so, the ObjectFactory creates a new 
object of the type 
org.apache.struts2.dispatcher.ServletDispatcherResult. This creation process, 
when faced to a high concurrent load
of requests gets really, really slow (still don't know why). The solution, very 
simple in fact, is to define a bean
in your spring bean file:

<bean id="org.apache.struts2.dispatcher.ServletDispatcherResult"
        class="org.apache.struts2.dispatcher.ServletDispatcherResult" 
scope="prototype"
        autowire="byName">
</bean>

Have a nice day,

Camilo Gonzalez



__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis! 
Regístrate ya - http://correo.espanol.yahoo.com/ 
public class ParametersInterceptor implements Interceptor {

	private static final long serialVersionUID = 1L;

	/* Cache expire time */
	private static long expireTime = 72000000;

	private static int maxCacheSize = 100;

	private static Map<ClassWrapper, Method> cacheMetodosGet;

	private static Map<ClassWrapper, Method> cacheMetodosSet;

	private static Map<ClassWrapper, Long> lastTimeUpdatedGet;

	private static Map<ClassWrapper, Long> lastTimeUpdatedSet;
	

	static {
		cacheMetodosGet = new TreeMap<ClassWrapper, Method>();
		cacheMetodosSet = new TreeMap<ClassWrapper, Method>();
		lastTimeUpdatedGet = new TreeMap<ClassWrapper, Long>();
		lastTimeUpdatedSet = new TreeMap<ClassWrapper, Long>();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
	 */
	public void destroy() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#init()
	 */
	public void init() {
	}

	public static Method getGetter(Class c, String varName) {
		ClassWrapper cw = new ClassWrapper(c, varName);
		if (cacheMetodosGet.containsKey(cw)) {
			long act = Calendar.getInstance().getTimeInMillis();
			long last = lastTimeUpdatedGet.get(cw);
			if (act - last <= expireTime) {
				return cacheMetodosGet.get(cw);
			}
		}
		for (Method m : c.getMethods()) {
			if (m.getName().equals("get" + varName)) {
				if (m.getParameterTypes().length == 0) {
					long act = Calendar.getInstance().getTimeInMillis();
					if (cacheMetodosGet.size() < maxCacheSize) {
						cacheMetodosGet.put(cw, m);
						lastTimeUpdatedGet.put(cw, act);
					}
					return m;
				}
			} else if (m.getName().equals("is" + varName)) {
				if (m.getParameterTypes().length == 0) {
					long act = Calendar.getInstance().getTimeInMillis();
					if (cacheMetodosGet.size() < maxCacheSize) {
						cacheMetodosGet.put(cw, m);
						lastTimeUpdatedGet.put(cw, act);
					}
					return m;
				}
			}
		}
		return null;
	}

	public static Method getSetter(Class c, String varName) {
		ClassWrapper cw = new ClassWrapper(c, varName);
		if (cacheMetodosSet.containsKey(cw)) {
			long act = Calendar.getInstance().getTimeInMillis();
			long last = lastTimeUpdatedSet.get(cw);
			if (act - last <= expireTime) {
				return cacheMetodosSet.get(cw);
			}
		}
		for (Method m : c.getMethods()) {
			if (m.getName().equals("set" + varName)) {
				if (m.getParameterTypes().length == 1) {
					long act = Calendar.getInstance().getTimeInMillis();
					if (cacheMetodosSet.size() < maxCacheSize) {
						cacheMetodosSet.put(cw, m);
						lastTimeUpdatedSet.put(cw, act);
					}
					return m;
				}
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
	 */
	public String intercept(ActionInvocation ai) throws Exception {
		Action ac = (Action) ai.getAction();
		HttpServletRequest req = ServletActionContext.getRequest();
		Enumeration en = req.getParameterNames();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			String value = req.getParameter(name);
			String[] values = req.getParameterValues(name);
			String names[] = name.split("[.]");
			Object actObj = ac;
			for (int i = 0; i < names.length - 1; i++) {
				Object val = null;
				String n = names[i];
				n = n.substring(0, 1).toUpperCase() + n.substring(1);
				Class c = actObj.getClass();
				Method getter = getGetter(c, n);
				Method setter = getSetter(c, n);
				if (getter != null && setter != null) {
					val = getter.invoke(actObj, new Object[0]);
					if (val == null) {
						val = getter.getReturnType().newInstance();
						setter.invoke(actObj, new Object[] { val });
					}
					actObj = val;
				}
				if (actObj == null || actObj != val) {
					// System.out.println("Couldn't set value in Action for
					// parameter: " + name);
					actObj = null;
					break;
				}
			}
			String n = names[names.length - 1];
			n = n.substring(0, 1).toUpperCase() + n.substring(1);
			if (actObj != null) {
				Method setter = null;
				Class c = actObj.getClass();
				Class c1 = null;
				setter = getSetter(c, n);
				if (setter != null) {
					c1 = setter.getParameterTypes()[0];
					if (c1 != null) {
						boolean set = false;
						if (values.length == 1) {
							if (c1.equals(String.class)) {
								setter.invoke(actObj, new Object[] { value });
								set = true;
							} else if (c1.equals(Integer.class)) {
								if (value == "")
									setter.invoke(actObj, new Object[] { null });
								else
									setter.invoke(actObj, new Object[] { new Integer(value) });
								set = true;
							} else if (c1.equals(Long.class)) {
								if (value == "")
									setter.invoke(actObj, new Object[] { null });
								else
									setter.invoke(actObj, new Object[] { new Long(value) });
								set = true;
							} else if (c1.equals(Boolean.class)) {
								if (value == "")
									setter.invoke(actObj, new Object[] { null });
								else
									setter.invoke(actObj, new Object[] { new Boolean(value) });
								set = true;
							} else if (c1.equals(boolean.class)) {
								if (value == "")
									value = "false";
								setter.invoke(actObj, new Object[] { new Boolean(value) });
								set = true;
							}
						}
						if (!set) {
							if (c1.equals(String[].class)) {
								setter.invoke(actObj, new Object[] { values });
								set = true;
							} else if (c1.equals(Integer[].class)) {
								Integer[] iarr = new Integer[values.length];
								int i = 0;
								for (String s : values) {
									iarr[i++] = new Integer(s);
								}
								setter.invoke(actObj, new Object[] { iarr });
								set = true;
							}
						}
					}
				}
			}
		}
		return ai.invoke();
	}

	private static class ClassWrapper implements Comparable<ClassWrapper> {
		private Class clase;

		private String methodName;

		public ClassWrapper(Class clase, String methodName) {
			super();
			this.clase = clase;
			this.methodName = methodName;
		}

		public int compareTo(ClassWrapper o) {
			if (clase != null && o.clase != null) {
				int c1 = clase.getName().compareTo(o.clase.getName());
				if (c1 != 0)
					return c1;

				if (methodName != null) {
					return methodName.compareTo(o.methodName);
				}
			}
			return 0;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof ClassWrapper) {
				ClassWrapper o = (ClassWrapper) obj;
				if (clase != null && clase.equals(o.clase)) {
					if (methodName != null && methodName.equals(o.methodName)) {
						return true;
					}
				}
			}
			return super.equals(obj);
		}
	}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to