/*
* Speedo: an implementation of JDO compliant personality on top of JORM
* generic I/O sub-system. Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Release: 1.0
*
* Created on Apr 19, 2004 @author franck.milleville@cgey.com
*
*/
package org.objectweb.speedo.j2eedo.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.jdo.JDOException;
import javax.jdo.JDOFatalException;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
import org.objectweb.speedo.j2eedo.bo.DatabaseImpl;
import org.objectweb.speedo.j2eedo.common.PMHolder;
import org.objectweb.util.monolog.api.BasicLevel;
/**
* This class allows to highlight conccurent access deadlock and issues.
*
* @author fmillevi@yahoo.com
* @see MainLauncher
*/
public class ShowConcurrencyErrors extends MainLauncher {
/**
* This method connects to the database using the default speedo properties
* file and calls the test method doTest
*
* @param args
* not used
* @throws JDOException
* @throws Exception
* @see #doTest()
*/
public static void main(String[] args) throws JDOException, Exception {
ShowConcurrencyErrors ml = new ShowConcurrencyErrors();
ml.initPMF();
ml.doTest();
}
private static final int NUMBER_OF_THREAD = 3;
private static final int NUMBER_OF_GET_BY_ID = 100;
private static final int NUMBER_OF_QUERIES = 100;
private static final int NUMBER_OF_REMOVE = 20;
private static final int NUMBER_OF_CREATE = 20;
private static final int NUMBER_OF_SPLIT = 40;
/**
* In order to stress the concurrency manager, the main function starts 3
* threads performing the same actions on projects :
* <ul>
* <li>Get by id</li>
* <li>Query by members or id</li>
* <li>Create new project</li>
* <li>Split a project</li>
* <li>Delete a project</li>
*/
public void doTest() throws JDOException, Exception {
final int nbThread = NUMBER_OF_THREAD;
Thread ts[] = new Thread[nbThread];
final int nbTx = nbThread;
final List methodsList = new ArrayList();
for (int i = 0; i < NUMBER_OF_GET_BY_ID; i++)
methodsList.add(DatabaseImpl.PARAMETER_GET_PROJECT);
for (int i = 0; i < NUMBER_OF_QUERIES; i++)
methodsList.add(DatabaseImpl.PARAMETER_QUERY_PROJECTS);
for (int i = 0; i < NUMBER_OF_CREATE; i++)
methodsList.add(DatabaseImpl.PARAMETER_NEW_PROJECT);
for (int i = 0; i < NUMBER_OF_SPLIT; i++)
methodsList.add(DatabaseImpl.PARAMETER_SPLIT_PROJECT);
for (int i = 0; i < NUMBER_OF_REMOVE; i++)
methodsList.add(DatabaseImpl.PARAMETER_REM_PROJECT);
for (int thread = 0; thread < nbThread; thread++) {
ts[thread] = new Thread(new Runnable() {
public void run() {
String action = null;
String returnStr = null;
Iterator iter = null;
PersistenceManagerFactory pmf =
JDOHelper.getPersistenceManagerFactory(p);
PMHolder pmHolder = new PMHolder(pmf);
int j = 0;
for (int i = 0; i < nbTx; i++) {
logger.log(BasicLevel.INFO, "Start loop " + i);
Collections.shuffle(methodsList);
iter = methodsList.iterator();
while (iter.hasNext()) {
if (0 == (j++ % 100.0))
logger.log(BasicLevel.INFO, j + " actions called...");
action = (String) iter.next();
// check if the action need to start a transaction
logger.log(BasicLevel.DEBUG, "Calls method:" + action);
try {
returnStr = DatabaseImpl.instance.doAction(action, true, pmHolder);
} catch (JDOFatalException e) {
logger.log(BasicLevel.WARN, "Action '" + action
+ "' throws a JDOFatalException exception :", e);
} catch (JDOException e) {
logger.log(BasicLevel.WARN, "Action '" + action
+ "' throws a JDO exception :", e);
} catch (Exception e) {
logger.log(BasicLevel.WARN, "Action '"
+ action + "' throws an exception :", e);
}
logger.log(BasicLevel.DEBUG, "The method " + action
+ " returns:\n" + returnStr);
}
}
logger.log(BasicLevel.INFO, j + " actions called ");
}
});
}
//-------------- Launch all threads ------------//
for (int thread = 0; thread < nbThread; thread++) {
ts[thread].start();
}
}
}