102 lines
3.8 KiB
TypeScript
102 lines
3.8 KiB
TypeScript
import * as BackgroundTask from 'expo-background-task';
|
||
import * as TaskManager from 'expo-task-manager';
|
||
import pLimit from 'p-limit';
|
||
import { getUploadTaskStatus, initUploadTable, insertUploadTask } from '../db';
|
||
import { getMediaByDateRange } from './media';
|
||
import { processAndUploadMedia } from './uploader';
|
||
|
||
const BACKGROUND_UPLOAD_TASK = 'background-upload-task';
|
||
|
||
const CONCURRENCY_LIMIT = 3; // 后台上传并发数,例如同时上传3个文件
|
||
const limit = pLimit(CONCURRENCY_LIMIT);
|
||
|
||
// 注册后台任务
|
||
export const registerBackgroundUploadTask = async () => {
|
||
try {
|
||
// 初始化数据库表
|
||
await initUploadTable();
|
||
|
||
const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_UPLOAD_TASK);
|
||
if (isRegistered) {
|
||
console.log('Background task already registered.');
|
||
} else {
|
||
await BackgroundTask.registerTaskAsync(BACKGROUND_UPLOAD_TASK, {
|
||
minimumInterval: 15 * 60, // 15 分钟
|
||
});
|
||
console.log('Background task registered successfully.');
|
||
}
|
||
return true;
|
||
} catch (error) {
|
||
console.error('Error registering background task:', error);
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 定义后台任务
|
||
TaskManager.defineTask(BACKGROUND_UPLOAD_TASK, async () => {
|
||
try {
|
||
console.log('Running background upload task...');
|
||
const now = new Date();
|
||
const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
||
|
||
// 获取最近24小时的媒体文件
|
||
const media = await getMediaByDateRange(oneDayAgo, now);
|
||
|
||
if (media.length === 0) {
|
||
console.log('No new media files to upload in the last 24 hours.');
|
||
return BackgroundTask.BackgroundTaskResult.Success;
|
||
}
|
||
|
||
console.log(`Found ${media.length} media files to potentially upload.`);
|
||
|
||
// 并发上传文件
|
||
let successCount = 0;
|
||
let skippedCount = 0;
|
||
let failedCount = 0;
|
||
|
||
const uploadPromises = media.map((file) =>
|
||
limit(async () => {
|
||
try {
|
||
const existingTask = await getUploadTaskStatus(file.uri);
|
||
if (!existingTask) {
|
||
await insertUploadTask(file.uri, file.filename);
|
||
} else if (existingTask.status === 'success' || existingTask.status === 'skipped') {
|
||
console.log(`File ${file.uri} already ${existingTask.status}, skipping processing.`);
|
||
return { status: 'skipped' }; // 返回状态以便统计
|
||
}
|
||
|
||
const result = await processAndUploadMedia(file);
|
||
if (result === null) {
|
||
return { status: 'skipped' };
|
||
} else if (result.originalSuccess) {
|
||
return { status: 'success' };
|
||
} else {
|
||
return { status: 'failed' };
|
||
}
|
||
} catch (e) {
|
||
console.error('Upload failed for', file.uri, e);
|
||
return { status: 'failed' };
|
||
}
|
||
})
|
||
);
|
||
|
||
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++;
|
||
}
|
||
});
|
||
|
||
console.log(`Background upload task finished. Successful: ${successCount}, Skipped: ${skippedCount}, Failed: ${failedCount}, Total: ${media.length}`);
|
||
|
||
return BackgroundTask.BackgroundTaskResult.Success;
|
||
} catch (error) {
|
||
console.error('Background task error:', error);
|
||
return BackgroundTask.BackgroundTaskResult.Failed;
|
||
}
|
||
}); |