نسخة فاراداي:
فاراداي (0.11.0)
faraday_middleware (0.11.0.1)
faraday_middleware-aws-signers-v4 (0.1.5)
نسخة روبي:
ruby 2.3.0p0 (2015-12-25 مراجعة 53290) [x86_64-darwin15]
لدي واجهة تصل إلى بعض واجهات برمجة التطبيقات ، وكنت أستخدم اتصال فاراداي مع طريقة الحصول وتعيين إعادة المحاولة ، وكان كل شيء يعمل بشكل جيد حتى قمت بتغيير طريقة النشر ، ثم توقفت إعادة المحاولة عن العمل لقد بحثت في Google قليلاً لذا فهمت أن المنشور ليس كذلك المدرجة في
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
المرجع: https://github.com/lostisland/faraday/pull/437/files
ولا بد لي من استخدام retry_if إذا كنت أرغب في إعادة محاولة POST ولكن لم أجد وثائق dor retry_if .
لذا فإن اتصالي يبدو كما يلي:
def my_connection(my_api_endpoint)
Faraday.new(url: my_api_endpoint) do |faraday|
faraday.request :retry, max: 5, exceptions:
[BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed]
faraday.response :logger
faraday.adapter Faraday.default_adapter
faraday.options[:open_timeout] = 10
end
end
وتسميته بهذه الطريقة:
res = my_connection(my_api_endpoint).post do |req|
req.headers['Content-Type'] = 'application/json'
req.options.timeout = 25
req.body = body.to_json
end
أي مساعدة سوف تكون موضع ترحيب كبير.
مرحبًا yusefu ، نأسف لعدم وجود وثائق ، هذا شيء نحاول معالجته في الإصدار 1.0.
في غضون ذلك ، دعني أساعدك في مشكلتك. بشكل أساسي ، يعد retry_if
خيارًا يمكنك تمريره بالضبط بطريقة تمرير max: 5, exceptions: [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed]
. الاختلاف الوحيد هو أن retry_if
يجب أن يكون دالة (إما lambda أو proc.
إذا لم تكن معتادًا على هؤلاء ، فإنني أقترح استخدام proc
، والذي يمكن إنشاء مثيل له بـ Proc.new { ... }
أو باستخدام الأسطر المتعددة Proc.new do ... end
.
لذلك إذا كنت تريد استخدام retry_if
فإن المثال الخاص بك سيصبح شيئًا مثل:
def my_connection(my_api_endpoint)
# This is optional, I've added the <strong i="17">@connections</strong> memoized variable to avoid
# re-creating the connection every time. Not sure it's applicable to your case
# but consider it as it might improve performances
<strong i="18">@connections</strong> ||= []
@connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
faraday.request :retry, max: 5, exceptions:
[BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
retry_if: Proc.new do |env, exception|
# your implementation goes here...
end
faraday.response :logger
faraday.adapter Faraday.default_adapter
faraday.options[:open_timeout] = 10
end
end
ومع ذلك ، إذا كان هدفك الوحيد هو إضافة: النشر إلى قائمة طرق إعادة المحاولة ، فيمكنك أيضًا استخدام الخيار methods
المضاف إلى PR الذي قمت بربطه:
def my_connection(my_api_endpoint)
# This is optional, I've added the <strong i="23">@connections</strong> memoized variable to avoid
# re-creating the connection every time. Not sure it's applicable to your case
# but consider it as it might improve performances
<strong i="24">@connections</strong> ||= []
@connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
faraday.request :retry, max: 5, exceptions:
[BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
methods: Faraday::Request::Retry::IDEMPOTENT_METHODS + [:post]
faraday.response :logger
faraday.adapter Faraday.default_adapter
faraday.options[:open_timeout] = 10
end
end
واسمحوا لي أن أعرف إذا كان هذا يساعد 😄
أعطى مثيل الاتصالات خطأ TypeError.
expected MyAPI::BadRequest, got #<TypeError: {:req=>{}, :res=>nil, :headers=>nil, :reason_phrase=>nil}> with backtrace:
ولكن مع الإضافة البسيطة للنشر إلى IDEMPOTENT_METHODS ، يمكن الآن إعادة المحاولة .
شكرا جزيلا لك iMacTia 🙏 لقد نجح.
شكرًا لملاحظاتك yusefu وآسف على TypeError.
أعتقد أن المشكلة هي أن @connections
يجب أن يكون تجزئة ، وليس مصفوفة ، إنها سيئة!
<strong i="9">@connections</strong> ||= {}
على أي حال ، يسعدني معرفة أن مشكلتك قد تم حلها الآن 👍!
التعليق الأكثر فائدة
شكرًا لملاحظاتك yusefu وآسف على TypeError.
أعتقد أن المشكلة هي أن
@connections
يجب أن يكون تجزئة ، وليس مصفوفة ، إنها سيئة!على أي حال ، يسعدني معرفة أن مشكلتك قد تم حلها الآن 👍!