001: /*
002: * Speedo: an implementation of JDO compliant personality on top of JORM
003: * generic I/O sub-system. Copyright (C) 2001-2004 France Telecom R&D
004: *
005: * This library is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU Lesser General Public License as published by the
007: * Free Software Foundation; either version 2 of the License, or (at your
008: * option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
013: * for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation,
017: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Release: 1.0
020: *
021: * Created on Apr 19, 2004 @author franck.milleville@cgey.com
022: *
023: */
024: package org.objectweb.speedo.j2eedo.test;
025:
026: import java.util.ArrayList;
027: import java.util.Collections;
028: import java.util.Iterator;
029: import java.util.List;
030:
031: import javax.jdo.JDOException;
032: import javax.jdo.JDOFatalException;
033: import javax.jdo.JDOHelper;
034: import javax.jdo.PersistenceManagerFactory;
035:
036: import org.objectweb.speedo.j2eedo.bo.DatabaseImpl;
037: import org.objectweb.speedo.j2eedo.common.PMHolder;
038: import org.objectweb.util.monolog.api.BasicLevel;
039:
040: /**
041: * This class allows to highlight conccurent access deadlock and issues.
042: *
043: * @author fmillevi@yahoo.com
044: * @see MainLauncher
045: */
046: public class ShowConcurrencyErrors extends MainLauncher {
047: /**
048: * This method connects to the database using the default speedo properties
049: * file and calls the test method doTest
050: *
051: * @param args
052: * not used
053: * @throws JDOException
054: * @throws Exception
055: * @see #doTest()
056: */
057: public static void main(String[] args) throws JDOException,
058: Exception {
059: ShowConcurrencyErrors ml = new ShowConcurrencyErrors();
060: ml.initPMF();
061: ml.doTest();
062: }
063:
064: private static final int NUMBER_OF_THREAD = 3;
065: private static final int NUMBER_OF_GET_BY_ID = 100;
066: private static final int NUMBER_OF_QUERIES = 100;
067: private static final int NUMBER_OF_REMOVE = 20;
068: private static final int NUMBER_OF_CREATE = 20;
069: private static final int NUMBER_OF_SPLIT = 40;
070:
071: /**
072: * In order to stress the concurrency manager, the main function starts 3
073: * threads performing the same actions on projects :
074: * <ul>
075: * <li>Get by id</li>
076: * <li>Query by members or id</li>
077: * <li>Create new project</li>
078: * <li>Split a project</li>
079: * <li>Delete a project</li>
080: */
081: public void doTest() throws JDOException, Exception {
082: final int nbThread = NUMBER_OF_THREAD;
083: Thread ts[] = new Thread[nbThread];
084: final int nbTx = nbThread;
085: final List methodsList = new ArrayList();
086:
087: for (int i = 0; i < NUMBER_OF_GET_BY_ID; i++)
088: methodsList.add(DatabaseImpl.PARAMETER_GET_PROJECT);
089: for (int i = 0; i < NUMBER_OF_QUERIES; i++)
090: methodsList.add(DatabaseImpl.PARAMETER_QUERY_PROJECTS);
091: for (int i = 0; i < NUMBER_OF_CREATE; i++)
092: methodsList.add(DatabaseImpl.PARAMETER_NEW_PROJECT);
093: for (int i = 0; i < NUMBER_OF_SPLIT; i++)
094: methodsList.add(DatabaseImpl.PARAMETER_SPLIT_PROJECT);
095: for (int i = 0; i < NUMBER_OF_REMOVE; i++)
096: methodsList.add(DatabaseImpl.PARAMETER_REM_PROJECT);
097:
098: for (int thread = 0; thread < nbThread; thread++) {
099: ts[thread] = new Thread(new Runnable() {
100: public void run() {
101: String action = null;
102: String returnStr = null;
103: Iterator iter = null;
104: PersistenceManagerFactory pmf = JDOHelper
105: .getPersistenceManagerFactory(p);
106: PMHolder pmHolder = new PMHolder(pmf);
107: int j = 0;
108: for (int i = 0; i < nbTx; i++) {
109: logger.log(BasicLevel.INFO, "Start loop " + i);
110: Collections.shuffle(methodsList);
111: iter = methodsList.iterator();
112: while (iter.hasNext()) {
113: if (0 == (j++ % 100.0))
114: logger.log(BasicLevel.INFO, j
115: + " actions called...");
116: action = (String) iter.next();
117: // check if the action need to start a transaction
118: logger.log(BasicLevel.DEBUG,
119: "Calls method:" + action);
120: try {
121: returnStr = DatabaseImpl.instance
122: .doAction(action, true,
123: pmHolder);
124: } catch (JDOFatalException e) {
125: logger
126: .log(
127: BasicLevel.WARN,
128: "Action '"
129: + action
130: + "' throws a JDOFatalException exception :",
131: e);
132: } catch (JDOException e) {
133: logger.log(BasicLevel.WARN, "Action '"
134: + action
135: + "' throws a JDO exception :",
136: e);
137: } catch (Exception e) {
138: logger.log(BasicLevel.WARN, "Action '"
139: + action
140: + "' throws an exception :", e);
141: }
142:
143: logger.log(BasicLevel.DEBUG, "The method "
144: + action + " returns:\n"
145: + returnStr);
146: }
147: }
148: logger.log(BasicLevel.INFO, j + " actions called ");
149: }
150: });
151: }
152: //-------------- Launch all threads ------------//
153: for (int thread = 0; thread < nbThread; thread++) {
154: ts[thread].start();
155: }
156: }
157: }
|