102 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
});