Mercurial Hosting > luan
annotate src/luan/lib/webserver/handlers/DomainHandler.java @ 1400:221eedb0f54e
fix inner class gc bug
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 13 Sep 2019 05:05:51 -0600 |
parents | 643cf1c37723 |
children | ef1620aa99cb |
rev | line source |
---|---|
1347
643cf1c37723
move webserver to lib and bug fixes
Franklin Schmidt <fschmidt@gmail.com>
parents:
1337
diff
changeset
|
1 package luan.lib.webserver.handlers; |
1315 | 2 |
3 import java.io.Closeable; | |
4 import java.io.IOException; | |
5 import java.lang.ref.Reference; | |
1400
221eedb0f54e
fix inner class gc bug
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
6 import java.lang.ref.WeakReference; |
1315 | 7 import java.lang.ref.SoftReference; |
8 import java.lang.ref.ReferenceQueue; | |
9 import java.util.Map; | |
10 import java.util.HashMap; | |
1337 | 11 import luan.lib.logging.Logger; |
12 import luan.lib.logging.LoggerFactory; | |
1347
643cf1c37723
move webserver to lib and bug fixes
Franklin Schmidt <fschmidt@gmail.com>
parents:
1337
diff
changeset
|
13 import luan.lib.webserver.Handler; |
643cf1c37723
move webserver to lib and bug fixes
Franklin Schmidt <fschmidt@gmail.com>
parents:
1337
diff
changeset
|
14 import luan.lib.webserver.Request; |
643cf1c37723
move webserver to lib and bug fixes
Franklin Schmidt <fschmidt@gmail.com>
parents:
1337
diff
changeset
|
15 import luan.lib.webserver.Response; |
1315 | 16 |
17 | |
18 public final class DomainHandler implements Handler { | |
19 private static final Logger logger = LoggerFactory.getLogger(DomainHandler.class); | |
20 | |
21 public interface Factory { | |
22 public Handler newHandler(String domain); | |
23 } | |
24 | |
25 private static class Ref { | |
26 private final Handler handler; | |
27 | |
28 private Ref(Handler handler) { | |
29 this.handler = handler; | |
30 } | |
31 } | |
32 | |
33 private final ReferenceQueue<Ref> queue = new ReferenceQueue<Ref>(); | |
34 | |
1400
221eedb0f54e
fix inner class gc bug
Franklin Schmidt <fschmidt@gmail.com>
parents:
1347
diff
changeset
|
35 private class MyReference extends WeakReference<Ref> { |
1315 | 36 private Handler handler; |
37 | |
38 private MyReference(Ref r) { | |
39 super(r,queue); | |
40 this.handler = r.handler; | |
41 } | |
42 } | |
43 | |
44 private static void close(Handler handler) { | |
45 if( handler instanceof Closeable ) { | |
46 try { | |
47 ((Closeable)handler).close(); | |
48 } catch(IOException e) { | |
49 logger.error(handler.toString(),e); | |
50 } | |
51 } | |
52 } | |
53 | |
54 private void sweep() { | |
55 while(true) { | |
56 MyReference ref = (MyReference)queue.poll(); | |
57 if( ref == null ) | |
58 return; | |
59 //logger.info("sweep"); | |
60 close(ref.handler); | |
61 ref.handler = null; | |
62 } | |
63 } | |
64 | |
65 private final Map<String,MyReference> map = new HashMap<String,MyReference>(); | |
66 | |
67 private final Factory factory; | |
68 | |
69 public DomainHandler(Factory factory) { | |
70 this.factory = factory; | |
71 } | |
72 | |
73 public Response handle(Request request) { | |
74 String host = (String)request.headers.get("host"); | |
1331 | 75 if( host == null ) |
76 return null; | |
1315 | 77 int i = host.indexOf(':'); |
78 String domain = i == -1 ? host : host.substring(0,i); | |
79 Handler handler = getHandler(domain); | |
80 return handler==null ? null : handler.handle(request); | |
81 } | |
82 | |
83 public Handler getHandler(String domain) { | |
84 Ref r = getRef(domain); | |
85 return r==null ? null : r.handler; | |
86 } | |
87 | |
88 public void removeHandler(String domain) { | |
89 domain = domain.toLowerCase(); | |
90 synchronized(map) { | |
91 Reference<Ref> ref = map.remove(domain); | |
92 Ref r = ref==null ? null : ref.get(); | |
93 if( r != null ) { | |
94 close(r.handler); | |
95 } | |
96 } | |
97 } | |
98 | |
99 private Ref getRef(String domain) { | |
100 domain = domain.toLowerCase(); | |
101 synchronized(map) { | |
102 Reference<Ref> ref = map.get(domain); | |
103 Ref r = ref==null ? null : ref.get(); | |
104 if( r == null ) { | |
105 //if(ref!=null) logger.info("gc "+domain); | |
106 sweep(); | |
107 Handler handler = factory.newHandler(domain); | |
108 if( handler == null ) | |
109 return null; | |
110 r = new Ref(handler); | |
111 map.put(domain,new MyReference(r)); | |
112 } | |
113 return r; | |
114 } | |
115 } | |
116 | |
117 } |