Merge branch 'main' of https://get.feep.ir/khaneghi_abshodeh/khaneghi_server
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Services\SmsBilling;
|
namespace App\Services\SmsBilling;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Client\Pool;
|
||||||
use Illuminate\Http\Client\Response;
|
use Illuminate\Http\Client\Response;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
@@ -201,6 +202,27 @@ class SuperAdminSmsClient
|
|||||||
$method = strtoupper($method);
|
$method = strtoupper($method);
|
||||||
$lastError = null;
|
$lastError = null;
|
||||||
|
|
||||||
|
if ($method === 'GET' && count($bases) > 1) {
|
||||||
|
$parallel = $this->requestJsonParallel(
|
||||||
|
$bases,
|
||||||
|
$canonicalPath,
|
||||||
|
$relativeUrl,
|
||||||
|
$query,
|
||||||
|
$timeout,
|
||||||
|
$label
|
||||||
|
);
|
||||||
|
if ($parallel !== null) {
|
||||||
|
return $parallel;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->forgetSuccessfulBase();
|
||||||
|
Log::warning("SuperAdmin SMS {$label} unavailable on all bases (parallel GET)", [
|
||||||
|
'bases' => $bases,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($bases as $index => $base) {
|
foreach ($bases as $index => $base) {
|
||||||
try {
|
try {
|
||||||
$pending = Http::withHeaders($this->authHeaders($method, $canonicalPath))
|
$pending = Http::withHeaders($this->authHeaders($method, $canonicalPath))
|
||||||
@@ -256,6 +278,8 @@ class SuperAdminSmsClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->forgetSuccessfulBase();
|
||||||
|
|
||||||
Log::warning("SuperAdmin SMS {$label} unavailable on all bases", [
|
Log::warning("SuperAdmin SMS {$label} unavailable on all bases", [
|
||||||
'bases' => $bases,
|
'bases' => $bases,
|
||||||
'last_error' => $lastError,
|
'last_error' => $lastError,
|
||||||
@@ -264,6 +288,88 @@ class SuperAdminSmsClient
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fan-out GET to all SuperAdmin hosts in parallel (max wait = one timeout, not N×timeout).
|
||||||
|
*
|
||||||
|
* @param list<string> $bases
|
||||||
|
* @param array<string, mixed> $query
|
||||||
|
* @return array<string, mixed>|null
|
||||||
|
*/
|
||||||
|
private function requestJsonParallel(
|
||||||
|
array $bases,
|
||||||
|
string $canonicalPath,
|
||||||
|
string $relativeUrl,
|
||||||
|
array $query,
|
||||||
|
int $timeout,
|
||||||
|
string $label
|
||||||
|
): ?array {
|
||||||
|
$headers = $this->authHeaders('GET', $canonicalPath);
|
||||||
|
$options = Controller::httpClientOptions([], (float) $timeout);
|
||||||
|
|
||||||
|
try {
|
||||||
|
/** @var array<string, Response|\Throwable> $responses */
|
||||||
|
$responses = Http::pool(function (Pool $pool) use ($bases, $headers, $relativeUrl, $query, $timeout, $options) {
|
||||||
|
foreach ($bases as $index => $base) {
|
||||||
|
$pool->as((string) $index)
|
||||||
|
->withHeaders($headers)
|
||||||
|
->acceptJson()
|
||||||
|
->connectTimeout(2)
|
||||||
|
->timeout($timeout)
|
||||||
|
->withOptions($options)
|
||||||
|
->get($this->urlForBase($base, $relativeUrl), $query);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning("SuperAdmin SMS {$label} parallel pool failed", [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($bases as $index => $base) {
|
||||||
|
$key = (string) $index;
|
||||||
|
if (! array_key_exists($key, $responses)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $responses[$key];
|
||||||
|
if ($response instanceof \Throwable) {
|
||||||
|
Log::warning("SuperAdmin SMS {$label} parallel exception", [
|
||||||
|
'base' => $base,
|
||||||
|
'error' => $response->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $response->successful()) {
|
||||||
|
Log::warning("SuperAdmin SMS {$label} parallel failed", [
|
||||||
|
'base' => $base,
|
||||||
|
'status' => $response->status(),
|
||||||
|
'body' => $response->body(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $response->json();
|
||||||
|
if (! is_array($data)) {
|
||||||
|
Log::warning("SuperAdmin SMS {$label} parallel invalid JSON", [
|
||||||
|
'base' => $base,
|
||||||
|
]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->rememberSuccessfulBase($base);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list<string>
|
* @return list<string>
|
||||||
*/
|
*/
|
||||||
@@ -340,6 +446,17 @@ class SuperAdminSmsClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function forgetSuccessfulBase(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Cache::forget(self::SUCCESS_BASE_CACHE_KEY);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::debug('SuperAdmin SMS sticky base cache forget failed', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function readSuccessfulBase(): ?string
|
private function readSuccessfulBase(): ?string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user