Mercurial Hosting > luan
comparison src/luan/lib/webserver/handlers/DomainHandler.java @ 1401:ef1620aa99cb
fix gc issues
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 16 Sep 2019 22:51:41 -0400 |
parents | 221eedb0f54e |
children |
comparison
equal
deleted
inserted
replaced
1400:221eedb0f54e | 1401:ef1620aa99cb |
---|---|
1 package luan.lib.webserver.handlers; | 1 package luan.lib.webserver.handlers; |
2 | 2 |
3 import java.io.Closeable; | 3 import java.io.Closeable; |
4 import java.io.IOException; | 4 import java.io.IOException; |
5 import java.lang.ref.Reference; | 5 import java.lang.ref.Reference; |
6 import java.lang.ref.WeakReference; | 6 //import java.lang.ref.WeakReference; |
7 import java.lang.ref.SoftReference; | 7 import java.lang.ref.SoftReference; |
8 import java.lang.ref.ReferenceQueue; | 8 import java.lang.ref.ReferenceQueue; |
9 import java.util.Map; | 9 import java.util.Map; |
10 import java.util.HashMap; | 10 import java.util.HashMap; |
11 import luan.lib.logging.Logger; | 11 import luan.lib.logging.Logger; |
20 | 20 |
21 public interface Factory { | 21 public interface Factory { |
22 public Handler newHandler(String domain); | 22 public Handler newHandler(String domain); |
23 } | 23 } |
24 | 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 | |
35 private class MyReference extends WeakReference<Ref> { | |
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) { | 25 private static void close(Handler handler) { |
45 if( handler instanceof Closeable ) { | 26 if( handler instanceof Closeable ) { |
46 try { | 27 try { |
47 ((Closeable)handler).close(); | 28 ((Closeable)handler).close(); |
48 } catch(IOException e) { | 29 } catch(IOException e) { |
49 logger.error(handler.toString(),e); | 30 logger.error(handler.toString(),e); |
50 } | 31 } |
51 } | 32 } |
52 } | 33 } |
53 | 34 |
54 private void sweep() { | 35 private final Map<String,Reference<Handler>> map = new HashMap<String,Reference<Handler>>(); |
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 | 36 |
67 private final Factory factory; | 37 private final Factory factory; |
68 | 38 |
69 public DomainHandler(Factory factory) { | 39 public DomainHandler(Factory factory) { |
70 this.factory = factory; | 40 this.factory = factory; |
79 Handler handler = getHandler(domain); | 49 Handler handler = getHandler(domain); |
80 return handler==null ? null : handler.handle(request); | 50 return handler==null ? null : handler.handle(request); |
81 } | 51 } |
82 | 52 |
83 public Handler getHandler(String domain) { | 53 public Handler getHandler(String domain) { |
84 Ref r = getRef(domain); | 54 domain = domain.toLowerCase(); |
85 return r==null ? null : r.handler; | 55 synchronized(map) { |
56 Reference<Handler> ref = map.get(domain); | |
57 Handler handler = ref==null ? null : ref.get(); | |
58 if( handler == null ) { | |
59 //if(ref!=null) logger.info("gc "+domain); | |
60 handler = factory.newHandler(domain); | |
61 if( handler == null ) | |
62 return null; | |
63 map.put(domain,new SoftReference<Handler>(handler)); | |
64 } | |
65 return handler; | |
66 } | |
86 } | 67 } |
87 | 68 |
88 public void removeHandler(String domain) { | 69 public void removeHandler(String domain) { |
70 logger.info("removeHandler "+domain); | |
89 domain = domain.toLowerCase(); | 71 domain = domain.toLowerCase(); |
90 synchronized(map) { | 72 synchronized(map) { |
91 Reference<Ref> ref = map.remove(domain); | 73 Reference<Handler> ref = map.remove(domain); |
92 Ref r = ref==null ? null : ref.get(); | 74 Handler handler = ref==null ? null : ref.get(); |
93 if( r != null ) { | 75 if( handler != null ) { |
94 close(r.handler); | 76 close(handler); |
95 } | 77 } |
96 } | 78 } |
97 } | 79 } |
98 | 80 |
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 } | 81 } |