feat: Add comprehensive documentation suite and reorganize project structure

- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
This commit is contained in:
SamiAhmed7777
2025-10-21 00:39:45 -07:00
commit 0b7e2d0a5b
6080 changed files with 1332936 additions and 0 deletions

372
start-workers.php Normal file
View File

@@ -0,0 +1,372 @@
<?php
/*******************************************************************************************************************
| EasyStream Queue Workers Starter
| Starts background workers for video processing and system maintenance
|*******************************************************************************************************************/
define('_ISVALID', true);
// Include core configuration
include_once 'f_core/config.core.php';
/**
* Queue Workers Management Script
*/
class WorkerManager
{
private $queueManager;
private $logger;
private $workers = [];
public function __construct()
{
$this->queueManager = new VQueueManager();
$this->logger = VLogger::getInstance();
}
/**
* Start all workers
*/
public function startWorkers()
{
echo "Starting EasyStream Queue Workers...\n";
echo str_repeat("=", 50) . "\n";
// Start video processing workers
$this->startVideoWorkers(2);
// Start general workers
$this->startGeneralWorkers(1);
// Schedule cleanup jobs
$this->scheduleCleanupJobs();
echo "\nAll workers started successfully!\n";
echo "Press Ctrl+C to stop all workers\n\n";
// Keep script running
$this->monitorWorkers();
}
/**
* Start video processing workers
* @param int $count Number of workers to start
*/
private function startVideoWorkers($count)
{
echo "Starting {$count} video processing workers...\n";
for ($i = 1; $i <= $count; $i++) {
$cmd = "php f_core/f_workers/queue-worker.php video_processing > logs/video_worker_{$i}.log 2>&1 &";
if (PHP_OS_FAMILY === 'Windows') {
$cmd = "start /B php f_core/f_workers/queue-worker.php video_processing > logs/video_worker_{$i}.log 2>&1";
}
$pid = $this->executeCommand($cmd);
if ($pid) {
$this->workers[] = [
'type' => 'video_processing',
'id' => $i,
'pid' => $pid,
'started' => time()
];
echo " ✓ Video worker {$i} started (PID: {$pid})\n";
} else {
echo " ✗ Failed to start video worker {$i}\n";
}
}
}
/**
* Start general workers
* @param int $count Number of workers to start
*/
private function startGeneralWorkers($count)
{
echo "Starting {$count} general workers...\n";
for ($i = 1; $i <= $count; $i++) {
$cmd = "php f_core/f_workers/queue-worker.php default notifications > logs/general_worker_{$i}.log 2>&1 &";
if (PHP_OS_FAMILY === 'Windows') {
$cmd = "start /B php f_core/f_workers/queue-worker.php default notifications > logs/general_worker_{$i}.log 2>&1";
}
$pid = $this->executeCommand($cmd);
if ($pid) {
$this->workers[] = [
'type' => 'general',
'id' => $i,
'pid' => $pid,
'started' => time()
];
echo " ✓ General worker {$i} started (PID: {$pid})\n";
} else {
echo " ✗ Failed to start general worker {$i}\n";
}
}
}
/**
* Schedule cleanup jobs
*/
private function scheduleCleanupJobs()
{
echo "Scheduling cleanup jobs...\n";
// Schedule daily cleanup at 2 AM
$cleanupData = [
'type' => 'full',
'log_retention_days' => 30,
'temp_file_max_age_hours' => 24,
'session_max_age_hours' => 168,
'failed_upload_max_age_hours' => 48,
'analytics_retention_days' => 90,
'queue_retention_hours' => 24
];
// Calculate delay until 2 AM tomorrow
$now = time();
$tomorrow2AM = strtotime('tomorrow 2:00 AM');
$delay = $tomorrow2AM - $now;
$jobId = $this->queueManager->enqueue('CleanupJob', $cleanupData, 'maintenance', $delay, 1);
if ($jobId) {
echo " ✓ Daily cleanup job scheduled (Job ID: {$jobId})\n";
echo " Next run: " . date('Y-m-d H:i:s', $tomorrow2AM) . "\n";
} else {
echo " ✗ Failed to schedule cleanup job\n";
}
// Schedule weekly database optimization
$dbOptimizeData = [
'type' => 'database'
];
// Calculate delay until Sunday 3 AM
$nextSunday3AM = strtotime('next Sunday 3:00 AM');
$weeklyDelay = $nextSunday3AM - $now;
$weeklyJobId = $this->queueManager->enqueue('CleanupJob', $dbOptimizeData, 'maintenance', $weeklyDelay, 1);
if ($weeklyJobId) {
echo " ✓ Weekly database optimization scheduled (Job ID: {$weeklyJobId})\n";
echo " Next run: " . date('Y-m-d H:i:s', $nextSunday3AM) . "\n";
}
}
/**
* Monitor workers and restart if needed
*/
private function monitorWorkers()
{
while (true) {
sleep(30); // Check every 30 seconds
foreach ($this->workers as $index => $worker) {
if (!$this->isProcessRunning($worker['pid'])) {
echo "Worker {$worker['type']}_{$worker['id']} (PID: {$worker['pid']}) has stopped. Restarting...\n";
// Restart the worker
$this->restartWorker($worker, $index);
}
}
// Log worker status every 5 minutes
if (time() % 300 === 0) {
$this->logWorkerStatus();
}
}
}
/**
* Restart a worker
* @param array $worker Worker info
* @param int $index Worker index
*/
private function restartWorker($worker, $index)
{
if ($worker['type'] === 'video_processing') {
$cmd = "php f_core/f_workers/queue-worker.php video_processing > logs/video_worker_{$worker['id']}.log 2>&1 &";
} else {
$cmd = "php f_core/f_workers/queue-worker.php default notifications > logs/general_worker_{$worker['id']}.log 2>&1 &";
}
if (PHP_OS_FAMILY === 'Windows') {
$cmd = str_replace(' &', '', $cmd);
$cmd = "start /B " . $cmd;
}
$pid = $this->executeCommand($cmd);
if ($pid) {
$this->workers[$index]['pid'] = $pid;
$this->workers[$index]['started'] = time();
echo " ✓ Worker restarted with PID: {$pid}\n";
} else {
echo " ✗ Failed to restart worker\n";
}
}
/**
* Execute command and return PID
* @param string $cmd Command to execute
* @return int|false PID or false on failure
*/
private function executeCommand($cmd)
{
if (PHP_OS_FAMILY === 'Windows') {
pclose(popen($cmd, 'r'));
return true; // Windows doesn't easily return PID
} else {
$output = shell_exec($cmd . ' echo $!');
return $output ? (int)trim($output) : false;
}
}
/**
* Check if process is running
* @param int $pid Process ID
* @return bool True if running
*/
private function isProcessRunning($pid)
{
if (PHP_OS_FAMILY === 'Windows') {
$output = shell_exec("tasklist /FI \"PID eq {$pid}\" 2>NUL");
return strpos($output, (string)$pid) !== false;
} else {
return file_exists("/proc/{$pid}");
}
}
/**
* Log worker status
*/
private function logWorkerStatus()
{
$runningWorkers = count($this->workers);
$queueStats = $this->queueManager->getQueueStatistics();
$this->logger->info('Worker status check', [
'running_workers' => $runningWorkers,
'queue_stats' => $queueStats,
'uptime' => time() - $this->workers[0]['started']
]);
}
/**
* Stop all workers
*/
public function stopWorkers()
{
echo "Stopping all workers...\n";
foreach ($this->workers as $worker) {
if (PHP_OS_FAMILY === 'Windows') {
shell_exec("taskkill /PID {$worker['pid']} /F 2>NUL");
} else {
shell_exec("kill {$worker['pid']} 2>/dev/null");
}
echo " ✓ Stopped worker {$worker['type']}_{$worker['id']} (PID: {$worker['pid']})\n";
}
echo "All workers stopped.\n";
}
/**
* Show help
*/
public function showHelp()
{
echo "\nEasyStream Queue Workers Manager\n";
echo str_repeat("=", 40) . "\n\n";
echo "Usage: php start-workers.php [command]\n\n";
echo "Commands:\n";
echo " start Start all workers (default)\n";
echo " stop Stop all workers\n";
echo " status Show worker status\n";
echo " help Show this help\n\n";
echo "Examples:\n";
echo " php start-workers.php\n";
echo " php start-workers.php start\n";
echo " php start-workers.php stop\n\n";
}
/**
* Show worker status
*/
public function showStatus()
{
echo "EasyStream Workers Status\n";
echo str_repeat("=", 30) . "\n\n";
$queueStats = $this->queueManager->getQueueStatistics();
$health = $this->queueManager->healthCheck();
echo "System Health: " . strtoupper($health['status']) . "\n";
echo "Backend: " . $health['backend'] . "\n\n";
if (!empty($queueStats)) {
echo "Queue Statistics:\n";
foreach ($queueStats as $queue => $stats) {
echo " {$queue}:\n";
echo " Pending: " . ($stats['pending'] ?? 0) . "\n";
echo " Processing: " . ($stats['processing'] ?? 0) . "\n";
echo " Completed: " . ($stats['completed'] ?? 0) . "\n";
echo " Failed: " . ($stats['failed'] ?? 0) . "\n\n";
}
}
}
}
// CLI execution
if (php_sapi_name() === 'cli') {
$manager = new WorkerManager();
$command = $argv[1] ?? 'start';
// Handle shutdown signals
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGTERM, function() use ($manager) {
$manager->stopWorkers();
exit(0);
});
pcntl_signal(SIGINT, function() use ($manager) {
$manager->stopWorkers();
exit(0);
});
}
switch ($command) {
case 'start':
$manager->startWorkers();
break;
case 'stop':
$manager->stopWorkers();
break;
case 'status':
$manager->showStatus();
break;
case 'help':
case '--help':
case '-h':
$manager->showHelp();
break;
default:
echo "Unknown command: {$command}\n";
$manager->showHelp();
exit(1);
}
}
?>