اکشنهای سیستم
این مستند شامل تمام اکشنهایی است که در پسزمینه داشبورد کاربر اتفاق میافتند و کاربر مستقیماً متوجه آنها نمیشود، اما برای عملکرد صحیح سیستم ضروری هستند.
فلسفه System Actions
چرا نیاز به اکشنهای پسزمینه داریم؟
- بهبود تجربه کاربر: بسیاری از عملیات زمانبر هستند و نباید کاربر منتظر بماند
- جداسازی نگرانیها: منطق بیزنسی پیچیده باید از رابط کاربری جدا باشد
- قابلیت اطمینان: اگر عملیات ناموفق شود، میتوان retry کرد بدون اینکه کاربر دوباره اقدام کند
- مقیاسپذیری: عملیات سنگین را میتوان در سرورهای جداگانه اجرا کرد
دستهبندی اکشنها
۱. اکشنهای احراز هویت و امنیت
۱.۱ بررسی اعتبار توکن
زمان اجرا: هر درخواست به سرور
عملکرد:
- توکن JWT را از header استخراج میکند
- امضای توکن را بررسی میکند
- تاریخ انقضا را چک میکند
- اگر منقضی شده، سعی میکند با refresh token، توکن جدید بگیرد
API:
Middleware: AuthenticationMiddleware
دادههای لاگ:
- User ID
- Token expiry time
- Refresh status
۱.۲ ثبت لاگ فعالیت کاربر
زمان اجرا: هر عملیات مهم کاربر (لاگین، آپلود، ویرایش، حذف)
عملکرد:
- اطلاعات فعالیت کاربر را در جدول
user_activity_logsثبت میکند - شامل: نوع عملیات، زمان، IP، User Agent، ...
هدف:
- امکان بررسی فعالیتهای مشکوک
- آمار استفاده از سیستم
- Audit trail برای compliance
مثال لاگ:
{
"user_id": 12345,
"action": "video_uploaded",
"timestamp": "2024-11-16T10:30:00Z",
"ip_address": "1.2.3.4",
"user_agent": "Mozilla/5.0...",
"metadata": {
"video_id": 67890,
"file_size": 500000000
}
}
۱.۳ تشخیص فعالیت مشکوک
زمان اجرا: Real-time، همزمان با فعالیت کاربر
عملکرد: سیستم الگوهای مشکوک را تشخیص میدهد:
- تعداد زیاد درخواست در مدت کوتاه (Brute force یا Spam)
- تلاش برای دسترسی به resource های دیگران
- تغییرات غیرعادی در الگوی رفتاری
اقدام:
- اگر مشکوک بود، یک flag در دیتابیس ثبت میشود
- تیم امنیتی notification دریافت میکنند
- در صورت لزوم، کاربر موقتاً مسدود میشود
API:
Service: SecurityMonitoringService
Method: detectSuspiciousActivity()
۲. اکشنهای آپلود و پردازش
۲.۱ محاسبه هش MD5
زمان اجرا: بلافاصله پس از شروع آپلود فایل
عملکرد:
- بهصورت chunk به chunk، هش MD5 فایل را محاسبه میکند
- این هش برای تشخیص ویدئوی تکراری و Content ID استفاده میشود
الگوریتم:
hash = MD5_INIT()
for each chunk in file:
hash = MD5_UPDATE(hash, chunk)
final_hash = MD5_FINAL(hash)
API:
Service: FileHashService
Method: calculateMD5()
زمان تقریبی:
- فایل ۱ گیگابایتی: ~۳۰ ثانیه
۲.۲ بررسی ویدئوی تکراری
زمان اجرا: پس از محاسبه هش MD5
عملکرد:
- هش MD5 را در دیتابیس جستجو میکند
- چک میکند که آیا این ویدئو قبلاً توسط همین کاربر آپلود شده یا خیر
- اگر تکراری بود، آپلود را متوقف میکند
Query:
SELECT id, title FROM videos
WHERE user_id = ? AND md5_hash = ?
API:
Service: DuplicateDetectionService
Method: checkDuplicate(userId, md5Hash)
۲.۳ بررسی محدودیت روزانه
زمان اجرا: قبل از شروع آپلود
عملکرد:
- تعداد و حجم آپلودهای امروز کاربر را از دیتابیس میخواند
- با حد مجاز مقایسه میکند
- اگر رسیده باشد، آپلود را reject میکند
Query:
SELECT COUNT(*) as upload_count, SUM(file_size) as total_size
FROM videos
WHERE user_id = ? AND DATE(created_at) = CURDATE()
منطق تصمیمگیری:
if (uploadCount >= maxUploads || totalSize + newFileSize > maxSize) {
reject("Daily limit exceeded")
}
۲.۴ ارسال به صف کانورت
زمان اجرا: پس از اتمام موفقیتآمیز آپلود فایل
عملکرد:
- اطلاعات ویدئو را در یک پیام قرار میدهد
- پیام را به صف (Queue) کانورت ارسال میکند
- Worker های تیم کانورت این پیامها را میخوانند و پردازش میکنند
صف استفاده شده: RabbitMQ یا Kafka
پیام نمونه:
{
"video_id": 67890,
"user_id": 12345,
"file_path": "/uploads/2024/11/16/video_xyz.mp4",
"file_size": 500000000,
"md5_hash": "abc123...",
"priority": "normal",
"callback_url": "https://aparat.com/api/convert/callback"
}
API:
Service: ConvertQueueService
Method: enqueueVideo(videoData)
۲.۵ دریافت نتیجه پردازش از تیم کانورت
زمان اجرا: وقتی تیم کانورت پردازش را تمام کرد و callback را صدا زد
عملکرد:
- تیم کانورت یک callback به backend ما میزند
- اطلاعات ویدئوهای تبدیلشده (۳۶۰p, ۴۸۰p, ۷۲۰p, ۱۰۸۰p) را دریافت میکنیم
- این اطلاعات را در دیتابیس ذخیره میکنیم
- وضعیت ویدئو را از "در حال پردازش" به "آماده" تغییر میدهیم
- به کاربر notification میفرستیم
Callback Payload:
{
"video_id": 67890,
"status": "completed",
"qualities": [
{"quality": "360p", "url": "https://cdn.aparat.com/.../360p.mp4", "size": 50000000},
{"quality": "480p", "url": "https://cdn.aparat.com/.../480p.mp4", "size": 100000000},
{"quality": "720p", "url": "https://cdn.aparat.com/.../720p.mp4", "size": 250000000},
{"quality": "1080p", "url": "https://cdn.aparat.com/.../1080p.mp4", "size": 500000000}
],
"thumbnail": "https://cdn.aparat.com/.../thumb.jpg",
"duration": 600
}
API:
Endpoint: POST /api/convert/callback
۲.۶ ثبت Content ID
زمان اجرا: وقتی کاربر گزینه "فعالسازی حق نشر" را انتخاب کرده باشد
عملکرد:
- هش MD5 ویدئو را در جدول
content_idثبت میکند - مالکیت این هش را برای کاربر ثبت میکند
- ویدئوهای مشابه دیگر کاربران را جستجو میکند
- اگر یافت شد، آنها را حذف میکند (یا به صاحب Content ID اطلاع میدهد)
Query:
-- ثبت Content ID
INSERT INTO content_id (user_id, video_id, md5_hash, created_at)
VALUES (?, ?, ?, NOW())
-- جستجوی ویدئوهای مشابه
SELECT id FROM videos
WHERE md5_hash = ? AND user_id != ?
API:
Service: ContentIDService
Method: registerContentID(userId, videoId, md5Hash)
Method: findDuplicates(md5Hash, excludeUserId)
۳. اکشنهای مدیریت لیست پخش
۳.۱ افزودن ویدئو به لیستهای پخش
زمان اجرا: پس از ثبت نهایی ویدئو
عملکرد:
- لیستهای پخش انتخابشده توسط کاربر را میخواند
- برای هر لیست، یک رکورد در جدول
playlist_videosایجاد میکند - تعداد ویدئوهای لیست را update میکند
محدودیت:
- حداکثر ۵ لیست پخش
Query:
-- افزودن به لیست
INSERT INTO playlist_videos (playlist_id, video_id, position, created_at)
VALUES (?, ?, ?, NOW())
-- آپدیت تعداد
UPDATE playlists
SET video_count = video_count + 1
WHERE id = ?
۳.۲ ایجاد لیست پخش جدید
زمان اجرا: وقتی کاربر در حین آپلود، لیست پخش جدید میسازد
عملکرد:
- بررسی میکند تعداد لیستهای کاربر کمتر از ۱۰۰۰ باشد
- اگر بیشتر بود، بدون نمایش خطا عملیات را لغو میکند (silent fail)
- در غیر این صورت، لیست جدید را ایجاد میکند
Query:
-- بررسی تعداد
SELECT COUNT(*) FROM playlists WHERE user_id = ?
-- ایجاد لیست جدید
INSERT INTO playlists (user_id, title, video_count, created_at)
VALUES (?, ?, 0, NOW())
۴. اکشنهای آمار و Analytics
۴.۱ محاسبه آمار Real-time
زمان اجرا: هر ۳۰ دقیقه (Cron Job)
عملکرد:
- برای هر ویدئو، آمار را از جداول مختلف جمعآوری میکند:
- تعداد بازدید از جدول
video_views - تعداد لایک از جدول
video_likes - تعداد کامنت از جدول
comments
- تعداد بازدید از جدول
- این آمار را aggregate میکند
- در جدول
video_stats_cacheذخیره میکند
Query:
INSERT INTO video_stats_cache (video_id, views, likes, comments, calculated_at)
SELECT
video_id,
COUNT(DISTINCT view_id) as views,
(SELECT COUNT(*) FROM video_likes WHERE video_id = v.video_id) as likes,
(SELECT COUNT(*) FROM comments WHERE video_id = v.video_id) as comments,
NOW()
FROM video_views v
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 MINUTE)
GROUP BY video_id
هدف: سرعت بالای نمایش آمار به کاربر (بدون نیاز به query های پیچیده)
۴.۲ محاسبه آمار درآمد
زمان اجرا: هر ۱ ساعت (Cron Job)
عملکرد:
- درآمد تبلیغاتی هر ویدئو را از سیستم Ad Server دریافت میکند
- RPM (Revenue Per Mille) هر ویدئو را محاسبه میکند
- درآمد کل کاربر را جمع میزند
- در جدول
revenue_statsذخیره میکند
فرمول RPM:
RPM = (Total Revenue / Total Views) * 1000
۴.۳ ثبت لاگ بازدید
زمان اجرا: هر بار که کاربری ویدئو را تماشا میکند
عملکرد:
- اطلاعات بازدید را ثبت میکند:
- User ID (یا Anonymous)
- Video ID
- IP Address
- User Agent
- Referrer (از کجا آمده)
- Watch Time (چقدر از ویدئو را دیده)
- این دادهها برای محاسبه آمار استفاده میشوند
نکته: از Big Data tools مثل Kafka + Spark برای پردازش حجم بالای view logs استفاده میشود.
۵. اکشنهای Notification
۵.۱ ارسال نوتیفیکیشن پس از اتمام پردازش
زمان اجرا: پس از دریافت callback از تیم کانورت (وقتی ویدئو آماده شد)
عملکرد:
- یک نوتیفیکیشن ایجاد میکند
- به جدول
notificationsاضافه میکند - از طریق WebSocket یا Push Notification به کاربر ارسال میکند
محتوای notification:
{
"type": "video_ready",
"title": "ویدئوی شما آماده شد!",
"message": "ویدئوی «عنوان ویدئو» پردازش شد و آماده نمایش است.",
"link": "/dashboard/videos/67890",
"timestamp": "2024-11-16T10:30:00Z"
}
کانالهای ارسال:
- In-app notification
- Push notification (موبایل)
- ایمیل (اختیاری)
۵.۲ ارسال هشدارها (Alerts)
زمان اجرا: وقتی شرایط هشدار برقرار شود
عملکرد:
- سیستم شرایط هشدارهای تعریفشده را چک میکند
- اگر شرط برقرار باشد، هشدار را ارسال میکند
مثال: کاربر تنظیم کرده: "وقتی بازدید ویدئوی من از ۱۰,۰۰۰ گذشت، به من اطلاع بده"
if (video.views >= 10000 && !alert_sent) {
sendNotification(user, "ویدئوی شما به ۱۰,۰۰۰ بازدید رسید!")
markAlertAsSent(alert_id)
}
۶. اکشنهای بهینهسازی و Caching
۶.۱ کش کردن دادههای پرتکرار
زمان اجرا: همیشه
عملکرد: دادههایی که زیاد تغییر نمیکنند را در Redis cache میکند:
- آمار کلی کانال (TTL: 5 min)
- لیست ویدئوها (TTL: 10 min)
- اطلاعات پروفایل (TTL: 30 min)
Key Pattern:
user:{user_id}:stats
user:{user_id}:videos
video:{video_id}:stats
۶.۲ Invalidate کردن کش
زمان اجرا: وقتی داده تغییر میکند
عملکرد: کلیدهای مربوطه را از Redis حذف میکند تا دفعه بعد، داده fresh از دیتابیس خوانده شود.
مثال:
// وقتی ویدئو جدید آپلود شد
redis.del(`user:${userId}:videos`)
redis.del(`user:${userId}:stats`)
۷. اکشنهای نظافت (Cleanup)
۷.۱ حذف فایلهای موقت
زمان اجرا: هر روز ساعت ۳ بامداد (Cron Job)
عملکرد:
- فایلهای آپلود نیمهکاره که بیش از ۲۴ ساعت گذشته را پیدا میکند
- این فایلها را حذف میکند تا فضای دیسک آزاد شود
۷.۲ حذف نوتیفیکیشنهای قدیمی
زمان اجرا: هر هفته (Cron Job)
عملکرد: نوتیفیکیشنهای بیش از ۳ ماه قبل را حذف میکند (یا archive میکند).
۸. اکشنهای Monitoring و Health Check
۸.۱ بررسی سلامت سیستم
زمان اجرا: هر ۱ دقیقه
عملکرد:
- Ping به سرویسهای مختلف میزند:
- Database
- Redis
- Queue (RabbitMQ)
- CDN
- اگر مشکلی بود، alert به تیم DevOps میفرستد
۸.۲ جمعآوری Metrics
زمان اجرا: Real-time
عملکرد: متریکهای مختلف سیستم را جمعآوری و به Prometheus/Grafana میفرستد:
- تعداد درخواستها
- زمان پاسخ
- نرخ خطا
- استفاده از CPU/Memory
- تعداد آپلودهای موفق/ناموفق
جدول خلاصه System Actions
| نام اکشن | فرکانس اجرا | سرویس مسئول | اولویت |
|---|---|---|---|
| بررسی توکن | هر request | Auth Service | بحرانی |
| لاگ فعالیت | هر عملیات مهم | Logging Service | متوسط |
| محاسبه MD5 | حین آپلود | File Service | بالا |
| تشخیص تکراری | بعد از MD5 | Duplicate Service | بالا |
| ارسال به صف کانورت | بعد از آپلود | Queue Service | بحرانی |
| دریافت نتیجه کانورت | Callback | Webhook Handler | بحرانی |
| ثبت Content ID | اختیاری | Content ID Service | متوسط |
| محاسبه آمار | هر ۳۰ دقیقه | Analytics Service | متوسط |
| محاسبه درآمد | هر ۱ ساعت | Revenue Service | بالا |
| ارسال نوتیفیکیشن | Event-based | Notification Service | متوسط |
| کش کردن | Real-time | Cache Service | بالا |
| Cleanup | روزانه | Maintenance Service | پایین |
| Health Check | هر ۱ دقیقه | Monitoring Service | بحرانی |
نمودار تعاملات (Sequence Diagram)
فرآیند آپلود ویدئو
کاربر -> Frontend: انتخاب فایل
Frontend -> Backend: شروع آپلود
Backend -> FileService: محاسبه MD5
FileService -> Backend: MD5 Hash
Backend -> DuplicateService: چک تکراری
DuplicateService -> Database: Query
Database -> DuplicateService: نتیجه
DuplicateService -> Backend: OK
Backend -> Storage: ذخیره فایل
Storage -> Backend: File Path
Backend -> QueueService: ارسال به صف کانورت
QueueService -> ConvertWorker: پیام
Backend -> Frontend: آپلود موفق
Frontend -> کاربر: پیام موفقیت
... (پردازش در پسزمینه) ...
ConvertWorker -> ConvertService: شروع پردازش
ConvertService -> ConvertWorker: نتیجه
ConvertWorker -> Backend: Callback
Backend -> Database: ذخیره اطلاعات
Backend -> NotificationService: ارسال نوتیفیکیشن
NotificationService -> کاربر: ویدئو آماده شد!
پیوستها
API های مربوط به System Actions
/api/convert/callback- دریافت نتیجه از تیم کانورت/api/health- Health check/api/metrics- دریافت متریکها
سرویسهای خارجی
- RabbitMQ: صف پیامها
- Redis: Cache
- Kafka: Stream processing برای view logs
- Prometheus: Monitoring
- Grafana: Visualization
آخرین بهروزرسانی: ۱۴۰۳/۰۸/۲۶ نویسنده: تیم فنی آپارات