feat: sync httpdns sdk/platform updates without large binaries

This commit is contained in:
robin
2026-03-04 17:59:14 +08:00
parent 853897a6f8
commit 532891fad0
700 changed files with 6096 additions and 2712 deletions

View File

@@ -0,0 +1,645 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "HttpdnsRequestManager.h"
#import "HttpdnsHostObject.h"
#import "HttpdnsRemoteResolver.h"
#import "HttpdnsLocalResolver.h"
#import "HttpdnsInternalConstant.h"
#import "HttpdnsUtil.h"
#import "HttpdnsLog_Internal.h"
#import "HttpdnsPersistenceUtils.h"
#import "HttpdnsService_Internal.h"
#import "HttpdnsScheduleCenter.h"
#import "HttpdnsService_Internal.h"
#import "HttpdnsReachability.h"
#import "HttpdnsHostRecord.h"
#import "HttpdnsUtil.h"
#import "HttpDnsLocker.h"
#import "HttpdnsRequest_Internal.h"
#import "HttpdnsHostObjectInMemoryCache.h"
#import "HttpdnsIPQualityDetector.h"
#import "HttpdnsIpStackDetector.h"
#import "HttpdnsDB.h"
static dispatch_queue_t _persistentCacheConcurrentQueue = NULL;
static dispatch_queue_t _asyncResolveHostQueue = NULL;
typedef struct {
BOOL isResultUsable;
BOOL isResolvingRequired;
} HostObjectExamingResult;
@interface HttpdnsRequestManager()
@property (nonatomic, strong) dispatch_queue_t cacheQueue;
@property (nonatomic, assign, readwrite) NSInteger accountId;
@property (nonatomic, weak) HttpDnsService *ownerService;
@property (atomic, setter=setPersistentCacheIpEnabled:, assign) BOOL persistentCacheIpEnabled;
@property (atomic, setter=setDegradeToLocalDNSEnabled:, assign) BOOL degradeToLocalDNSEnabled;
@property (atomic, assign) BOOL atomicExpiredIPEnabled;
@property (atomic, assign) BOOL atomicPreResolveAfterNetworkChanged;
@property (atomic, assign) NSTimeInterval lastUpdateTimestamp;
@property (atomic, assign) HttpdnsNetworkStatus lastNetworkStatus;
@end
@implementation HttpdnsRequestManager {
HttpdnsHostObjectInMemoryCache *_hostObjectInMemoryCache;
HttpdnsDB *_httpdnsDB;
}
+ (void)initialize {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_persistentCacheConcurrentQueue = dispatch_queue_create("com.Trust.sdk.httpdns.persistentCacheOperationQueue", DISPATCH_QUEUE_CONCURRENT);
_asyncResolveHostQueue = dispatch_queue_create("com.Trust.sdk.httpdns.asyncResolveHostQueue", DISPATCH_QUEUE_CONCURRENT);
});
}
- (instancetype)initWithAccountId:(NSInteger)accountId ownerService:(HttpDnsService *)service {
if (self = [super init]) {
_accountId = accountId;
_ownerService = service;
HttpdnsReachability *reachability = [HttpdnsReachability sharedInstance];
self.atomicExpiredIPEnabled = NO;
self.atomicPreResolveAfterNetworkChanged = NO;
_hostObjectInMemoryCache = [[HttpdnsHostObjectInMemoryCache alloc] init];
_httpdnsDB = [[HttpdnsDB alloc] initWithAccountId:accountId];
[[HttpdnsIpStackDetector sharedInstance] redetectIpStack];
_lastNetworkStatus = reachability.currentReachabilityStatus;
_lastUpdateTimestamp = [NSDate date].timeIntervalSince1970;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleReachabilityNotification:)
name:kHttpdnsReachabilityChangedNotification
object:reachability];
[reachability startNotifier];
}
return self;
}
- (void)setExpiredIPEnabled:(BOOL)enable {
self.atomicExpiredIPEnabled = enable;
}
- (void)setCachedIPEnabled:(BOOL)enable discardRecordsHasExpiredFor:(NSTimeInterval)duration {
//
[self setPersistentCacheIpEnabled:enable];
if (enable) {
dispatch_async(_persistentCacheConcurrentQueue, ^{
//
[self->_httpdnsDB cleanRecordAlreadExpiredAt:[[NSDate date] timeIntervalSince1970] - duration];
// <EFBFBD><EFBFBD>?
[self loadCacheFromDbToMemory];
});
}
}
- (void)setPreResolveAfterNetworkChanged:(BOOL)enable {
self.atomicPreResolveAfterNetworkChanged = enable;
}
- (void)preResolveHosts:(NSArray *)hosts queryType:(HttpdnsQueryIPType)queryType {
if (![HttpdnsUtil isNotEmptyArray:hosts]) {
return;
}
__weak typeof(self) weakSelf = self;
dispatch_async(_asyncResolveHostQueue, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if ([strongSelf isHostsNumberLimitReached]) {
return;
}
// <EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>?
NSUInteger totalCount = hosts.count;
for (NSUInteger i = 0; i < totalCount; i += HTTPDNS_PRE_RESOLVE_BATCH_SIZE) {
NSUInteger length = MIN(HTTPDNS_PRE_RESOLVE_BATCH_SIZE, totalCount - i);
NSArray *batch = [hosts subarrayWithRange:NSMakeRange(i, length)];
NSString *combinedHostString = [batch componentsJoinedByString:@","];
HttpdnsLogDebug("Pre resolve host by async lookup, hosts: %@", combinedHostString);
HttpdnsRequest *request = [[HttpdnsRequest alloc] initWithHost:combinedHostString queryIpType:queryType];
request.accountId = strongSelf.accountId;
[request becomeNonBlockingRequest];
dispatch_async(_asyncResolveHostQueue, ^{
[strongSelf executePreResolveRequest:request retryCount:0];
});
}
});
}
#pragma mark - core method for all public query API
- (HttpdnsHostObject *)resolveHost:(HttpdnsRequest *)request {
HttpdnsLogDebug("resolveHost, request: %@", request);
NSString *host = request.host;
NSString *cacheKey = request.cacheKey;
if (request.accountId == 0 || request.accountId != self.accountId) {
request.accountId = self.accountId;
}
if ([HttpdnsUtil isEmptyString:host]) {
return nil;
}
HttpdnsHostObject *result = [_hostObjectInMemoryCache getHostObjectByCacheKey:cacheKey createIfNotExists:^id _Nonnull {
HttpdnsLogDebug("No cache for cacheKey: %@", cacheKey);
HttpdnsHostObject *newObject = [HttpdnsHostObject new];
newObject.hostName = host;
newObject.v4Ips = @[];
newObject.v6Ips = @[];
return newObject;
}];
HostObjectExamingResult examingResult = [self examineHttpdnsHostObject:result underQueryType:request.queryIpType];
BOOL isCachedResultUsable = examingResult.isResultUsable;
BOOL isResolvingRequired = examingResult.isResolvingRequired;
if (isCachedResultUsable) {
if (isResolvingRequired) {
//
// <EFBFBD><EFBFBD>?
[self determineResolvingHostNonBlocking:request];
}
// cacheKeyhost
result.hostName = host;
HttpdnsLogDebug("Reuse available cache for cacheKey: %@, result: %@", cacheKey, result);
// <EFBFBD><EFBFBD>?
return result;
}
if (request.isBlockingRequest) {
// <EFBFBD><EFBFBD>?
return [self determineResolveHostBlocking:request];
} else {
// <EFBFBD><EFBFBD>?
[self determineResolvingHostNonBlocking:request];
return nil;
}
}
- (void)determineResolvingHostNonBlocking:(HttpdnsRequest *)request {
dispatch_async(_asyncResolveHostQueue, ^{
HttpDnsLocker *locker = [HttpDnsLocker sharedInstance];
if ([locker tryLock:request.cacheKey queryType:request.queryIpType]) {
@try {
[self executeRequest:request retryCount:0];
} @catch (NSException *exception) {
HttpdnsLogDebug("determineResolvingHostNonBlocking host: %@, exception: %@", request.host, exception);
} @finally {
[locker unlock:request.cacheKey queryType:request.queryIpType];
}
} else {
HttpdnsLogDebug("determineResolvingHostNonBlocking skipped due to concurrent limitation, host: %@", request.host);
}
});
}
- (HttpdnsHostObject *)determineResolveHostBlocking:(HttpdnsRequest *)request {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block HttpdnsHostObject *result = nil;
dispatch_async(_asyncResolveHostQueue, ^{
HttpDnsLocker *locker = [HttpDnsLocker sharedInstance];
@try {
[locker lock:request.cacheKey queryType:request.queryIpType];
result = [self->_hostObjectInMemoryCache getHostObjectByCacheKey:request.cacheKey];
if (result && ![result isExpiredUnderQueryIpType:request.queryIpType]) {
// 线
return;
}
result = [self executeRequest:request retryCount:0];
} @catch (NSException *exception) {
HttpdnsLogDebug("determineResolveHostBlocking host: %@, exception: %@", request.host, exception);
} @finally {
[locker unlock:request.cacheKey queryType:request.queryIpType];
dispatch_semaphore_signal(semaphore);
}
});
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(request.resolveTimeoutInSecond * NSEC_PER_SEC)));
return result;
}
- (HostObjectExamingResult)examineHttpdnsHostObject:(HttpdnsHostObject *)hostObject underQueryType:(HttpdnsQueryIPType)queryType {
if (!hostObject) {
return (HostObjectExamingResult){NO, YES};
}
if ([hostObject isIpEmptyUnderQueryIpType:queryType]) {
return (HostObjectExamingResult){NO, YES};
}
if ([hostObject isExpiredUnderQueryIpType:queryType]) {
if (self.atomicExpiredIPEnabled || [hostObject isLoadFromDB]) {
// <EFBFBD><EFBFBD>?
HttpdnsLogDebug("The ips is expired, but we accept it, host: %@, queryType: %ld, expiredIpEnabled: %d, isLoadFromDB: %d",
hostObject.hostName, queryType, self.atomicExpiredIPEnabled, [hostObject isLoadFromDB]);
// <EFBFBD><EFBFBD>?
return (HostObjectExamingResult){YES, YES};
}
// <EFBFBD><EFBFBD>?
return (HostObjectExamingResult){NO, YES};
}
return (HostObjectExamingResult){YES, NO};
}
- (HttpdnsHostObject *)executeRequest:(HttpdnsRequest *)request retryCount:(int)hasRetryedCount {
NSString *host = request.host;
NSString *cacheKey = request.cacheKey;
HttpdnsQueryIPType queryIPType = request.queryIpType;
HttpdnsHostObject *result = nil;
BOOL isDegradationResult = NO;
if (hasRetryedCount <= HTTPDNS_MAX_REQUEST_RETRY_TIME) {
HttpdnsLogDebug("Internal request starts, host: %@, request: %@", host, request);
NSError *error = nil;
NSArray<HttpdnsHostObject *> *resultArray = [[HttpdnsRemoteResolver new] resolve:request error:&error];
if (error) {
HttpdnsLogDebug("Internal request error, host: %@, error: %@", host, error);
HttpdnsScheduleCenter *scheduleCenter = self.ownerService.scheduleCenter;
[scheduleCenter rotateServiceServerHost];
//
hasRetryedCount++;
[NSThread sleepForTimeInterval:hasRetryedCount * 0.25];
return [self executeRequest:request retryCount:hasRetryedCount];
}
if ([HttpdnsUtil isEmptyArray:resultArray]) {
HttpdnsLogDebug("Internal request get empty result array, host: %@", host);
return nil;
}
// host<EFBFBD><EFBFBD>?
result = resultArray.firstObject;
} else {
if (!self.degradeToLocalDNSEnabled) {
HttpdnsLogDebug("Internal remote request retry count exceed limit, host: %@", host);
return nil;
}
result = [[HttpdnsLocalResolver new] resolve:request];
if (!result) {
HttpdnsLogDebug("Fallback to local dns resolver, but still get no result, host: %@", host);
return nil;
}
isDegradationResult = YES;
}
HttpdnsLogDebug("Internal request finished, host: %@, cacheKey: %@, isDegradationResult: %d, result: %@ ",
host, cacheKey, isDegradationResult, result);
// merge
HttpdnsHostObject *lookupResult = [self mergeLookupResultToManager:result host:host cacheKey:cacheKey underQueryIpType:queryIPType];
// <EFBFBD><EFBFBD>?
return [lookupResult copy];
}
- (void)executePreResolveRequest:(HttpdnsRequest *)request retryCount:(int)hasRetryedCount {
NSString *host = request.host;
HttpdnsQueryIPType queryIPType = request.queryIpType;
BOOL isDegradationResult = NO;
if (hasRetryedCount > HTTPDNS_MAX_REQUEST_RETRY_TIME) {
HttpdnsLogDebug("PreResolve remote request retry count exceed limit, host: %@", host);
return;
}
HttpdnsLogDebug("PreResolve request starts, host: %@, request: %@", host, request);
NSError *error = nil;
NSArray<HttpdnsHostObject *> *resultArray = [[HttpdnsRemoteResolver new] resolve:request error:&error];
if (error) {
HttpdnsLogDebug("PreResolve request error, host: %@, error: %@", host, error);
HttpdnsScheduleCenter *scheduleCenter = self.ownerService.scheduleCenter;
[scheduleCenter rotateServiceServerHost];
//
hasRetryedCount++;
[NSThread sleepForTimeInterval:hasRetryedCount * 0.25];
//
[self executePreResolveRequest:request retryCount:hasRetryedCount];
return;
}
if ([HttpdnsUtil isEmptyArray:resultArray]) {
HttpdnsLogDebug("PreResolve request get empty result array, host: %@", host);
return;
}
HttpdnsLogDebug("PreResolve request finished, host: %@, isDegradationResult: %d, result: %@ ",
host, isDegradationResult, resultArray);
for (HttpdnsHostObject *result in resultArray) {
// merge
// SDNScacheKeyhostName
[self mergeLookupResultToManager:result host:result.hostName cacheKey:result.hostName underQueryIpType:queryIPType];
}
}
- (HttpdnsHostObject *)mergeLookupResultToManager:(HttpdnsHostObject *)result host:host cacheKey:(NSString *)cacheKey underQueryIpType:(HttpdnsQueryIPType)queryIpType {
if (!result) {
return nil;
}
NSArray<HttpdnsIpObject *> *v4IpObjects = [result getV4Ips];
NSArray<HttpdnsIpObject *> *v6IpObjects = [result getV6Ips];
NSString* extra = [result getExtra];
BOOL hasNoIpv4Record = NO;
BOOL hasNoIpv6Record = NO;
if (queryIpType & HttpdnsQueryIPTypeIpv4 && [HttpdnsUtil isEmptyArray:v4IpObjects]) {
hasNoIpv4Record = YES;
}
if (queryIpType & HttpdnsQueryIPTypeIpv6 && [HttpdnsUtil isEmptyArray:v6IpObjects]) {
hasNoIpv6Record = YES;
}
HttpdnsHostObject *cachedHostObject = [_hostObjectInMemoryCache getHostObjectByCacheKey:cacheKey];
if (!cachedHostObject) {
HttpdnsLogDebug("Create new hostObject for cache, cacheKey: %@, host: %@", cacheKey, host);
cachedHostObject = [[HttpdnsHostObject alloc] init];
}
[cachedHostObject setCacheKey:cacheKey];
[cachedHostObject setClientIp:result.clientIp];
[cachedHostObject setHostName:host];
[cachedHostObject setIsLoadFromDB:NO];
[cachedHostObject setHasNoIpv4Record:hasNoIpv4Record];
[cachedHostObject setHasNoIpv6Record:hasNoIpv6Record];
if ([HttpdnsUtil isNotEmptyArray:v4IpObjects]) {
[cachedHostObject setV4Ips:v4IpObjects];
[cachedHostObject setV4TTL:result.getV4TTL];
[cachedHostObject setLastIPv4LookupTime:result.lastIPv4LookupTime];
}
if ([HttpdnsUtil isNotEmptyArray:v6IpObjects]) {
[cachedHostObject setV6Ips:v6IpObjects];
[cachedHostObject setV6TTL:result.getV6TTL];
[cachedHostObject setLastIPv6LookupTime:result.lastIPv6LookupTime];
}
if ([HttpdnsUtil isNotEmptyString:extra]) {
[cachedHostObject setExtra:extra];
}
HttpdnsLogDebug("Updated hostObject to cached, cacheKey: %@, host: %@", cacheKey, host);
//
[_hostObjectInMemoryCache setHostObject:cachedHostObject forCacheKey:cacheKey];
[self persistToDB:cacheKey hostObject:cachedHostObject];
NSArray *ipv4StrArray = [cachedHostObject getV4IpStrings];
if ([HttpdnsUtil isNotEmptyArray:ipv4StrArray]) {
[self initiateQualityDetectionForIP:ipv4StrArray forHost:host cacheKey:cacheKey];
}
NSArray *ipv6StrArray = [cachedHostObject getV6IpStrings];
if ([HttpdnsUtil isNotEmptyArray:ipv6StrArray]) {
[self initiateQualityDetectionForIP:ipv6StrArray forHost:host cacheKey:cacheKey];
}
return cachedHostObject;
}
- (void)initiateQualityDetectionForIP:(NSArray *)ipArray forHost:(NSString *)host cacheKey:(NSString *)cacheKey {
HttpDnsService *service = self.ownerService ?: [HttpDnsService sharedInstance];
NSDictionary<NSString *, NSNumber *> *dataSource = [service getIPRankingDatasource];
if (!dataSource || ![dataSource objectForKey:host]) {
return;
}
NSNumber *port = [dataSource objectForKey:host];
for (NSString *ip in ipArray) {
[[HttpdnsIPQualityDetector sharedInstance] scheduleIPQualityDetection:cacheKey
ip:ip
port:port
callback:^(NSString * _Nonnull cacheKey, NSString * _Nonnull ip, NSInteger costTime) {
[self->_hostObjectInMemoryCache updateQualityForCacheKey:cacheKey forIp:ip withConnectedRT:costTime];
}];
}
}
- (BOOL)isHostsNumberLimitReached {
if ([_hostObjectInMemoryCache count] >= HTTPDNS_MAX_MANAGE_HOST_NUM) {
HttpdnsLogDebug("Can't handle more than %d hosts due to the software configuration.", HTTPDNS_MAX_MANAGE_HOST_NUM);
return YES;
}
return NO;
}
- (void)handleReachabilityNotification:(NSNotification *)notification {
[self networkChanged];
}
- (void)networkChanged {
HttpdnsNetworkStatus currentStatus = [[HttpdnsReachability sharedInstance] currentReachabilityStatus];
NSString *currentStatusString = [[HttpdnsReachability sharedInstance] currentReachabilityString];
// <EFBFBD><EFBFBD>?
// 1
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
[[HttpdnsIpStackDetector sharedInstance] redetectIpStack];
});
NSTimeInterval currentTimestamp = [NSDate date].timeIntervalSince1970;
BOOL statusChanged = (_lastNetworkStatus != currentStatus);
// :
// - <EFBFBD><EFBFBD>?
// - <EFBFBD><EFBFBD>?
NSTimeInterval elapsedTime = currentTimestamp - _lastUpdateTimestamp;
if (elapsedTime >= 5 || (statusChanged && elapsedTime >= 1)) {
HttpdnsLogDebug("Processing network change: oldStatus: %ld, newStatus: %ld(%@), elapsedTime=%.2f seconds",
_lastNetworkStatus, currentStatus, currentStatusString, elapsedTime);
//
// 2<EFBFBD><EFBFBD>?
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
HttpdnsScheduleCenter *scheduleCenter = self.ownerService.scheduleCenter;
[scheduleCenter asyncUpdateRegionScheduleConfig];
});
//
// cacheKey hostName<EFBFBD><EFBFBD>?
// SDNS 使 cacheKey <EFBFBD><EFBFBD>?
NSArray *allKeys = [_hostObjectInMemoryCache allCacheKeys];
NSMutableArray<NSString *> *hostArray = [NSMutableArray array];
for (NSString *key in allKeys) {
HttpdnsHostObject *obj = [self->_hostObjectInMemoryCache getHostObjectByCacheKey:key];
if (!obj) {
continue;
}
NSString *cacheKey = [obj getCacheKey];
NSString *hostName = [obj getHostName];
if (cacheKey && hostName && [cacheKey isEqualToString:hostName]) {
[hostArray addObject:hostName];
}
}
// <EFBFBD><EFBFBD>?
// 3<EFBFBD><EFBFBD>?
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
// hostName <EFBFBD><EFBFBD>?SDNS cacheKey <EFBFBD><EFBFBD>?
for (NSString *host in hostArray) {
[self->_hostObjectInMemoryCache removeHostObjectByCacheKey:host];
}
if (self.atomicPreResolveAfterNetworkChanged && hostArray.count > 0) {
HttpdnsLogDebug("Network changed, pre resolve for host-key entries: %@", hostArray);
[self preResolveHosts:hostArray queryType:HttpdnsQueryIPTypeAuto];
}
});
// <EFBFBD><EFBFBD>?
_lastNetworkStatus = currentStatus;
_lastUpdateTimestamp = currentTimestamp;
} else {
HttpdnsLogDebug("Ignoring network change event: oldStatus: %ld, newStatus: %ld(%@), elapsedTime=%.2f seconds",
_lastNetworkStatus, currentStatus, currentStatusString, elapsedTime);
}
}
#pragma mark -
#pragma mark - disable status Setter and Getter Method
- (dispatch_queue_t)cacheQueue {
if (!_cacheQueue) {
_cacheQueue = dispatch_queue_create("com.Trust.sdk.httpdns.cacheDisableStatusQueue", DISPATCH_QUEUE_SERIAL);
}
return _cacheQueue;
}
#pragma mark -
#pragma mark - Flag for Disable and Sniffer Method
- (void)loadCacheFromDbToMemory {
NSArray<HttpdnsHostRecord *> *hostRecords = [self->_httpdnsDB getAllRecords];
if ([HttpdnsUtil isEmptyArray:hostRecords]) {
return;
}
for (HttpdnsHostRecord *hostRecord in hostRecords) {
NSString *hostName = hostRecord.hostName;
NSString *cacheKey = hostRecord.cacheKey;
HttpdnsHostObject *hostObject = [HttpdnsHostObject fromDBRecord:hostRecord];
// App使<EFBFBD><EFBFBD>?
[hostObject setIsLoadFromDB:YES];
[self->_hostObjectInMemoryCache setHostObject:hostObject forCacheKey:cacheKey];
NSArray *v4IpStrArr = [hostObject getV4IpStrings];
if ([HttpdnsUtil isNotEmptyArray:v4IpStrArr]) {
[self initiateQualityDetectionForIP:v4IpStrArr forHost:hostName cacheKey:cacheKey];
}
NSArray *v6IpStrArr = [hostObject getV6IpStrings];
if ([HttpdnsUtil isNotEmptyArray:v6IpStrArr]) {
[self initiateQualityDetectionForIP:v6IpStrArr forHost:hostName cacheKey:cacheKey];
}
}
}
- (void)cleanMemoryAndPersistentCacheOfHostArray:(NSArray<NSString *> *)hostArray {
for (NSString *host in hostArray) {
if ([HttpdnsUtil isNotEmptyString:host]) {
[_hostObjectInMemoryCache removeHostObjectByCacheKey:host];
}
}
// <EFBFBD><EFBFBD>?
dispatch_async(_persistentCacheConcurrentQueue, ^{
[self->_httpdnsDB deleteByHostNameArr:hostArray];
});
}
- (void)cleanMemoryAndPersistentCacheOfAllHosts {
[_hostObjectInMemoryCache removeAllHostObjects];
// <EFBFBD><EFBFBD>?
dispatch_async(_persistentCacheConcurrentQueue, ^{
[self->_httpdnsDB deleteAll];
});
}
- (void)persistToDB:(NSString *)cacheKey hostObject:(HttpdnsHostObject *)hostObject {
if (!_persistentCacheIpEnabled) {
return;
}
dispatch_async(_persistentCacheConcurrentQueue, ^{
HttpdnsHostRecord *hostRecord = [hostObject toDBRecord];
[self->_httpdnsDB createOrUpdate:hostRecord];
});
}
#pragma mark -
#pragma mark - <EFBFBD><EFBFBD>?
- (NSString *)showMemoryCache {
NSString *cacheDes;
cacheDes = [NSString stringWithFormat:@"%@", _hostObjectInMemoryCache];
return cacheDes;
}
- (void)cleanAllHostMemoryCache {
[_hostObjectInMemoryCache removeAllHostObjects];
}
- (void)syncLoadCacheFromDbToMemory {
[self loadCacheFromDbToMemory];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end