YH_DNSCacheManager.m 5.58 KB
//
//  YH_DNSCacheManager.m
//  YH_Mall
//
//  Created by jhsonzhi on 16/7/18.
//  Copyright © 2016年 YOHO. All rights reserved.
//

#import "YH_DNSCacheManager.h"
#import "YH_DNSMemoryCache.h"
#import "YH_DNSDomainModel.h"
#import "YH_DNSUtils.h"
#import "YH_DNSHttpDnsPack.h"


@interface YH_DNSCacheManager()

@property (strong, nonatomic) YH_DNSMemoryCache *memoryCacheDic;

@end

@implementation YH_DNSCacheManager

+ (instancetype)sharedInstance {
    static  YH_DNSCacheManager *sharedInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedInstance = [[YH_DNSCacheManager alloc]init];
    });
    return sharedInstance;
}

- (id)init {
    if (self = [super init]) {
        _memoryCacheDic = [YH_DNSMemoryCache sharedInstance];
    }
    return  self;
}

- (NSArray *)getExpireDnsCache {
    @synchronized(self) {
        return [self.memoryCacheDic getExpireDnsCache];
    }
}

- (NSArray *)getAllModels {
    @synchronized(self) {
        return [self.memoryCacheDic getAllModels];
    }
}

- (void)addMemoryCache:(NSString *)hostName model:(YH_DNSDomainModel *)model {
    @synchronized(self) {
        if (model == nil) {
            NSLog(@"ERROR:%s:%d model is nil.", __func__, __LINE__);
            return;
        }
        if (model.ipModelArray == nil || model.ipModelArray.count == 0) {
            NSLog(@"ERROR:%s:%d model.ipModelArray is nil.", __func__, __LINE__);
            return;
        }
        
        for (YH_DNSIpModel *ipModel in model.ipModelArray) {
            if (!ipModel) {
                NSLog(@"WARNING:%s an ipModel in model.ipModelArray is nil.", __func__);
                return;
            }
        }
        
        [self.memoryCacheDic addModel:model keyHost:hostName];
        return;
    }
}

//本函数只用于更新从本地dns获取的ip, 从httpserver 获取的ip 不应该用此函数更新。
//- (void)updateMemoryCache:(NSString *)domain model:(YH_DNSDomainModel *)model
//{
//    @synchronized(self) {
//        if (model == nil) {
//            NSLog(@"ERROR:%s:%d model is nil.", __func__, __LINE__);
//            return;
//        }
//        if (model.ipModelArray == nil || model.ipModelArray.count == 0) {
//            NSLog(@"ERROR:%s:%d model.ipModelArray is nil.", __func__, __LINE__);
//            return;
//        }
//        
//        [self.memoryCacheDic updateModel:model keyHost:domain];
//        return;
//    }
//}

- (NSString *)getRandomIp:(YH_DNSDomainModel *)domainModel{
     @synchronized(self) {
         NSString *randomIp = nil;
         NSInteger modelCount = [domainModel.ipModelArray count];
         if (modelCount > 0) {
             YH_DNSIpModel *ipModel = domainModel.ipModelArray[arc4random()%modelCount];
             randomIp = ipModel.ip;
         }
         return randomIp;
     }
}

- (NSDictionary *)getDnsCacheByHost:(NSString *)hostName {
    //这个锁是防止 多个线程重复的 从数据库取数据插入缓存。
    @synchronized(self) {
        NSMutableDictionary *resultDic = nil;
        
        YH_DNSDomainModel *model = [self.memoryCacheDic getModelByKeyUrl:hostName];
        NSString* source = @"memorycache";
        
        //TODO:读取数据库
        
        if (model != nil) {
            if ([YH_DNSUtils isDomainModelExpired:model]) {
                NSLog(@"INFO:%s:%d model(domain:%@) from %@ is expired.", __func__, __LINE__, model.domain, source);
                return nil;
            } else if (model.ipModelArray == nil || model.ipModelArray.count == 0) {
                NSLog(@"INFO:%s:%d model(domain:%@) from %@ all ip are expired.", __func__, __LINE__, model.domain, source);
                return nil;
            } else {
                //TODO:把数据库里的有效model 存到缓存里。
            }
            
            NSString * resultIpString = [self getRandomIp:model];
            resultDic = [NSMutableDictionary dictionary];
            [resultDic setValue:((!YHDNS_isStrEmpty(resultIpString)) ? resultIpString: @"") forKey:@"ip"];
            [resultDic setValue:@(model.isNeedPreFetch) forKey:@"prefetch"];
        }

        return resultDic;
    }
}

- (YH_DNSDomainModel *)insertDnsCache:(YH_DNSHttpDnsPack *) dnsPack {
    @synchronized(self) {
        YH_DNSDomainModel* model = [[YH_DNSDomainModel alloc]init];
        model.domain = dnsPack.domain;
        
        model.time = [[YH_DNSUtils sharedInstance] stringFromDate:[NSDate date]];
        
        NSInteger t = 60;
        for (YH_DNSIpModel* tempIp in dnsPack.dns) {
            YH_DNSIpModel* ipModel = [[YH_DNSIpModel alloc]init];
            ipModel.ip = tempIp.ip;
            ipModel.ttl = tempIp.ttl;
            ipModel.finally_update_time = [[YH_DNSUtils sharedInstance] stringFromDate:[NSDate date]];
            [model.ipModelArray addObject:ipModel];
            
            if ([ipModel.ttl intValue] < t) {
                t = [ipModel.ttl intValue];
            }
        }
        
        model.ttl = [NSString stringWithFormat:@"%zd", t];
        
        if (model.ipModelArray != nil && model.ipModelArray.count > 0) {
            [self addMemoryCache:model.domain model:model];
        }
        return model;
    }
}

- (YH_DNSIpModel *)findIpModel:(YH_DNSIpModel *)ipModel inArray:(NSArray *)array {
    for (YH_DNSIpModel* modelItem in array) {
        if ([modelItem.ip isEqualToString:ipModel.ip]) {
            return modelItem;
        }
    }
    return nil;
}

- (void)clear {
    @synchronized(self) {
        [self clearMemoryCache];
    }
}

- (void)clearDB{
 
}

- (void)clearMemoryCache {
    @synchronized(self) {
        [self.memoryCacheDic removeAllModels];
    }
}
@end