Fix FILE_REFERENCE_EXPIRED for streams

This commit is contained in:
Eduard Kuzmenko 2021-07-19 21:02:40 +03:00
parent c67a8fc89e
commit 68c81916e3

View File

@ -27,6 +27,7 @@ import apiManager from "./apiManager";
import { isWebpSupported } from "./mtproto.worker"; import { isWebpSupported } from "./mtproto.worker";
import { bytesToHex } from "../../helpers/bytes"; import { bytesToHex } from "../../helpers/bytes";
import assumeType from "../../helpers/assumeType"; import assumeType from "../../helpers/assumeType";
import { ctx } from "../../helpers/userAgent";
type Delayed = { type Delayed = {
offset: number, offset: number,
@ -89,7 +90,7 @@ export class ApiFileManager {
public refreshReferencePromises: { public refreshReferencePromises: {
[referenceHex: string]: { [referenceHex: string]: {
deferred: CancellablePromise<ReferenceBytes>, deferred: CancellablePromise<ReferenceBytes>,
ready: Promise<void> timeout: number
} }
} = {}; } = {};
@ -189,10 +190,12 @@ export class ApiFileManager {
} }
public requestFilePart(dcId: DcId, location: InputFileLocation, offset: number, limit: number, id = 0, queueId = 0, checkCancel?: () => void) { public requestFilePart(dcId: DcId, location: InputFileLocation, offset: number, limit: number, id = 0, queueId = 0, checkCancel?: () => void) {
return this.downloadRequest(dcId, id, async() => { return this.downloadRequest(dcId, id, () => {
checkCancel && checkCancel(); checkCancel && checkCancel();
const invoke = (): Promise<MyUploadFile> => { const invoke = (): Promise<MyUploadFile> => {
checkCancel && checkCancel();
const promise = apiManager.invokeApi('upload.getFile', { const promise = apiManager.invokeApi('upload.getFile', {
location, location,
offset, offset,
@ -204,7 +207,7 @@ export class ApiFileManager {
return promise.catch((err) => { return promise.catch((err) => {
if(err.type === 'FILE_REFERENCE_EXPIRED') { if(err.type === 'FILE_REFERENCE_EXPIRED') {
return this.refreshReference(location).then(() => invoke()); return this.refreshReference(location).then(invoke);
} }
throw err; throw err;
@ -217,7 +220,7 @@ export class ApiFileManager {
location.checkedReference = true; location.checkedReference = true;
const hex = bytesToHex(reference); const hex = bytesToHex(reference);
if(this.refreshReferencePromises[hex]) { if(this.refreshReferencePromises[hex]) {
return this.refreshReference(location).then(() => invoke()); return this.refreshReference(location).then(invoke);
} }
} }
@ -268,29 +271,28 @@ export class ApiFileManager {
r = this.refreshReferencePromises[hex] = { r = this.refreshReferencePromises[hex] = {
deferred, deferred,
ready: deferred.then(reference => { timeout: ctx.setTimeout(() => {
if(hex === bytesToHex(reference)) { this.log.error('Didn\'t refresh the reference:', inputFileLocation);
throw 'REFERENCE_IS_NOT_REFRESHED'; deferred.reject('REFERENCE_IS_NOT_REFRESHED');
} }, 60000)
(inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference = reference;
})
}; };
const timeout = setTimeout(() => {
this.log.error('Didn\'t refresh the reference:', inputFileLocation);
deferred.reject('REFERENCE_IS_NOT_REFRESHED');
}, 60000);
deferred.finally(() => { deferred.finally(() => {
clearTimeout(timeout); clearTimeout(r.timeout);
}); });
const task = {type: 'refreshReference', payload: reference}; const task = {type: 'refreshReference', payload: reference};
notifySomeone(task); notifySomeone(task);
} }
return r.ready; // have to replace file_reference in any way, because location can be different everytime if it's stream
return r.deferred.then(reference => {
if(hex === bytesToHex(reference)) {
throw 'REFERENCE_IS_NOT_REFRESHED';
}
(inputFileLocation as InputFileLocation.inputDocumentFileLocation).file_reference = reference;
});
} }
public downloadFile(options: DownloadOptions): CancellablePromise<Blob> { public downloadFile(options: DownloadOptions): CancellablePromise<Blob> {