fix: prevent sync timeout and memory issues for large patient batches

This commit is contained in:
SajjadMahmoody 2026-06-02 01:58:55 +03:30
parent ddad4da95c
commit e4b3d4dd99
1 changed files with 35 additions and 10 deletions

View File

@ -80,6 +80,7 @@ public function isFtpConfigured(): bool
public function sync(): array public function sync(): array
{ {
set_time_limit(0);
$report = []; $report = [];
$baseUrl = "http://{$this->peerIp}:{$this->peerPort}"; $baseUrl = "http://{$this->peerIp}:{$this->peerPort}";
@ -428,31 +429,38 @@ private function extractFilePaths(array $changes): array
private function pushFilesViaHttp(array $changes, string $baseUrl, array &$report): void private function pushFilesViaHttp(array $changes, string $baseUrl, array &$report): void
{ {
$currentPaths = $this->extractFilePaths($changes); $currentPaths = $this->extractFilePaths($changes);
$pendingPaths = $this->getPendingFiles('c2s'); $pendingPaths = $this->getPendingFiles('c2s');
$allPaths = array_values(array_unique(array_merge($pendingPaths, $currentPaths))); $allPaths = array_values(array_unique(array_merge($pendingPaths, $currentPaths)));
$failedPaths = []; $failedPaths = [];
foreach ($allPaths as $filePath) { foreach ($allPaths as $filePath) {
if (! Storage::disk('public')->exists($filePath)) { $localPath = Storage::disk('public')->path($filePath);
if (! file_exists($localPath)) {
$report[] = "فایل [{$filePath}] در سیستم محلی یافت نشد ✗"; $report[] = "فایل [{$filePath}] در سیستم محلی یافت نشد ✗";
continue; continue;
} }
$stream = fopen($localPath, 'rb');
try { try {
$response = Http::timeout(600) $response = Http::timeout(600)
->withHeader('X-Sync-Token', $this->token) ->withHeader('X-Sync-Token', $this->token)
->attach('file', Storage::disk('public')->get($filePath), basename($filePath)) ->attach('file', $stream, basename($filePath))
->post("{$baseUrl}/api/sync/receive-file", ['path' => $filePath]); ->post("{$baseUrl}/api/sync/receive-file", ['path' => $filePath]);
if ($response->successful()) { if ($response->successful()) {
$report[] = "فایل [{$filePath}] ارسال شد (HTTP) ✓"; $report[] = "فایل [{$filePath}] ارسال شد (HTTP) ✓";
} else { } else {
$report[] = "فایل [{$filePath}] ارسال نشد (HTTP) ✗ " . $response->status(); $report[] = "فایل [{$filePath}] ارسال نشد (HTTP) ✗ " . $response->status();
$failedPaths[] = $filePath; $failedPaths[] = $filePath;
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
$report[] = "فایل [{$filePath}] ارسال نشد (HTTP) ✗ " . $e->getMessage(); $report[] = "فایل [{$filePath}] ارسال نشد (HTTP) ✗ " . $e->getMessage();
$failedPaths[] = $filePath; $failedPaths[] = $filePath;
} finally {
if (is_resource($stream)) {
fclose($stream);
}
} }
} }
@ -464,8 +472,8 @@ private function pushFilesViaHttp(array $changes, string $baseUrl, array &$repor
private function syncFilesViaHttp(array $changes, string $baseUrl, array &$report): void private function syncFilesViaHttp(array $changes, string $baseUrl, array &$report): void
{ {
$localBase = rtrim(Storage::disk('public')->path(''), '/\\');
$currentPaths = $this->extractFilePaths($changes); $currentPaths = $this->extractFilePaths($changes);
$pendingPaths = $this->getPendingFiles('s2c'); $pendingPaths = $this->getPendingFiles('s2c');
$allPaths = array_values(array_unique(array_merge($pendingPaths, $currentPaths))); $allPaths = array_values(array_unique(array_merge($pendingPaths, $currentPaths)));
$failedPaths = []; $failedPaths = [];
@ -474,20 +482,37 @@ private function syncFilesViaHttp(array $changes, string $baseUrl, array &$repor
if (Storage::disk('public')->exists($filePath)) { if (Storage::disk('public')->exists($filePath)) {
continue; continue;
} }
$localFile = $localBase . '/' . $filePath;
$partFile = $localFile . '.part';
$localDir = dirname($localFile);
try { try {
if (! is_dir($localDir)) {
mkdir($localDir, 0755, true);
}
if (file_exists($partFile)) {
@unlink($partFile);
}
$response = Http::timeout(60) $response = Http::timeout(60)
->withHeader('X-Sync-Token', $this->token) ->withHeader('X-Sync-Token', $this->token)
->get("{$baseUrl}/api/sync/file", ['path' => $filePath]); ->get("{$baseUrl}/api/sync/file", ['path' => $filePath]);
if ($response->successful()) { if ($response->successful()) {
Storage::disk('public')->put($filePath, $response->body()); file_put_contents($partFile, $response->body());
rename($partFile, $localFile);
$report[] = "فایل [{$filePath}] دریافت شد (HTTP) ✓"; $report[] = "فایل [{$filePath}] دریافت شد (HTTP) ✓";
} else { } else {
$report[] = "فایل [{$filePath}] دریافت نشد (HTTP) ✗ " . $response->status(); $report[] = "فایل [{$filePath}] دریافت نشد (HTTP) ✗ " . $response->status();
$failedPaths[] = $filePath; $failedPaths[] = $filePath;
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
$report[] = "فایل [{$filePath}] دریافت نشد (HTTP) ✗ " . $e->getMessage(); if (file_exists($partFile)) {
@unlink($partFile);
}
$report[] = "فایل [{$filePath}] دریافت نشد (HTTP) ✗ " . $e->getMessage();
$failedPaths[] = $filePath; $failedPaths[] = $filePath;
} }
} }