1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-03 09:57:46 +01:00
Telegram/Telegraph/TGNetworkWorker.m
2015-10-01 19:19:52 +03:00

226 lines
5.1 KiB
Objective-C

//
// TGDownloadWorker.m
// Telegraph
//
// Created by Peter on 14/02/14.
//
//
#import "TGNetworkWorker.h"
#import "ASQueue.h"
#import "ActionStage.h"
#import "TGTelegraph.h"
#import "TGTimer.h"
#import <MTProtoKit/MTContext.h>
#import <MTProtoKit/MTProto.h>
#import <MTProtoKit/MTRequestMessageService.h>
#import <MTProtoKit/MTRequest.h>
static int workerCount = 0;
@interface TGNetworkWorker () <MTRequestMessageServiceDelegate>
{
MTContext *_context;
MTProto *_mtProto;
MTRequestMessageService *_requestService;
TGTimer *_timeoutTimer;
bool _isReadyToBeRemoved;
bool _isBusy;
}
@end
@implementation TGNetworkWorker
- (instancetype)initWithContext:(MTContext *)context datacenterId:(NSInteger)datacenterId masterDatacenterId:(NSInteger)masterDatacenterId
{
self = [super init];
if (self != nil)
{
workerCount++;
TGLog(@"[TGNetworkWorker#%x/%d start (%d)]", (int)self, (int)datacenterId, workerCount);
_context = context;
_datacenterId = datacenterId;
_mtProto = [[MTProto alloc] initWithContext:_context datacenterId:_datacenterId];
_mtProto.requiredAuthToken = @(TGTelegraphInstance.clientUserId);
_mtProto.authTokenMasterDatacenterId = masterDatacenterId;
_requestService = [[MTRequestMessageService alloc] initWithContext:_context];
_requestService.delegate = self;
[_mtProto addMessageService:_requestService];
[self startTimer];
}
return self;
}
- (void)dealloc
{
workerCount--;
TGLog(@"[TGNetworkWorker#%x stop (%d)]", (int)self, workerCount);
if (_timeoutTimer != nil)
{
[_timeoutTimer invalidate];
_timeoutTimer = nil;
}
[_mtProto stop];
_requestService.delegate = nil;
}
- (void)startTimer
{
[ActionStageInstance() dispatchOnStageQueue:^
{
[self clearTimer];
__weak TGNetworkWorker *weakSelf = self;
_timeoutTimer = [[TGTimer alloc] initWithTimeout:30 repeat:false completion:^
{
__strong TGNetworkWorker *strongSelf = weakSelf;
[strongSelf timerTimeout];
} queue:[ActionStageInstance() globalStageDispatchQueue]];
[_timeoutTimer start];
}];
}
- (void)clearTimer
{
[ActionStageInstance() dispatchOnStageQueue:^
{
if (_timeoutTimer != nil)
{
[_timeoutTimer invalidate];
_timeoutTimer = nil;
}
}];
}
- (void)timerTimeout
{
[ActionStageInstance() dispatchOnStageQueue:^
{
_isReadyToBeRemoved = true;
id<TGNetworkWorkerDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(networkWorkerReadyToBeRemoved:)])
[delegate networkWorkerReadyToBeRemoved:self];
}];
}
- (bool)isBusy
{
return _isBusy;
}
- (void)setIsBusy:(bool)isBusy
{
[ActionStageInstance() dispatchOnStageQueue:^
{
if (_isBusy != isBusy)
{
_isBusy = isBusy;
if (isBusy)
[self clearTimer];
else
[self startTimer];
if (!_isBusy)
{
id<TGNetworkWorkerDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(networkWorkerDidBecomeAvailable:)])
[delegate networkWorkerDidBecomeAvailable:self];
}
}
}];
}
- (void)updateReadyToBeRemoved
{
[ActionStageInstance() dispatchOnStageQueue:^
{
if (_isReadyToBeRemoved)
{
id<TGNetworkWorkerDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(networkWorkerReadyToBeRemoved:)])
[delegate networkWorkerReadyToBeRemoved:self];
}
}];
}
- (void)addRequest:(MTRequest *)request
{
[ActionStageInstance() dispatchOnStageQueue:^
{
[_requestService addRequest:request];
}];
}
- (void)cancelRequestById:(id)requestId
{
[_requestService removeRequestByInternalId:requestId askForReconnectionOnDrop:true];
}
- (void)cancelRequestByIdSoft:(id)requestId
{
[_requestService removeRequestByInternalId:requestId askForReconnectionOnDrop:false];
}
- (void)ensureConnection
{
[_mtProto requestTransportTransaction];
}
- (void)requestMessageServiceDidCompleteAllRequests:(MTRequestMessageService *)__unused requestMessageService
{
}
- (void)requestMessageServiceAuthorizationRequired:(MTRequestMessageService *)__unused requestMessageService
{
[_context updateAuthTokenForDatacenterWithId:_datacenterId authToken:nil];
[_context authTokenForDatacenterWithIdRequired:_datacenterId authToken:_mtProto.requiredAuthToken masterDatacenterId:_mtProto.authTokenMasterDatacenterId];
}
@end
@implementation TGNetworkWorkerGuard
- (instancetype)initWithWorker:(TGNetworkWorker *)worker
{
self = [super init];
if (self != nil)
{
_worker = worker;
}
return self;
}
- (void)dealloc
{
[self releaseWorker];
}
- (TGNetworkWorker *)strongWorker
{
return _worker;
}
- (void)releaseWorker
{
TGNetworkWorker *worker = _worker;
_worker = nil;
[worker setIsBusy:false];
worker = nil;
}
@end