mirror of
https://github.com/danog/Telegram.git
synced 2024-12-03 09:57:46 +01:00
226 lines
5.1 KiB
Objective-C
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
|