feat: 并发为3
This commit is contained in:
parent
3f32bb26bc
commit
86bdc7089b
@ -3,10 +3,12 @@ import * as BackgroundFetch from 'expo-background-fetch';
|
|||||||
import * as ImageManipulator from 'expo-image-manipulator';
|
import * as ImageManipulator from 'expo-image-manipulator';
|
||||||
import * as MediaLibrary from 'expo-media-library';
|
import * as MediaLibrary from 'expo-media-library';
|
||||||
import * as TaskManager from 'expo-task-manager';
|
import * as TaskManager from 'expo-task-manager';
|
||||||
|
import pLimit from 'p-limit';
|
||||||
import { Alert } from 'react-native';
|
import { Alert } from 'react-native';
|
||||||
|
|
||||||
const BACKGROUND_UPLOAD_TASK = 'background-upload-task';
|
const BACKGROUND_UPLOAD_TASK = 'background-upload-task';
|
||||||
|
// 设置最大并发数
|
||||||
|
const CONCURRENCY_LIMIT = 3; // 同时最多上传3个文件
|
||||||
// 获取指定时间范围内的媒体文件
|
// 获取指定时间范围内的媒体文件
|
||||||
export const getMediaByDateRange = async (startDate: Date, endDate: Date) => {
|
export const getMediaByDateRange = async (startDate: Date, endDate: Date) => {
|
||||||
try {
|
try {
|
||||||
@ -107,25 +109,59 @@ const addMaterial = async (file: string, compressFile: string) => {
|
|||||||
|
|
||||||
// 上传文件到URL
|
// 上传文件到URL
|
||||||
const uploadFile = async (file: File, uploadUrl: string): Promise<void> => {
|
const uploadFile = async (file: File, uploadUrl: string): Promise<void> => {
|
||||||
return new Promise((resolve, reject) => {
|
console.log('=== Starting file upload ===');
|
||||||
const xhr = new XMLHttpRequest();
|
console.log('File info:', {
|
||||||
xhr.open('PUT', uploadUrl);
|
name: file.name,
|
||||||
xhr.setRequestHeader('Content-Type', file.type);
|
type: file.type,
|
||||||
|
size: file.size,
|
||||||
xhr.onload = () => {
|
lastModified: file.lastModified
|
||||||
if (xhr.status >= 200 && xhr.status < 300) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
reject(new Error(`Upload failed with status ${xhr.status}`));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onerror = () => {
|
|
||||||
reject(new Error('Network error during upload'));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.send(file);
|
|
||||||
});
|
});
|
||||||
|
console.log('Upload URL:', uploadUrl);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
console.log('Upload timeout triggered');
|
||||||
|
controller.abort();
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
console.log('Sending upload request...');
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
const response = await fetch(uploadUrl, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': file.type,
|
||||||
|
'x-oss-forbid-overwrite': 'true'
|
||||||
|
},
|
||||||
|
body: file,
|
||||||
|
signal: controller.signal
|
||||||
|
});
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
const endTime = Date.now();
|
||||||
|
|
||||||
|
console.log(`Upload completed in ${endTime - startTime}ms`, {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
headers: Object.fromEntries(response.headers.entries())
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text().catch(() => '');
|
||||||
|
console.error('Upload failed with response:', errorText);
|
||||||
|
throw new Error(`Upload failed: ${response.status} ${response.statusText}\n${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Upload successful');
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Upload error details:', {
|
||||||
|
name: error.name,
|
||||||
|
message: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 检查并请求媒体库权限
|
// 检查并请求媒体库权限
|
||||||
@ -177,11 +213,7 @@ const processMediaUpload = async (asset: MediaLibrary.Asset) => {
|
|||||||
const mimeType = isVideo ? 'video/mp4' : 'image/jpeg';
|
const mimeType = isVideo ? 'video/mp4' : 'image/jpeg';
|
||||||
const file = new File([blob], filename, { type: mimeType });
|
const file = new File([blob], filename, { type: mimeType });
|
||||||
|
|
||||||
console.log("Original file prepared for upload:", {
|
console.log("Original file prepared for upload:", file);
|
||||||
name: file.name,
|
|
||||||
size: file.size,
|
|
||||||
type: file.type
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取上传URL并上传原始文件
|
// 获取上传URL并上传原始文件
|
||||||
const { upload_url, file_id } = await getUploadUrl(file, {
|
const { upload_url, file_id } = await getUploadUrl(file, {
|
||||||
@ -212,6 +244,7 @@ const processMediaUpload = async (asset: MediaLibrary.Asset) => {
|
|||||||
size: compressedFile.size,
|
size: compressedFile.size,
|
||||||
type: compressedFile.type
|
type: compressedFile.type
|
||||||
});
|
});
|
||||||
|
console.log("compressedFile", compressedFile);
|
||||||
|
|
||||||
// 获取上传URL并上传压缩文件
|
// 获取上传URL并上传压缩文件
|
||||||
const { upload_url, file_id } = await getUploadUrl(compressedFile, {
|
const { upload_url, file_id } = await getUploadUrl(compressedFile, {
|
||||||
@ -248,7 +281,7 @@ const processMediaUpload = async (asset: MediaLibrary.Asset) => {
|
|||||||
compressed: compressedResult.file_id
|
compressed: compressedResult.file_id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error('Error in processMediaUpload:', error);
|
console.error('Error in processMediaUpload:', error);
|
||||||
if (error.message === 'No media library permission') {
|
if (error.message === 'No media library permission') {
|
||||||
throw error;
|
throw error;
|
||||||
@ -294,7 +327,6 @@ TaskManager.defineTask(BACKGROUND_UPLOAD_TASK, async () => {
|
|||||||
const { hasPermission } = await checkMediaLibraryPermission();
|
const { hasPermission } = await checkMediaLibraryPermission();
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
console.log('Media library permission not granted');
|
console.log('Media library permission not granted');
|
||||||
// 返回 NoData 而不是 Failed,这样系统可能会在稍后重试
|
|
||||||
return BackgroundFetch.BackgroundFetchResult.NoData;
|
return BackgroundFetch.BackgroundFetchResult.NoData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,22 +344,49 @@ TaskManager.defineTask(BACKGROUND_UPLOAD_TASK, async () => {
|
|||||||
|
|
||||||
console.log(`Found ${media.length} media items to process`);
|
console.log(`Found ${media.length} media items to process`);
|
||||||
|
|
||||||
// 处理每个媒体文件
|
// 创建并发限制器
|
||||||
for (const item of media) {
|
const limit = pLimit(CONCURRENCY_LIMIT);
|
||||||
try {
|
|
||||||
await processMediaUpload(item);
|
// 准备所有上传任务
|
||||||
} catch (error) {
|
const uploadPromises = media.map(item =>
|
||||||
console.error(`Error processing media ${item.id}:`, error);
|
limit(async () => {
|
||||||
// 如果是权限错误,直接返回失败
|
try {
|
||||||
if (error.message === 'No media library permission') {
|
await processMediaUpload(item);
|
||||||
return BackgroundFetch.BackgroundFetchResult.Failed;
|
return { success: true, id: item.id };
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`Error processing media ${item.id}:`, error);
|
||||||
|
if (error.message === 'No media library permission') {
|
||||||
|
throw error; // 权限错误直接抛出
|
||||||
|
}
|
||||||
|
return { success: false, id: item.id, error };
|
||||||
}
|
}
|
||||||
// 其他错误继续处理下一个文件
|
})
|
||||||
}
|
);
|
||||||
|
|
||||||
|
// 等待所有上传任务完成
|
||||||
|
const results = await Promise.allSettled(uploadPromises);
|
||||||
|
|
||||||
|
// 统计结果
|
||||||
|
const succeeded = results.filter(r =>
|
||||||
|
r.status === 'fulfilled' && r.value.success
|
||||||
|
).length;
|
||||||
|
const failed = results.length - succeeded;
|
||||||
|
|
||||||
|
console.log(`Background upload task completed. Success: ${succeeded}, Failed: ${failed}`);
|
||||||
|
|
||||||
|
// 如果有权限错误,返回失败
|
||||||
|
const hasPermissionError = results.some(r =>
|
||||||
|
r.status === 'rejected' ||
|
||||||
|
(r.status === 'fulfilled' && r.value.error?.message === 'No media library permission')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasPermissionError) {
|
||||||
|
return BackgroundFetch.BackgroundFetchResult.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Background upload task completed');
|
return succeeded > 0 ?
|
||||||
return BackgroundFetch.BackgroundFetchResult.NewData;
|
BackgroundFetch.BackgroundFetchResult.NewData :
|
||||||
|
BackgroundFetch.BackgroundFetchResult.NoData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in background upload task:', error);
|
console.error('Error in background upload task:', error);
|
||||||
return BackgroundFetch.BackgroundFetchResult.Failed;
|
return BackgroundFetch.BackgroundFetchResult.Failed;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user