İlk temizlik tamamlandı bir önceki projeden
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WeldLogTriggers;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Helpers\TransactionHelper;
|
||||
|
||||
/**
|
||||
* WeldLog Trigger Manager
|
||||
*
|
||||
* Manages the execution of all weld log triggers
|
||||
* Handles trigger execution order, timing, and error handling
|
||||
*/
|
||||
class WeldLogTriggerManager
|
||||
{
|
||||
/**
|
||||
* @var WeldLogTriggerRegistry Trigger registry
|
||||
*/
|
||||
protected $registry;
|
||||
|
||||
/**
|
||||
* @var float Overall start time
|
||||
*/
|
||||
protected $overallStartTime;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param WeldLogTriggerRegistry $registry
|
||||
*/
|
||||
public function __construct(WeldLogTriggerRegistry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all applicable triggers
|
||||
*
|
||||
* @param object $weldLogData Current weld log data
|
||||
* @param object|null $beforeData Previous weld log data (null for new records)
|
||||
* @param array $changedFields List of changed field names
|
||||
* @param bool $isNewRecord Whether this is a new record
|
||||
* @return array Execution results
|
||||
*/
|
||||
public function executeTriggers(
|
||||
$weldLogData,
|
||||
$beforeData = null,
|
||||
array $changedFields = [],
|
||||
bool $isNewRecord = false,
|
||||
?string $action = null
|
||||
): array {
|
||||
$this->overallStartTime = microtime(true);
|
||||
|
||||
Log::info("=== WELD LOG SAVE TRIGGER STARTED ===", [
|
||||
'weld_log_id' => $weldLogData->id,
|
||||
'timestamp' => now()->toDateTimeString(),
|
||||
'is_new_record' => $isNewRecord,
|
||||
'changed_fields_count' => count($changedFields),
|
||||
'changed_fields' => $changedFields,
|
||||
'action' => $action,
|
||||
'memory_usage_start' => round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
|
||||
]);
|
||||
|
||||
// Set database timeouts and memory limits
|
||||
TransactionHelper::setDatabaseTimeouts(300, 600, 600);
|
||||
ini_set('memory_limit', '2G');
|
||||
ini_set('max_execution_time', 600); // 10 minutes
|
||||
|
||||
$results = [];
|
||||
$triggers = $this->registry->getTriggersInOrder();
|
||||
|
||||
Log::info("Total triggers registered: " . count($triggers), [
|
||||
'trigger_names' => array_map(function($t) { return $t->getName(); }, $triggers)
|
||||
]);
|
||||
|
||||
foreach ($triggers as $trigger) {
|
||||
// Check if trigger should run
|
||||
if (!$trigger->shouldRun($changedFields, $isNewRecord)) {
|
||||
Log::info("Skipping trigger: {$trigger->getName()}", [
|
||||
'reason' => 'shouldRun returned false',
|
||||
'order' => $trigger->getOrder(),
|
||||
'dependent_fields' => $trigger->getDependentFields()
|
||||
]);
|
||||
|
||||
$results[$trigger->getName()] = [
|
||||
'skipped' => true,
|
||||
'reason' => 'shouldRun returned false'
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Execute sync or async
|
||||
if ($trigger->isAsync()) {
|
||||
$this->executeAsync($trigger, $weldLogData, $beforeData, $changedFields);
|
||||
$results[$trigger->getName()] = [
|
||||
'queued' => true,
|
||||
'execution' => 'async'
|
||||
];
|
||||
} else {
|
||||
try {
|
||||
$result = $trigger->execute($weldLogData, $beforeData, [
|
||||
'changed_fields' => $changedFields,
|
||||
'is_new_record' => $isNewRecord,
|
||||
'action' => $action
|
||||
]);
|
||||
$results[$trigger->getName()] = array_merge($result, [
|
||||
'executed' => true,
|
||||
'execution' => 'sync'
|
||||
]);
|
||||
} catch (\Throwable $th) {
|
||||
Log::error("Trigger execution failed: {$trigger->getName()}", [
|
||||
'error' => $th->getMessage(),
|
||||
'file' => $th->getFile(),
|
||||
'line' => $th->getLine(),
|
||||
'trace' => $th->getTraceAsString()
|
||||
]);
|
||||
|
||||
$results[$trigger->getName()] = [
|
||||
'executed' => false,
|
||||
'error' => $th->getMessage(),
|
||||
'execution' => 'sync'
|
||||
];
|
||||
|
||||
// Re-throw critical errors, log others
|
||||
if ($this->isCriticalTrigger($trigger->getName())) {
|
||||
throw $th;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->logOverallCompletion($weldLogData->id, $results);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute trigger asynchronously (via queue)
|
||||
*
|
||||
* @param \App\Services\WeldLogTriggers\Contracts\WeldLogTriggerInterface $trigger
|
||||
* @param object $weldLogData
|
||||
* @param object|null $beforeData
|
||||
* @param array $changedFields
|
||||
*/
|
||||
protected function executeAsync($trigger, $weldLogData, $beforeData, $changedFields)
|
||||
{
|
||||
// Future implementation: Dispatch job to queue
|
||||
// \App\Jobs\WeldLogTriggerJob::dispatch(
|
||||
// get_class($trigger),
|
||||
// $weldLogData->id,
|
||||
// $beforeData,
|
||||
// $changedFields
|
||||
// );
|
||||
|
||||
Log::info("Trigger queued (async execution): {$trigger->getName()}", [
|
||||
'weld_log_id' => $weldLogData->id,
|
||||
'note' => 'Async execution not yet implemented, falling back to sync'
|
||||
]);
|
||||
|
||||
// Fallback to sync execution for now
|
||||
try {
|
||||
$trigger->execute($weldLogData, $beforeData, [
|
||||
'changed_fields' => $changedFields,
|
||||
'is_new_record' => false,
|
||||
// $action is not available here in the current signature, but async isn't used yet anyway
|
||||
]);
|
||||
} catch (\Throwable $th) {
|
||||
Log::error("Async trigger execution failed: {$trigger->getName()}", [
|
||||
'error' => $th->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a trigger is critical (should stop execution on failure)
|
||||
*
|
||||
* @param string $triggerName
|
||||
* @return bool
|
||||
*/
|
||||
protected function isCriticalTrigger(string $triggerName): bool
|
||||
{
|
||||
// Define which triggers are critical
|
||||
$criticalTriggers = [
|
||||
'Spool Status Changer',
|
||||
'Line Lists Update',
|
||||
'NDE Matrix Update',
|
||||
'Construction Paint Logs Sync',
|
||||
'Paint Follow Ups Sync',
|
||||
];
|
||||
|
||||
return in_array($triggerName, $criticalTriggers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log overall execution completion
|
||||
*
|
||||
* @param int $weldLogId
|
||||
* @param array $results
|
||||
*/
|
||||
protected function logOverallCompletion($weldLogId, array $results)
|
||||
{
|
||||
$overallDuration = round((microtime(true) - $this->overallStartTime) * 1000, 2);
|
||||
|
||||
// Count execution statistics
|
||||
$executedCount = 0;
|
||||
$skippedCount = 0;
|
||||
$queuedCount = 0;
|
||||
$failedCount = 0;
|
||||
|
||||
foreach ($results as $triggerName => $result) {
|
||||
if (isset($result['executed']) && $result['executed']) {
|
||||
$executedCount++;
|
||||
} elseif (isset($result['skipped']) && $result['skipped']) {
|
||||
$skippedCount++;
|
||||
} elseif (isset($result['queued']) && $result['queued']) {
|
||||
$queuedCount++;
|
||||
} elseif (isset($result['executed']) && !$result['executed']) {
|
||||
$failedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Log::info("=== WELD LOG SAVE TRIGGER COMPLETED ===", [
|
||||
'weld_log_id' => $weldLogId,
|
||||
'timestamp' => now()->toDateTimeString(),
|
||||
'total_execution_time_ms' => $overallDuration,
|
||||
'total_execution_time_sec' => round($overallDuration / 1000, 3),
|
||||
'peak_memory_usage_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
|
||||
'final_memory_usage_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
|
||||
'statistics' => [
|
||||
'total_triggers' => count($results),
|
||||
'executed' => $executedCount,
|
||||
'skipped' => $skippedCount,
|
||||
'queued' => $queuedCount,
|
||||
'failed' => $failedCount
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registry instance
|
||||
*
|
||||
* @return WeldLogTriggerRegistry
|
||||
*/
|
||||
public function getRegistry(): WeldLogTriggerRegistry
|
||||
{
|
||||
return $this->registry;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user