[SoapRMI] SOLVED: be careful about sharing parser instance [x
pp potential cleanup/reset problem]
Anthony Baker
Anthony_at_centerspan.com
Mon, 29 Jul 2002 09:32:49 -0700
Just curious, how much more efficient is pooling parser instances vs. just
creating a new parser for every request? I ran some tests with a pooling
implementation I had written and didn't see much improvement. Perhaps the
parser is fast enough to not need the overhead of pooling?
:-)
Anthony
-----Original Message-----
From: Aleksander Slominski [mailto:aslom_at_cs.indiana.edu]
Sent: Monday, July 29, 2002 9:15 AM
To: CHEN,SHIH-CHANG (HP-NewJersey,ex2)
Cc: 'soaprmi_at_mailman.cs.indiana.edu'; xmlpull-user_at_yahoogroups.com
Subject: [SoapRMI] SOLVED: be careful about sharing parser instance [xpp
potential cleanup/reset problem]
"CHEN,SHIH-CHANG (HP-NewJersey,ex2)" wrote:
> > what is the parser state (getEventType()) just before last next()?
>
> 0 (start_document): nost
> 1, 2, 3 or 4: sometime ?
hi,
those constants are defined in interface XmlPullParser - to have more
friendly messages use:
* System.out.println(XmlPullParser.TYPES[ parser.getEventType() ]);
* or even better to see actual input and positions
System.out.println(parser.getPositionDescritption());
> > did you make sure that only one thread at any time is accessing
> > parser instance. the easiest approach is to use pool of parser
> > instances that are reused to handle requests (typically each request
> > gets its own parser instance and not shared with other thread).
>
> I also suspect my ide (eclipse) or servlet engine(Tomcat404) has
> threading problems. But a servlet instance is supposed to run in one
> thread. And Servlent container will take care of servlet instance
> pooling. In my case, a parser instance is cached in a servlet
> instance.
>
> I will using pooling if I cannot solve this problem. Attachment is my
> servlet for server-side. In client-side, I use WebLoad5 to simulate
> concurrent 10 http
> clients.(http://www.radview.com/products/WebLOAD.asp)
i think we have the problem solved :-)
unless you explicitly make servlet instance thread save
(using marker interface SingleThreadModel) you need to do
your own per-thread initialization outside of init() as this method is
called only once when servlet is created, see:
http://www.jguru.com/faq/view.jsp?EID=150
(...)Under most circumstances, there is only one instance of your servlet,
no matter how many client requests are in process. That means that at any
given moment, there may be many threads running inside the service() method
of your solo instance, all sharing the same instance data and potentially
stepping on each other's toes. This means that you should be careful to
synchronize access to shared data (instance
variables) using the synchronized keyword.(...)
so in your case you _need_ to create new parser instance or use pool example
pool implementation is available at:
http://www.extreme.indiana.edu/~aslom/xmlpull/org/xmlpull/v1/util/XmlPullPar
serPool.java
and then your sample can be modified to:
import org.xmlpull.v1.util.XmlPullParserPool;
public class EchoServlet extends HttpServlet {
//private XmlPullParserFactory pullfactory;
//reset does not work correctly
//private XmlPullParser xpp; -- parser instance is NOT multithread safe
XmlPullParserPool pool;
public void init() throws ServletException {
try {
XmlPullParserFactory pullfactory = XmlPullParserFactory.newInstance();
pullfactory.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
pool = new XmlPullParserPool(pullfactory);
} catch (XmlPullParserException e) {
e.printStackTrace( System.out );
throw new ServletException( e.getMessage() );
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
InputStream in = req.getInputStream();
try {
pullEcho( in, res.getWriter() );
} catch (XmlPullParserException e) {
//e.printStackTrace( System.out );
throw new IOException( e.getMessage() );
}//
private void pullEcho( InputStream in, Writer writer )
throws IOException,XmlPullParserException
{
//XmlPullParser xpp = pullfactory.newPullParser();
// here access to pool of parser instances
XmlPullParser xpp = pool.getPullParserFromPool();
try {
xpp.setInput ( new InputStreamReader ( in ) );
int eventType = xpp.getEventType();
// ...
// whne finished processing return parser to pool:
} finally { if(xpp != null) {PullParserPool.return(xpp);} }
}
let me know if this solved your problem.
thanks,
alek
ps. BTW we are now adding to XmlPull API new interface XmlSerializer that
will make much easier to write echo XML code :-)
_______________________________________________
SoapRMI mailing list
http://www.extreme.indiana.edu/soap
http://mailman.cs.indiana.edu/mailman/listinfo/soaprmi