আমার এমন একাধিক কর্ম রয়েছে যা একাধিক কাতারে কর্মীদের উপর চলে, যার মধ্যে গুজল ব্যবহার করে কিছু এইচটিটিপি অনুরোধ রয়েছে। যাইহোক, এই কাজের অভ্যন্তরের ট্রাই-ক্যাচ ব্লকটি GuzzleHttp\Exception\RequestException
যখন আমি ব্যাকগ্রাউন্ড প্রক্রিয়াতে এই কাজটি চালাচ্ছি তখন আপস আপ লাগে না । চলমান প্রক্রিয়াটি হ'ল php artisan queue:work
লারাভেল কিউ সিস্টেম কর্মী যা সারিবদ্ধ নজরদারি করে এবং কাজগুলি সন্ধান করে।
পরিবর্তে, ফেলে দেওয়া ব্যতিক্রম GuzzleHttp\Promise\RejectionException
বার্তাটির মধ্যে একটি:
প্রতিশ্রুতি যুক্তি দিয়ে প্রত্যাখ্যান করা হয়েছিল: সিআরএল ত্রুটি ২৮: 0 বাইট পেয়ে 30001 মিলি সেকেন্ডের পরে অপারেশন শেষ হয়েছে ( https://curl.haxx.se/libcurl/c/libcurl-erferences.html দেখুন )
এটি আসলে ছদ্মবেশযুক্ত GuzzleHttp\Exception\ConnectException
( https://github.com/g Puzzle / promises / blob / master / src / RejectException.php#L22 দেখুন ), কারণ যদি আমি একটি নিয়মিত পিএইচপি প্রক্রিয়াতে একই রকম কাজ চালাই তবে যেটি দেখার মাধ্যমে ট্রিগার হয় is ইউআরএল, আমি ConnectException
বার্তাটির সাথে মতামতটি পেয়েছি :
সিআরএল ত্রুটি 28: 0 টি বাইটের মধ্যে 0 টি দিয়ে 100 মিলিসেকেন্ডের পরে অপারেশন শেষ হয়েছে ( https://curl.haxx.se/libcurl/c/libcurl-erferences.html দেখুন )
নমুনা কোড যা এই টাইমআউটটিকে ট্রিগার করবে:
try {
$c = new \GuzzleHttp\Client([
'timeout' => 0.1
]);
$response = (string) $c->get('https://example.com')->getBody();
} catch(GuzzleHttp\Exception\RequestException $e) {
// This occasionally gets catched when a ConnectException (child) is thrown,
// but it doesnt happen with RejectionException because it is not a child
// of RequestException.
}
উপরের কোডটি হয় কর্মী প্রক্রিয়ায় দৌড়ে একটি RejectionException
বা ConnectException
যখন ছুঁড়ে মারে ConnectException
তবে ব্রাউজারের মাধ্যমে ম্যানুয়ালি পরীক্ষা করা হয় (যা আমি বলতে পারি তা থেকে)।
সুতরাং মূলত আমি যা আহরণ করি তা RejectionException
হ'ল এটি বার্তাটি মোড়ানো হয় ConnectException
তবে আমি গুজলের অ্যাসিনক্রোনাস বৈশিষ্ট্যগুলি ব্যবহার করছি না। আমার অনুরোধগুলি কেবল সিরিজে করা হয়। কেবলমাত্র পার্থক্যটি হ'ল একাধিক পিএইচপি প্রক্রিয়াগুলি গুজল এইচটিটিপি কলগুলি করতে পারে বা নিজেই চাকরির সময়সীমা শেষ হতে পারে (যার ফলস্বরূপ লারাভেলের একটি আলাদা ব্যতিক্রম হওয়া উচিত Illuminate\Queue\MaxAttemptsExceededException
) তবে আমি দেখতে পাচ্ছি না যে কীভাবে এই কোডটি আলাদাভাবে আচরণ করে causes
ব্রাউজার ট্রিগারের বিপরীতে সিএলআই থেকে চালিত হওয়ার সময় বিভিন্ন স্টাফ চালানোর জন্য গুজল প্যাকেজগুলি php_sapi_name()
/ PHP_SAPI
যা (যা ব্যবহৃত ইন্টারফেসটি নির্ধারণ করে) ব্যবহার করছে সেগুলির মধ্যে আমি কোনও কোড খুঁজে পাইনি ।
TL; ড
গুজল কেন RejectionException
আমার কর্মী প্রক্রিয়াগুলিতে আমাকে ছুঁড়ে ফেলে , তবে ConnectException
ব্রাউজারের মাধ্যমে নিয়মিত পিএইচপি স্ক্রিপ্টগুলিতে চালিত হয়?
সম্পাদনা 1
দুঃখের বিষয় আমি ন্যূনতম প্রজননযোগ্য উদাহরণ তৈরি করতে পারি না। উপরে দেখানো সঠিক ব্যতিক্রম সহ আমি আমার সেন্ট্রি ইস্যু ট্র্যাকারে অনেক ত্রুটি বার্তা দেখতে পাচ্ছি। উত্সটি হিসাবে বর্ণিত হয়েছে Starting Artisan command: horizon:work
(যা লারাভেল হরাইজন, এটি লারাভেল সারিতে তদারকি করে)। পিএইচপি সংস্করণগুলির মধ্যে কোনও তাত্পর্য আছে কিনা তা আমি আবার পরীক্ষা করে দেখেছি, তবে ওয়েবসাইট এবং কর্মী উভয়ই একই পিএইচপি চালায় 7.3.14
যা সঠিক:
PHP 7.3.14-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Jan 23 2020 13:59:16) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.14, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.14-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
- সিআরএল সংস্করণটি
cURL 7.58.0
। - গুজল সংস্করণটি
guzzlehttp/guzzle 6.5.2
- লারাভেল সংস্করণটি
laravel/framework 6.12.0
সম্পাদনা 2 (স্ট্যাক ট্রেস)
GuzzleHttp\Promise\RejectionException: The promise was rejected with reason: cURL error 28: Operation timed out after 30000 milliseconds with 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
#44 /vendor/guzzlehttp/promises/src/functions.php(112): GuzzleHttp\Promise\exception_for
#43 /vendor/guzzlehttp/promises/src/Promise.php(75): GuzzleHttp\Promise\Promise::wait
#42 /vendor/guzzlehttp/guzzle/src/Client.php(183): GuzzleHttp\Client::request
#41 /app/Bumpers/Client.php(333): App\Bumpers\Client::callRequest
#40 /app/Bumpers/Client.php(291): App\Bumpers\Client::callFunction
#39 /app/Bumpers/Client.php(232): App\Bumpers\Client::bumpThread
#38 /app/Models/Bumper.php(206): App\Models\Bumper::post
#37 /app/Jobs/PostBumper.php(59): App\Jobs\PostBumper::handle
#36 [internal](0): call_user_func_array
#35 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}
#34 /vendor/laravel/framework/src/Illuminate/Container/Util.php(36): Illuminate\Container\Util::unwrapIfClosure
#33 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\BoundMethod::callBoundMethod
#32 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::call
#31 /vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\Container::call
#30 /vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Bus\Dispatcher::Illuminate\Bus\{closure}
#29 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#28 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline::then
#27 /vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Bus\Dispatcher::dispatchNow
#26 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(83): Illuminate\Queue\CallQueuedHandler::Illuminate\Queue\{closure}
#25 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#24 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline::then
#23 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(85): Illuminate\Queue\CallQueuedHandler::dispatchThroughMiddleware
#22 /vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(59): Illuminate\Queue\CallQueuedHandler::call
#21 /vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\Jobs\Job::fire
#20 /vendor/laravel/framework/src/Illuminate/Queue/Worker.php(354): Illuminate\Queue\Worker::process
#19 /vendor/laravel/framework/src/Illuminate/Queue/Worker.php(300): Illuminate\Queue\Worker::runJob
#18 /vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker::daemon
#17 /vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Console\WorkCommand::runWorker
#16 /vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand::handle
#15 /vendor/laravel/horizon/src/Console/WorkCommand.php(46): Laravel\Horizon\Console\WorkCommand::handle
#14 [internal](0): call_user_func_array
#13 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}
#12 /vendor/laravel/framework/src/Illuminate/Container/Util.php(36): Illuminate\Container\Util::unwrapIfClosure
#11 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\BoundMethod::callBoundMethod
#10 /vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::call
#9 /vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\Container::call
#8 /vendor/laravel/framework/src/Illuminate/Console/Command.php(201): Illuminate\Console\Command::execute
#7 /vendor/symfony/console/Command/Command.php(255): Symfony\Component\Console\Command\Command::run
#6 /vendor/laravel/framework/src/Illuminate/Console/Command.php(188): Illuminate\Console\Command::run
#5 /vendor/symfony/console/Application.php(1012): Symfony\Component\Console\Application::doRunCommand
#4 /vendor/symfony/console/Application.php(272): Symfony\Component\Console\Application::doRun
#3 /vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application::run
#2 /vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Illuminate\Console\Application::run
#1 /vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Foundation\Console\Kernel::handle
#0 /artisan(37): null
Client::callRequest()
ফাংশন কেবল একটি মদ্যপানোত্সব ক্লায়েন্ট যার উপর আমি ফোন রয়েছে $client->request($request['method'], $request['url'], $request['options']);
(তাই তোমার দর্শন লগ করা ব্যবহার করছেন না requestAsync()
)। আমি মনে করি সমান্তরালভাবে কাজ চালানোর সাথে এর কিছু করার আছে যা এই সমস্যার কারণ হয়ে দাঁড়ায়।
3 সম্পাদনা করুন (সমাধান পাওয়া গেছে)
নিম্নলিখিত টেস্টকেসটি বিবেচনা করুন যা HTTP অনুরোধ করে (যা নিয়মিত 200 প্রতিক্রিয়া ফিরিয়ে আনবে):
try {
$c = new \GuzzleHttp\Client([
'base_uri' => 'https://example.com'
]);
$handler = $c->getConfig('handler');
$handler->push(\GuzzleHttp\Middleware::mapResponse(function(ResponseInterface $response) {
// Create a fake connection exception:
$e = new \GuzzleHttp\Exception\ConnectException('abc', new \GuzzleHttp\Psr7\Request('GET', 'https://example.com/2'));
// These 2 lines both cascade as `ConnectException`:
throw $e;
return \GuzzleHttp\Promise\rejection_for($e);
// This line cascades as a `RejectionException`:
return \GuzzleHttp\Promise\rejection_for($e->getMessage());
}));
$c->get('');
} catch(\Exception $e) {
var_dump($e);
}
এখন আমি যা করলাম তা কল ছিল rejection_for($e->getMessage())
যা RejectionException
বার্তাটির স্ট্রিংয়ের উপর নির্ভর করে নিজস্ব তৈরি করে। কলিং rejection_for($e)
এখানে সঠিক সমাধান ছিল। উত্তর দেওয়ার জন্য কেবলমাত্র এই জিনিসটি যদি এই rejection_for
ফাংশনটি সাধারণ হিসাবে একই হয় throw $e
।
HandlerStack
:)?