From 47b8369b2681fb26dc733a5a6e7f39fc292adb52 Mon Sep 17 00:00:00 2001 From: Arndt Brenschede Date: Fri, 28 Feb 2014 20:08:09 +0100 Subject: [PATCH] route server with threadpool --- .../java/btools/router/RoutingEngine.java | 6 +- .../java/btools/mapaccess/NodesCache.java | 2 +- .../main/java/btools/server/RouteServer.java | 156 +++++------------- .../btools/server/request/YoursHandler.java | 69 -------- 4 files changed, 47 insertions(+), 186 deletions(-) delete mode 100644 brouter-server/src/main/java/btools/server/request/YoursHandler.java diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 36fd442..e374ab8 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -186,6 +186,11 @@ public class RoutingEngine extends Thread } finally { + if ( nodesCache != null ) + { + nodesCache.close(); + nodesCache = null; + } openSet.clear(); finished = true; // this signals termination to outside } @@ -195,7 +200,6 @@ public class RoutingEngine extends Thread { boolean oom_carsubset_hint = nodesCache == null ? false : nodesCache.oom_carsubset_hint; nodesMap = null; - nodesCache = null; terminate(); return oom_carsubset_hint ? "\nPlease use 'carsubset' maps for long-distance car-routing" : ""; } diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index b1a09b9..1ecfcb3 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -241,7 +241,7 @@ public final class NodesCache { try { - f.ra.close(); + if ( f != null ) f.ra.close(); } catch( IOException ioe ) { diff --git a/brouter-server/src/main/java/btools/server/RouteServer.java b/brouter-server/src/main/java/btools/server/RouteServer.java index 9879ca8..46dd2a9 100644 --- a/brouter-server/src/main/java/btools/server/RouteServer.java +++ b/brouter-server/src/main/java/btools/server/RouteServer.java @@ -9,9 +9,11 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; +import java.net.InetAddress; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; import java.util.StringTokenizer; import btools.router.OsmNodeNamed; @@ -20,84 +22,21 @@ import btools.router.RoutingContext; import btools.router.RoutingEngine; import btools.server.request.RequestHandler; import btools.server.request.ServerHandler; -import btools.server.request.YoursHandler; public class RouteServer extends Thread { public ServiceContext serviceContext; - public short port = 17777; - private ServerSocket serverSocket = null; + private Socket clientSocket = null; + private RoutingEngine cr = null; - public void close() + public void stopRouter() { - try - { - ServerSocket ss = serverSocket; - serverSocket = null; - ss.close(); - } - catch( Throwable t ) {} + RoutingEngine e = cr; + if ( e != null ) e.terminate(); } - - private void killOtherServer() throws Exception - { - Socket socket = new Socket( "localhost", port ); - BufferedWriter bw = null; - try - { - bw = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); - bw.write( "EXIT\n" ); - } - finally - { - bw.close(); - socket.close(); - } - } - + public void run() - { - // first go an kill any other server on that port - - for(;;) - { - try - { - killOtherServer(); - System.out.println( "killed, waiting" ); - try { Thread.sleep( 3000 ); } catch( InterruptedException ie ) {} - } - catch( Throwable t ) { - System.out.println( "not killed: " + t ); - break; - } - } - try - { - serverSocket = new ServerSocket(port); - for(;;) - { - System.out.println("RouteServer accepting connections.."); - Socket clientSocket = serverSocket.accept(); - if ( !serveRequest( clientSocket ) ) break; - } - } - catch( Throwable e ) - { - System.out.println("RouteServer main loop got exception (exiting): "+e); - if ( serverSocket != null ) - { - try { serverSocket.close(); } catch( Throwable t ) {} - } - System.exit(0); - } - - } - - - - public boolean serveRequest( Socket clientSocket ) { BufferedReader br = null; BufferedWriter bw = null; @@ -108,15 +47,14 @@ public class RouteServer extends Thread // we just read the first line String getline = br.readLine(); - if ( getline == null || getline.startsWith( "EXIT") ) + if ( getline == null || getline.startsWith("GET /favicon.ico") ) { - throw new RuntimeException( "socketExitRequest" ); - } - if ( getline.startsWith("GET /favicon.ico") ) - { - return true; + return; } + InetAddress ip = clientSocket.getInetAddress(); + System.out.println( "ip=" + (ip==null ? "null" : ip.toString() ) + " -> " + getline ); + String url = getline.split(" ")[1]; HashMap params = getUrlParams(url); @@ -129,12 +67,12 @@ public class RouteServer extends Thread } else { - handler = new YoursHandler( serviceContext, params ); + throw new IllegalArgumentException( "unknown request syntax: " + getline ); } RoutingContext rc = handler.readRoutingContext(); List wplist = handler.readWayPointList(); - RoutingEngine cr = new RoutingEngine( null, null, serviceContext.segmentDir, wplist, rc ); + cr = new RoutingEngine( null, null, serviceContext.segmentDir, wplist, rc ); cr.quite = true; cr.doRun( maxRunningTime ); @@ -162,74 +100,62 @@ public class RouteServer extends Thread } catch (Throwable e) { - if ( "socketExitRequest".equals( e.getMessage() ) ) - { - return false; - } System.out.println("RouteServer got exception (will continue): "+e); e.printStackTrace(); } finally { + cr = null; if ( br != null ) try { br.close(); } catch( Exception e ) {} if ( bw != null ) try { bw.close(); } catch( Exception e ) {} + if ( clientSocket != null ) try { clientSocket.close(); } catch( Exception e ) {} } - return true; } public static void main(String[] args) throws Exception { System.out.println("BRouter 0.98 / 12012014 / abrensch"); - if ( args.length != 3 ) + if ( args.length != 4 ) { - System.out.println("serve YOURS protocol for BRouter"); - System.out.println("usage: java RouteServer "); - System.out.println(""); System.out.println("serve BRouter protocol"); - System.out.println("usage: java RouteServer "); + System.out.println("usage: java RouteServer "); return; } ServiceContext serviceContext = new ServiceContext(); serviceContext.segmentDir = args[0]; - File profileMapOrDir = new File( args[1] ); - if ( profileMapOrDir.isDirectory() ) - { - System.setProperty( "profileBaseDir", args[1] ); - } - else - { - serviceContext.profileMap = loadProfileMap( profileMapOrDir ); - } + System.setProperty( "profileBaseDir", args[1] ); + + int maxthreads = Integer.parseInt( args[3] ); + + TreeMap threadMap = new TreeMap(); ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[2])); + long last_ts = 0; for (;;) { Socket clientSocket = serverSocket.accept(); RouteServer server = new RouteServer(); server.serviceContext = serviceContext; - server.serveRequest( clientSocket ); + server.clientSocket = clientSocket; + + // kill thread if limit reached + if ( threadMap.size() >= maxthreads ) + { + Long k = threadMap.firstKey(); + RouteServer victim = threadMap.get( k ); + threadMap.remove( k ); + victim.stopRouter(); + } + + long ts = System.currentTimeMillis(); + while ( ts <= last_ts ) ts++; + threadMap.put( Long.valueOf( ts ), server ); + last_ts = ts; + server.start(); } } - private static Map loadProfileMap( File file ) throws IOException - { - Map profileMap = new HashMap(); - - BufferedReader pr = new BufferedReader( new InputStreamReader( new FileInputStream( file ) ) ); - for(;;) - { - String key = pr.readLine(); - if ( key == null ) break; - key = key.trim(); - if ( key.length() == 0 ) continue; - String value = pr.readLine(); - value = value.trim(); - profileMap.put( key, value ); - } - pr.close(); - return profileMap; - } private static HashMap getUrlParams( String url ) { diff --git a/brouter-server/src/main/java/btools/server/request/YoursHandler.java b/brouter-server/src/main/java/btools/server/request/YoursHandler.java deleted file mode 100644 index 4c28634..0000000 --- a/brouter-server/src/main/java/btools/server/request/YoursHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package btools.server.request; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import btools.router.OsmNodeNamed; -import btools.router.OsmTrack; -import btools.router.RoutingContext; -import btools.server.ServiceContext; - -public class YoursHandler extends RequestHandler { - - public YoursHandler( ServiceContext serviceContext, HashMap params ) - { - super(serviceContext, params); - } - - @Override - public RoutingContext readRoutingContext() - { - RoutingContext rc = new RoutingContext(); - - String profile_key = params.get( "v" ) + " " + params.get( "fast" ); - if (serviceContext.profileMap == null) throw new IllegalArgumentException( "no profile map loaded" ); - String profile_path = serviceContext.profileMap.get( profile_key ); - if ( profile_path == null ) profile_path = serviceContext.profileMap.get( "default" ); - if ( profile_path == null ) throw new IllegalArgumentException( "no profile for key: " + profile_key ); - rc.localFunction = profile_path; - - List nogoList = serviceContext.nogoList; - if ( nogoList != null ) - { - rc.prepareNogoPoints( nogoList ); - rc.nogopoints = nogoList; - } - - return rc; - } - - @Override - public List readWayPointList() - { - List wplist = new ArrayList(); - wplist.add( readPosition( params, "flon", "flat", "from" ) ); - wplist.add( readPosition( params, "tlon", "tlat", "to" ) ); - return wplist; - } - - @Override - public String formatTrack(OsmTrack track) - { - return track.formatAsKml(); - } - - private static OsmNodeNamed readPosition( HashMap params, String plon, String plat, String name ) - { - String vlon = params.get( plon ); - if ( vlon == null ) throw new IllegalArgumentException( "param " + plon + " bot found in input" ); - String vlat = params.get( plat ); - if ( vlat == null ) throw new IllegalArgumentException( "param " + plat + " bot found in input" ); - - OsmNodeNamed n = new OsmNodeNamed(); - n.name = name; - n.ilon = (int)( ( Double.parseDouble( vlon ) + 180. ) *1000000. + 0.5); - n.ilat = (int)( ( Double.parseDouble( vlat ) + 90. ) *1000000. + 0.5); - return n; - } -}