2323import java .util .Iterator ;
2424import java .util .List ;
2525import java .util .concurrent .ConcurrentHashMap ;
26+ import java .util .concurrent .atomic .AtomicReference ;
2627
2728/**
2829 * <p>
@@ -33,9 +34,11 @@ public class DnsPrefetcher {
3334
3435 public static DnsPrefetcher dnsPrefetcher = null ;
3536 private static String token ;
37+ private static Configuration config ;
3638
3739 private static ConcurrentHashMap <String , List <InetAddress >> mConcurrentHashMap = new ConcurrentHashMap <String , List <InetAddress >>();
3840 private static List <String > mHosts = new ArrayList <String >();
41+ private static AtomicReference mDnsCacheKey = new AtomicReference ();
3942
4043 private DnsPrefetcher () {
4144
@@ -52,10 +55,33 @@ public static DnsPrefetcher getDnsPrefetcher() {
5255 return dnsPrefetcher ;
5356 }
5457
55- public DnsPrefetcher init (String token ) throws UnknownHostException {
58+ /**
59+ * 不用判断是否预取,每次调用UploadManager都直接预取一次。
60+ * uploadManager只会new一次,但是uploadManager.put方法有多次,如果期间网络发生变化
61+ * 这个方法预取的结果应该被ConcurrentHashMap自动覆盖
62+ */
63+ public void localFetch () {
64+ List <String > localHosts = new ArrayList <String >();
65+ //local
66+ List <ZoneInfo > listZoneinfo = getLocalZone ();
67+ for (ZoneInfo zone : listZoneinfo ) {
68+ for (String host : zone .upDomainsList ) {
69+ localHosts .add (host );
70+ }
71+ }
72+ localHosts .add (Config .preQueryHost );
73+
74+ if (localHosts != null && localHosts .size () > 0 )
75+ preFetch (localHosts );
76+ }
77+
78+
79+ public DnsPrefetcher init (String token , Configuration config ) throws UnknownHostException {
5680 this .token = token ;
57- preHosts ();
58- preFetch ();
81+ this .config = config ;
82+ List <String > preHosts = preHosts ();
83+ if (preHosts != null && preHosts .size () > 0 )
84+ preFetch (preHosts );
5985 return this ;
6086 }
6187
@@ -86,43 +112,47 @@ public List<InetAddress> getInetAddressByHost(String host) {
86112 return mConcurrentHashMap .get (host );
87113 }
88114
89- private void preHosts () {
115+ private List < String > preHosts () {
90116 HashSet <String > set = new HashSet <String >();
91-
117+ List < String > preHosts = new ArrayList <>();
92118 //preQuery sync
93119 ZoneInfo zoneInfo = getPreQueryZone ();
94120 if (zoneInfo != null ) {
95121 for (String host : zoneInfo .upDomainsList ) {
96122 if (set .add (host ))
97- mHosts .add (host );
123+ preHosts .add (host );
98124 }
99125 }
126+
100127 //local
101128 List <ZoneInfo > listZoneinfo = getLocalZone ();
102129 for (ZoneInfo zone : listZoneinfo ) {
103130 for (String host : zone .upDomainsList ) {
104131 if (set .add (host ))
105- mHosts .add (host );
132+ preHosts .add (host );
106133 }
107134 }
108135 if (set .add (Config .preQueryHost ))
109- mHosts .add (Config .preQueryHost );
136+ preHosts .add (Config .preQueryHost );
137+ return preHosts ;
110138 }
111139
112140
113- private void preFetch () {
141+ private void preFetch (List < String > fetchHost ) {
114142 List <String > rePreHosts = new ArrayList <String >();
115- for (String host : mHosts ) {
143+ for (String host : fetchHost ) {
116144 List <InetAddress > inetAddresses = null ;
117145 try {
118146 inetAddresses = okhttp3 .Dns .SYSTEM .lookup (host );
119147 mConcurrentHashMap .put (host , inetAddresses );
148+ mHosts .add (host );
120149 } catch (UnknownHostException e ) {
121150 e .printStackTrace ();
122151 rePreHosts .add (host );
123152 }
124153 }
125- rePreFetch (rePreHosts , null );
154+ if (rePreHosts .size () > 0 )
155+ rePreFetch (rePreHosts , null );
126156 }
127157
128158 /**
@@ -151,6 +181,7 @@ private boolean rePreFetch(String host, Dns customeDns) {
151181 inetAddresses = customeDns .lookup (host );
152182 }
153183 mConcurrentHashMap .put (host , inetAddresses );
184+ mHosts .add (host );
154185 return true ;
155186 } catch (UnknownHostException e ) {
156187 e .printStackTrace ();
@@ -214,7 +245,11 @@ ZoneInfo preQueryIndex(DnsPrefetcher.ZoneIndex index) {
214245
215246 ResponseInfo getZoneJsonSync (DnsPrefetcher .ZoneIndex index ) {
216247 Client client = new Client ();
217- String address = "http://" + Config .preQueryHost + "/v2/query?ak=" + index .accessKey + "&bucket=" + index .bucket ;
248+ String schema = "https://" ;
249+ if (!config .useHttps ) {
250+ schema = "http://" ;
251+ }
252+ String address = schema + Config .preQueryHost + "/v2/query?ak=" + index .accessKey + "&bucket=" + index .bucket ;
218253 return client .syncGet (address , null );
219254 }
220255
@@ -264,6 +299,33 @@ public boolean equals(Object obj) {
264299 * @return true:重新预期并缓存, false:不需要重新预取和缓存
265300 */
266301 public static boolean checkRePrefetchDns (String token , Configuration config ) {
302+ if (mDnsCacheKey .get () == null )
303+ return true ;
304+
305+ String currentTime = String .valueOf (System .currentTimeMillis ());
306+ String localip = AndroidNetwork .getHostIP ();
307+ String akScope = StringUtils .getAkAndScope (token );
308+
309+ if (currentTime == null || localip == null || akScope == null )
310+ return true ;
311+ DnsCacheKey dnsCacheKey = (DnsCacheKey ) mDnsCacheKey .get ();
312+ if (dnsCacheKey == null || dnsCacheKey .getCurrentTime () == null )
313+ return true ;
314+ long cacheTime = (Long .parseLong (currentTime ) - Long .parseLong (dnsCacheKey .getCurrentTime ())) / 1000 ;
315+ if (!localip .equals (dnsCacheKey .getLocalIp ()) || cacheTime > config .dnsCacheTimeMs || !akScope .equals (dnsCacheKey .getAkScope ())) {
316+ return true ;
317+ }
318+
319+ return false ;
320+ }
321+
322+ /**
323+ * uploadManager初始化时,加载本地缓存到内存
324+ *
325+ * @param config
326+ * @return 如果不存在缓存返回true,需要重新预取;如果存在且满足使用,返回false
327+ */
328+ public static boolean recoverCache (Configuration config ) {
267329 Recorder recorder = null ;
268330 try {
269331 recorder = new DnsCacheFile (Config .dnscacheDir );
@@ -285,15 +347,14 @@ public static boolean checkRePrefetchDns(String token, Configuration config) {
285347
286348 String currentTime = String .valueOf (System .currentTimeMillis ());
287349 String localip = AndroidNetwork .getHostIP ();
288- String akScope = StringUtils .getAkAndScope (token );
289350
290- if (currentTime == null || localip == null || akScope == null )
351+ if (currentTime == null || localip == null )
291352 return true ;
292353 long cacheTime = (Long .parseLong (currentTime ) - Long .parseLong (cacheKey .getCurrentTime ())) / 1000 ;
293- if (!cacheKey .getLocalIp ().equals (localip ) || cacheTime > config .dnsCacheTimeMs || ! cacheKey . getAkScope (). equals ( akScope ) ) {
354+ if (!cacheKey .getLocalIp ().equals (localip ) || cacheTime > config .dnsCacheTimeMs ) {
294355 return true ;
295356 }
296-
357+ mDnsCacheKey . set ( cacheKey );
297358 return recoverDnsCache (data );
298359 }
299360
@@ -308,12 +369,16 @@ public static void startPrefetchDns(String token, Configuration config) {
308369 String akScope = StringUtils .getAkAndScope (token );
309370 if (currentTime == null || localip == null || akScope == null )
310371 return ;
311- String cacheKey = new DnsCacheKey (currentTime , localip , akScope ).toString ();
372+ DnsCacheKey dnsCacheKey = new DnsCacheKey (currentTime , localip , akScope );
373+ String cacheKey = dnsCacheKey .toString ();
374+
312375 Recorder recorder = null ;
313376 DnsPrefetcher dnsPrefetcher = null ;
314377 try {
315378 recorder = new DnsCacheFile (Config .dnscacheDir );
316- dnsPrefetcher = DnsPrefetcher .getDnsPrefetcher ().init (token );
379+ dnsPrefetcher = DnsPrefetcher .getDnsPrefetcher ().init (token , config );
380+ //确认预取结束后,需要更新缓存mDnsCacheKey
381+ mDnsCacheKey .set (dnsCacheKey );
317382 } catch (IOException e ) {
318383 e .printStackTrace ();
319384 return ;
0 commit comments