Mercurial Hosting > luan
view src/goodjava/webserver/handlers/DomainHandler.java @ 1493:471ef3e6a84e
more io
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 03 May 2020 00:12:15 -0600 |
parents | 42c07ecb0ddc |
children | 1b809d2fdf03 |
line wrap: on
line source
package goodjava.webserver.handlers; import java.io.Closeable; import java.io.IOException; import java.lang.ref.Reference; //import java.lang.ref.WeakReference; import java.lang.ref.SoftReference; import java.lang.ref.ReferenceQueue; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; import goodjava.webserver.Handler; import goodjava.webserver.Request; import goodjava.webserver.Response; public final class DomainHandler implements Handler { private static final Logger logger = LoggerFactory.getLogger(DomainHandler.class); public interface Factory { public Handler newHandler(String domain); } private static class MyTask extends TimerTask { private final Set<Handler> dontGc; MyTask(Set<Handler> dontGc) { this.dontGc = dontGc; } public void run() { dontGc.clear(); logger.info("dontGc.clear()"); } } private static final long HOUR = 1000L*60*60; private final Map<String,Reference<Handler>> map = new HashMap<String,Reference<Handler>>(); private final Set<Handler> dontGc = ConcurrentHashMap.newKeySet(); private final Timer timer = new Timer(); private final Factory factory; public DomainHandler(Factory factory) { this.factory = factory; timer.schedule(new MyTask(dontGc),HOUR,HOUR); } protected void finalize() throws Throwable { timer.cancel(); } public Response handle(Request request) { String host = (String)request.headers.get("host"); if( host == null ) return null; int i = host.indexOf(':'); String domain = i == -1 ? host : host.substring(0,i); Handler handler = getHandler(domain); if( handler==null ) return null; dontGc.add(handler); return handler.handle(request); } public Handler getHandler(String domain) { domain = domain.toLowerCase(); synchronized(map) { Reference<Handler> ref = map.get(domain); Handler handler = ref==null ? null : ref.get(); if( handler == null ) { //if(ref!=null) logger.info("gc "+domain); handler = factory.newHandler(domain); if( handler == null ) return null; map.put(domain,new SoftReference<Handler>(handler)); } return handler; } } public void removeHandler(String domain) { //logger.info("removeHandler "+domain); domain = domain.toLowerCase(); synchronized(map) { Reference<Handler> ref = map.remove(domain); Handler handler = ref==null ? null : ref.get(); if( handler != null ) { close(handler); } } } private static void close(Handler handler) { if( handler instanceof Closeable ) { try { ((Closeable)handler).close(); } catch(IOException e) { logger.error(handler.toString(),e); } } } }