- more abstraction of serverCore thread access

- no more keep-alive when number of connections exceeds 1/2 of the allowed number of connection

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@6456 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 15 years ago
parent 19f31bb043
commit f0b8db93f0

@ -65,11 +65,6 @@ public final class Connections_p {
// get the serverCore thread
final WorkflowThread httpd = sb.getThread("10_httpd");
/* waiting for all threads to finish */
int count = serverCore.sessionThreadGroup.activeCount();
final Thread[] threadList = new Thread[((serverCore) httpd).getJobCount()];
count = serverCore.sessionThreadGroup.enumerate(threadList);
// determines if name lookup should be done or not
boolean doNameLookup = false;
if (post != null) {
@ -84,92 +79,89 @@ public final class Connections_p {
}
}
// waiting for all threads to finish
int idx = 0, numActiveRunning = 0, numActivePending = 0;
boolean dark = true;
for ( int currentThreadIdx = 0; currentThreadIdx < count; currentThreadIdx++ ) {
final Thread t = threadList[currentThreadIdx];
if ((t != null) && (t instanceof serverCore.Session) && (t.isAlive())) {
// get the session object
final Session s = ((Session) t);
// get the session runtime
final long sessionTime = s.getTime();
// getthe request command line
boolean blockingRequest = false;
String commandLine = s.getCommandLine();
if (commandLine == null) blockingRequest = true;
final int commandCount = s.getCommandCount();
for (Session s: ((serverCore) httpd).getJobList()) {
if (!s.isAlive()) continue;
// get the session runtime
final long sessionTime = s.getTime();
// getthe request command line
boolean blockingRequest = false;
String commandLine = s.getCommandLine();
if (commandLine == null) blockingRequest = true;
final int commandCount = s.getCommandCount();
// get the source ip address and port
final InetAddress userAddress = s.getUserAddress();
final int userPort = s.getUserPort();
if (userAddress == null) continue;
final boolean isSSL = s.isSSL();
String dest = null;
String prot = null;
final serverHandler cmdObj = s.getCommandObj();
if (cmdObj instanceof HTTPDemon) {
prot = isSSL ? "https":"http";
// get the source ip address and port
final InetAddress userAddress = s.getUserAddress();
final int userPort = s.getUserPort();
if (userAddress == null) continue;
// get the http command object
final HTTPDemon currentHttpd = (HTTPDemon)cmdObj;
final boolean isSSL = s.isSSL();
// get the connection properties of this session
final Properties conProp = (Properties) currentHttpd.getConProp().clone();
String dest = null;
String prot = null;
final serverHandler cmdObj = s.getCommandObj();
if (cmdObj instanceof HTTPDemon) {
prot = isSSL ? "https":"http";
// get the http command object
final HTTPDemon currentHttpd = (HTTPDemon)cmdObj;
// get the connection properties of this session
final Properties conProp = (Properties) currentHttpd.getConProp().clone();
// get the destination host
dest = conProp.getProperty(HeaderFramework.CONNECTION_PROP_HOST);
if (dest==null)continue;
}
if ((dest != null) && (dest.equals(virtualHost))) dest = sb.peers.mySeed().getName() + ".yacy";
// determining if the source is a yacy host
yacySeed seed = null;
if (doNameLookup) {
seed = sb.peers.lookupByIP(userAddress,true,false,false);
if (seed != null) {
if ((seed.hash.equals(sb.peers.mySeed().hash)) &&
(!seed.get(yacySeed.PORT,"").equals(Integer.toString(userPort)))) {
seed = null;
}
// get the destination host
dest = conProp.getProperty(HeaderFramework.CONNECTION_PROP_HOST);
if (dest==null)continue;
}
if ((dest != null) && (dest.equals(virtualHost))) dest = sb.peers.mySeed().getName() + ".yacy";
// determining if the source is a yacy host
yacySeed seed = null;
if (doNameLookup) {
seed = sb.peers.lookupByIP(userAddress,true,false,false);
if (seed != null) {
if ((seed.hash.equals(sb.peers.mySeed().hash)) &&
(!seed.get(yacySeed.PORT,"").equals(Integer.toString(userPort)))) {
seed = null;
}
}
prop.put("list_" + idx + "_dark", dark ? "1" : "0");
dark=!dark;
try {
prop.put("list_" + idx + "_serverSessionID",URLEncoder.encode(s.getName(),"UTF8"));
} catch (final UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
prop.putHTML("list_" + idx + "_sessionName", s.getName());
prop.put("list_" + idx + "_proto", prot);
if (sessionTime > 1000*60) {
prop.put("list_" + idx + "_ms", "0");
prop.put("list_" + idx + "_ms_duration",DateFormatter.formatInterval(sessionTime));
} else {
prop.put("list_" + idx + "_ms", "1");
prop.putNum("list_" + idx + "_ms_duration", sessionTime);
}
prop.putHTML("list_" + idx + "_source",(seed!=null)?seed.getName()+".yacy":userAddress.getHostAddress()+":"+userPort);
prop.putHTML("list_" + idx + "_dest",(dest==null)?"-":dest);
if (blockingRequest) {
prop.put("list_" + idx + "_running", "0");
prop.putNum("list_" + idx + "_running_reqNr", commandCount+1);
numActivePending++;
} else {
prop.put("list_" + idx + "_running", "1");
prop.put("list_" + idx + "_running_command", commandLine==null ? "" :commandLine);
numActiveRunning++;
}
prop.putNum("list_" + idx + "_used", commandCount);
idx++;
}
prop.put("list_" + idx + "_dark", dark ? "1" : "0");
dark=!dark;
try {
prop.put("list_" + idx + "_serverSessionID",URLEncoder.encode(s.getName(),"UTF8"));
} catch (final UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
prop.putHTML("list_" + idx + "_sessionName", s.getName());
prop.put("list_" + idx + "_proto", prot);
if (sessionTime > 1000*60) {
prop.put("list_" + idx + "_ms", "0");
prop.put("list_" + idx + "_ms_duration",DateFormatter.formatInterval(sessionTime));
} else {
prop.put("list_" + idx + "_ms", "1");
prop.putNum("list_" + idx + "_ms_duration", sessionTime);
}
prop.putHTML("list_" + idx + "_source",(seed!=null)?seed.getName()+".yacy":userAddress.getHostAddress()+":"+userPort);
prop.putHTML("list_" + idx + "_dest",(dest==null)?"-":dest);
if (blockingRequest) {
prop.put("list_" + idx + "_running", "0");
prop.putNum("list_" + idx + "_running_reqNr", commandCount+1);
numActivePending++;
} else {
prop.put("list_" + idx + "_running", "1");
prop.put("list_" + idx + "_running_command", commandLine==null ? "" :commandLine);
numActiveRunning++;
}
prop.putNum("list_" + idx + "_used", commandCount);
idx++;
}
prop.put("list", idx);

@ -44,9 +44,11 @@ import java.net.Socket;
import java.net.SocketException;
import java.nio.channels.ClosedByInterruptException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import javax.net.ssl.HandshakeCompletedEvent;
@ -90,18 +92,18 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
public static final String LF_STRING = new String(new byte[]{LF});
public static final Class<?>[] stringType = {"".getClass()}; // set up some reflection
public static final long startupTime = System.currentTimeMillis();
public static final ThreadGroup sessionThreadGroup = new ThreadGroup("sessionThreadGroup");
protected static final HashMap<String, Object> commandObjMethodCache = new HashMap<String, Object>(5);
private static final ThreadGroup sessionThreadGroup = new ThreadGroup("sessionThreadGroup");
private static final HashMap<String, Object> commandObjMethodCache = new HashMap<String, Object>(5);
/**
* will be increased with each session and is used to return a hash code
*/
static int sessionCounter = 0;
private static int sessionCounter = 0;
// static variables
private static final long keepAliveTimeout = 60000; // time that a connection is kept alive if requested with a keepAlive statement
public static final Boolean TERMINATE_CONNECTION = Boolean.FALSE;
public static final Boolean RESUME_CONNECTION = Boolean.TRUE;
private static final long keepAliveTimeout = 60000; // time that a connection is kept alive if requested with a keepAlive statement
public static final Boolean TERMINATE_CONNECTION = Boolean.FALSE;
public static final Boolean RESUME_CONNECTION = Boolean.TRUE;
/**
* for brute-force prevention
@ -120,18 +122,18 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
/**
* specifies if the server should try to do a restart
*/
public boolean forceRestart = false;
private boolean forceRestart = false;
public static boolean useStaticIP = false;
private SSLSocketFactory sslSocketFactory = null;
private ServerSocket socket; // listener
private final int timeout; // connection time-out of the socket
serverHandler handlerPrototype; // the command class (a serverHandler)
private serverHandler handlerPrototype; // the command class (a serverHandler)
private final serverSwitch switchboard; // the command class switchboard
HashMap<String, String> denyHost;
int commandMaxLength;
private HashMap<String, String> denyHost;
private int commandMaxLength;
private int maxBusySessions;
private long lastAutoTermination;
@ -203,7 +205,7 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
this.sslSocketFactory = initSSLFactory();
// init session parameter
maxBusySessions = Math.max(1, Integer.valueOf(switchboard.getConfig("httpdMaxBusySessions","100")).intValue());
this.maxBusySessions = Math.max(1, Integer.valueOf(switchboard.getConfig("httpdMaxBusySessions","100")).intValue());
this.lastAutoTermination = System.currentTimeMillis();
@ -448,6 +450,17 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
this.log.logConfig("* terminated");
}
public List<Session> getJobList() {
final Thread[] threadList = new Thread[sessionThreadGroup.activeCount()];
serverCore.sessionThreadGroup.enumerate(threadList);
ArrayList<Session> l = new ArrayList<Session>();
for (Thread t: threadList) {
if (t == null) continue;
l.add((Session) t);
}
return l;
}
public int getJobCount() {
return sessionThreadGroup.activeCount();
}
@ -786,6 +799,7 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
break;
}
// check if we should still keep this alive:
if (sessionThreadGroup.activeCount() > maxBusySessions / 2) break;
// the more connections are alive, the shorter the keep alive timeout
situationDependentKeepAliveTimeout = keepAliveTimeout / Math.max(1, sessionThreadGroup.activeCount() - 20);
} // end of while

@ -488,15 +488,9 @@ public class serverSwitch {
public String[] sessionsOlderThan(String threadName, long timeout) {
ArrayList<String> list = new ArrayList<String>();
final WorkflowThread st = getThread(threadName);
final Thread[] threadList = new Thread[((serverCore) st).getJobCount()];
serverCore.sessionThreadGroup.enumerate(threadList);
for (Thread t: threadList) {
if (t == null) continue;
if (!(t instanceof serverCore.Session)) continue;
if (!t.isAlive()) continue;
if (t == null) continue;
final Session s = (Session) t;
for (Session s: ((serverCore) st).getJobList()) {
if (!s.isAlive()) continue;
if (s.getTime() > timeout) {
list.add(s.getName());
}
@ -507,34 +501,28 @@ public class serverSwitch {
public void closeSessions(String threadName, String sessionName) {
if (sessionName == null) return;
final WorkflowThread st = getThread(threadName);
final Thread[] threadList = new Thread[((serverCore) st).getJobCount()];
serverCore.sessionThreadGroup.enumerate(threadList);
for (Thread t: threadList) {
for (Session s: ((serverCore) st).getJobList()) {
if (
(t != null) &&
(t instanceof serverCore.Session) &&
(t.isAlive()) &&
(t.getName().equals(sessionName))
(s.isAlive()) &&
(s.getName().equals(sessionName))
) {
// try to stop session
((Session)t).setStopped(true);
s.setStopped(true);
try { Thread.sleep(100); } catch (final InterruptedException ex) {}
// try to interrupt session
if (t.isAlive()) {
t.interrupt();
try { Thread.sleep(100); } catch (final InterruptedException ex) {}
}
s.interrupt();
try { Thread.sleep(100); } catch (final InterruptedException ex) {}
// try to close socket
if (t.isAlive()) {
((Session)t).close();
if (s.isAlive()) {
s.close();
}
// wait for session to finish
if (t.isAlive()) {
try { t.join(500); } catch (final InterruptedException ex) {}
if (s.isAlive()) {
try { s.join(500); } catch (final InterruptedException ex) {}
}
}
}

Loading…
Cancel
Save