feat: 后台任务并发
This commit is contained in:
parent
e7e2c05bcd
commit
e2c5493c8c
@ -1,11 +1,15 @@
|
|||||||
import * as BackgroundTask from 'expo-background-task';
|
import * as BackgroundTask from 'expo-background-task';
|
||||||
import * as TaskManager from 'expo-task-manager';
|
import * as TaskManager from 'expo-task-manager';
|
||||||
|
import pLimit from 'p-limit';
|
||||||
import { getUploadTaskStatus, initUploadTable, insertUploadTask } from '../db';
|
import { getUploadTaskStatus, initUploadTable, insertUploadTask } from '../db';
|
||||||
import { getMediaByDateRange } from './media';
|
import { getMediaByDateRange } from './media';
|
||||||
import { processAndUploadMedia } from './uploader';
|
import { processAndUploadMedia } from './uploader';
|
||||||
|
|
||||||
const BACKGROUND_UPLOAD_TASK = 'background-upload-task';
|
const BACKGROUND_UPLOAD_TASK = 'background-upload-task';
|
||||||
|
|
||||||
|
const CONCURRENCY_LIMIT = 3; // 后台上传并发数,例如同时上传3个文件
|
||||||
|
const limit = pLimit(CONCURRENCY_LIMIT);
|
||||||
|
|
||||||
// 注册后台任务
|
// 注册后台任务
|
||||||
export const registerBackgroundUploadTask = async () => {
|
export const registerBackgroundUploadTask = async () => {
|
||||||
try {
|
try {
|
||||||
@ -45,38 +49,48 @@ TaskManager.defineTask(BACKGROUND_UPLOAD_TASK, async () => {
|
|||||||
|
|
||||||
console.log(`Found ${media.length} media files to potentially upload.`);
|
console.log(`Found ${media.length} media files to potentially upload.`);
|
||||||
|
|
||||||
// 串行上传文件
|
// 并发上传文件
|
||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
let skippedCount = 0;
|
let skippedCount = 0;
|
||||||
let failedCount = 0;
|
let failedCount = 0;
|
||||||
|
|
||||||
for (const file of media) {
|
const uploadPromises = media.map((file) =>
|
||||||
try {
|
limit(async () => {
|
||||||
const existingTask = await getUploadTaskStatus(file.uri);
|
try {
|
||||||
if (!existingTask) {
|
const existingTask = await getUploadTaskStatus(file.uri);
|
||||||
// If not in DB, insert as pending
|
if (!existingTask) {
|
||||||
await insertUploadTask(file.uri, file.filename);
|
await insertUploadTask(file.uri, file.filename);
|
||||||
} else if (existingTask.status === 'success' || existingTask.status === 'skipped') {
|
} else if (existingTask.status === 'success' || existingTask.status === 'skipped') {
|
||||||
console.log(`File ${file.uri} already ${existingTask.status}, skipping processing.`);
|
console.log(`File ${file.uri} already ${existingTask.status}, skipping processing.`);
|
||||||
skippedCount++;
|
return { status: 'skipped' }; // 返回状态以便统计
|
||||||
continue; // Skip processing if already successful or skipped
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const result = await processAndUploadMedia(file);
|
const result = await processAndUploadMedia(file);
|
||||||
if (result === null) {
|
if (result === null) {
|
||||||
// Skipped by processAndUploadMedia (e.g., already uploaded)
|
return { status: 'skipped' };
|
||||||
skippedCount++;
|
} else if (result.originalSuccess) {
|
||||||
} else if (result.originalSuccess) {
|
return { status: 'success' };
|
||||||
successCount++;
|
} else {
|
||||||
} else {
|
return { status: 'failed' };
|
||||||
// Failed
|
}
|
||||||
failedCount++;
|
} catch (e) {
|
||||||
|
console.error('Upload failed for', file.uri, e);
|
||||||
|
return { status: 'failed' };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
})
|
||||||
console.error('Upload failed for', file.uri, e);
|
);
|
||||||
|
|
||||||
|
const results = await Promise.all(uploadPromises);
|
||||||
|
|
||||||
|
results.forEach(result => {
|
||||||
|
if (result.status === 'success') {
|
||||||
|
successCount++;
|
||||||
|
} else if (result.status === 'skipped') {
|
||||||
|
skippedCount++;
|
||||||
|
} else if (result.status === 'failed') {
|
||||||
failedCount++;
|
failedCount++;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
console.log(`Background upload task finished. Successful: ${successCount}, Skipped: ${skippedCount}, Failed: ${failedCount}, Total: ${media.length}`);
|
console.log(`Background upload task finished. Successful: ${successCount}, Skipped: ${skippedCount}, Failed: ${failedCount}, Total: ${media.length}`);
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
"@react-navigation/elements": "^2.3.8",
|
"@react-navigation/elements": "^2.3.8",
|
||||||
"@react-navigation/native": "^7.1.6",
|
"@react-navigation/native": "^7.1.6",
|
||||||
"@reduxjs/toolkit": "^2.8.2",
|
"@reduxjs/toolkit": "^2.8.2",
|
||||||
|
"@types/p-limit": "^2.2.0",
|
||||||
"@types/react-redux": "^7.1.34",
|
"@types/react-redux": "^7.1.34",
|
||||||
"expo": "~53.0.12",
|
"expo": "~53.0.12",
|
||||||
"expo-audio": "~0.4.7",
|
"expo-audio": "~0.4.7",
|
||||||
@ -53,6 +54,7 @@
|
|||||||
"i18next-http-backend": "^3.0.2",
|
"i18next-http-backend": "^3.0.2",
|
||||||
"lottie-react-native": "7.2.2",
|
"lottie-react-native": "7.2.2",
|
||||||
"nativewind": "^4.1.23",
|
"nativewind": "^4.1.23",
|
||||||
|
"p-limit": "^6.2.0",
|
||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-i18next": "^15.5.3",
|
"react-i18next": "^15.5.3",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user