আমি যদি প্রতিক্রিয়া বন্ধ না করি তবে কী হতে পারে?


98

গো-এ, আমার কিছু http প্রতিক্রিয়া রয়েছে এবং আমি মাঝে মাঝে কল করতে ভুলে যাই:

resp.Body.Close()

এক্ষেত্রে কী হয়? একটি স্মৃতি ফাঁস হবে? এছাড়াও defer resp.Body.Close()প্রতিক্রিয়া অবজেক্ট পাওয়ার পরে অবিলম্বে রাখা কি নিরাপদ ?

client := http.DefaultClient
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
    return nil, err
}

কি হবে যদি একটি ত্রুটি হয়, পারা respবা resp.Bodyশূন্য হবে?


মুলতুবি রেফারেন্স রাখার জন্য এটি ঠিক আছে ody অন্যদিকে অনুরোধটি সফল হলে দেহের স্পষ্টরূপে বন্ধ হওয়া দরকার।
বসন্ত গণেশ কে

উত্তর:


110

এক্ষেত্রে কী হয়? একটি স্মৃতি ফাঁস হবে?

এটি একটি রিসোর্স লিক। সংযোগটি পুনরায় ব্যবহার করা হবে না, এবং ফাইল বিবরণকারীকে মুক্ত করা হবে না সে ক্ষেত্রে এটি উন্মুক্ত থাকতে পারে।

এছাড়াও প্রতিক্রিয়া অবজেক্ট পাওয়ার পরে অবিলম্বে স্থগিত রেখে দেওয়াই নিরাপদ? বডি.ক্লোজ ()?

না, ডকুমেন্টেশনে প্রদত্ত উদাহরণটি অনুসরণ করুন এবং ত্রুটিটি যাচাই করার সাথে সাথে এটি বন্ধ করুন।

client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
    return nil, err
}
defer resp.Body.Close()

http.Clientডকুমেন্টেশন থেকে :

যদি প্রত্যাবর্তিত ত্রুটি শূন্য হয় তবে প্রতিক্রিয়াতে একটি নন-শিল শরীর থাকবে যা ব্যবহারকারীর দ্বারা বন্ধ হওয়া প্রত্যাশিত। বডি যদি উভয়ই ইওএফ-তে পড়ে না এবং বন্ধ হয় তবে ক্লায়েন্টের অন্তর্নিহিত রাউন্ডট্রিপার (সাধারণত পরিবহণ) পরবর্তীকালে "রাখুন" অনুরোধের জন্য সার্ভারের সাথে একটি অবিরাম টিসিপি সংযোগটি পুনরায় ব্যবহার করতে সক্ষম না হতে পারে।


4
এই লিঙ্ক অনুসারে আপনার কোডের সাথে সংযোগ ফাঁস করা এখনও সম্ভব। কিছু উদাহরণ রয়েছে যেখানে প্রতিক্রিয়াটি অ-শূন্য এবং ত্রুটিটি শূন্য নয়।
এমএমসিডোল

13
@ এমএমসিডোল: এই পোস্টটি ঠিক ভুল, এবং কোনও গ্যারান্টি নেই যে এটি আতঙ্কিত হবে না, যেহেতু কোনও ত্রুটির প্রতিক্রিয়া যা-ই ফিরে আসে তার কোনও সংজ্ঞায়িত রাষ্ট্র থাকে না। যদি কোনও ত্রুটির কারণে কোনও দেহ বন্ধ না হয় তবে এটি একটি ত্রুটি এবং এটির প্রতিবেদন করা দরকার। আপনার অফিশিয়াল ক্লায়েন্ট ডকুমেন্টেশনটি অনুসরণ করা উচিত , যা এলোমেলো ব্লগ পোস্টের পরিবর্তে "ত্রুটিযুক্ত, কোনও প্রতিক্রিয়া উপেক্ষা করা যেতে পারে" বলে উল্লেখ করেছে।
জিমবি

4
@ ডেল-বয়: আপনি যদি ক্লায়েন্টটি আরও অনুরোধ করার প্রত্যাশা করেন, তবে আপনার শরীরটি পড়ার চেষ্টা করা উচিত যাতে সংযোগটি পুনরায় ব্যবহার করা যায়। আপনার যদি সংযোগের প্রয়োজন না হয়, তবে শরীর পড়তে বিরক্ত করবেন না। আপনি যদি দেহটি পড়েন তবে এটি মুড়িয়ে দিন io.LimitReader। আমি সাধারণত একটি মোটামুটি ছোট সীমা ব্যবহার করি, কারণ যদি অনুরোধটি খুব বড় হয় তবে নতুন সংযোগ তৈরি করা দ্রুত।
জিম্ব

4
এটি উল্লেখ করার মতো যে _, err := client.Do(req)ফাইল বর্ণনাকারী খালি থাকার ফলেও ফলাফল করা যায়। সুতরাং এমনকি যদি কেউ প্রতিক্রিয়া কী তা যত্নশীল না করে, তবুও এটিকে একটি পরিবর্তনশীলতে নির্ধারিত করা এবং দেহটি বন্ধ করা প্রয়োজন।
j boschiero

4
আগ্রহী যে কেউ জন্য, পূর্ণ ডকুমেন্টেশন (জোর দেওয়া যোগ) হল: "ত্রুটি তারিখে, কোন রেসপন্স উপেক্ষিত হতে পারে একটি অ-শূন্য ত্রুটি সহ অ শূন্য রেসপন্স শুধুমাত্র ঘটে যখন CheckRedirect ব্যর্থ হয়, এবং। এমনকি তারপর ফিরে Response.Body আগে থেকেই বন্ধ। "
নিশান্থশানমুঘাম

15

যদি কোনও এফডির সাথে যুক্ত সংস্থানগুলি পদ্ধতির Response.Bodyসাথে বন্ধ Close()না করা হয় তবে মুক্ত করা হবে না। এটি একটি রিসোর্স লিক।

বন্ধ Response.Body

প্রতিক্রিয়া উত্স থেকে :

বডি বন্ধ করা কলারের দায়িত্ব।

সুতরাং অবজেক্টের সাথে আবদ্ধ কোনও চূড়ান্তকরণকারী নেই এবং এটি অবশ্যই স্পষ্টভাবে বন্ধ করা উচিত।

হ্যান্ডলিং এবং মুলতুবি পরিষ্কারগুলি ত্রুটি

ত্রুটি হলে, কোনও প্রতিক্রিয়া উপেক্ষা করা যেতে পারে। নন-শূন্য ত্রুটিযুক্ত একটি নন-নীল প্রতিক্রিয়া কেবল তখনই ঘটে যখন চেকরাইডারেক্ট ব্যর্থ হয়, এবং তারপরেও ফিরে আসা প্রতিক্রিয়া ody রক্ত ​​ইতিমধ্যে বন্ধ is

resp, err := http.Get("http://example.com/")
if err != nil {
    // Handle error if error is non-nil
}
defer resp.Body.Close() // Close body only if response non-nil

4
আপনার অবশ্যই লক্ষ্য করা উচিত যে এগুলি আপনার ত্রুটি পরিচালনার শর্তের মধ্যে ফিরে আসা উচিত। যদি ব্যবহারকারী তাদের ত্রুটি পরিচালনার ক্ষেত্রে ফিরে না আসে তবে এটি আতঙ্ক সৃষ্টি করবে।
আপেলউড

3

উপরে বর্ণিত জিনিসগুলি হিসাবে প্রথমে বর্ণনাকারী কখনই বন্ধ হয় না।

এবং আরও কী, গোলং মিথ্যা persistConnহলে এটি পুনরায় ব্যবহারের জন্য সংযোগটি (মোড়কে কাঠামো ব্যবহার করে ) ক্যাশে করবে DisableKeepAlives

ব্যবহার client.Doপদ্ধতি পরে গোলংয়ে , গো readLoopপদক্ষেপের এক হিসাবে গোরোটাইন পদ্ধতি চালাবে ।

সুতরাং গোলাং এইচটিপি-তে transport.go, পদ্ধতিটিতে রেক বাতিল হওয়া অবধি কোনও চ্যানেলে pconn(persistConn struct)রাখা হবে না এবং রেকটি idleConnবাতিল হওয়া অবধি readLoopএই গোরোটাইন ( readLoopপদ্ধতি) অবরুদ্ধ থাকবে।

কোডটি এটি দেখানো হচ্ছে।

আপনি যদি আরও জানতে চান তবে আপনাকে readLoopপদ্ধতিটি দেখতে হবে ।


1

Https://golang.org/src/net/http/client.go দেখুন
"যখন ত্রুটি শূন্য থাকে তখন শ্রমে সর্বদা একটি শূন্য থাকে না" রক্তাক্ত।

তবে তারা কখনই ত্রুটিযুক্ত হয় না! = শুক্রবার, শ্রদ্ধা সর্বদা শূন্য থাকে। তারা আরও বলে:
"যদি রেস্প.বডিটি বন্ধ না করা হয় তবে ক্লায়েন্টের অন্তর্নিহিত রাউন্ডট্রিপার (সাধারণত পরিবহন) পরবর্তীকালে" রাখুন-জীবিত "অনুরোধের জন্য সার্ভারের সাথে একটি ধ্রুবক টিসিপি সংযোগটি পুনরায় ব্যবহার করতে সক্ষম না হতে পারে।"

সুতরাং আমি সাধারণত এইভাবে সমস্যাটি সমাধান করেছি:

client := http.DefaultClient
resp, err := client.Do(req)
if resp != nil {
   defer resp.Body.Close()
}
if err != nil {
    return nil, err 
}

4
এটি ভুল, এবং কোনও গ্যারান্টি নেই যে শ্রদ্ধা রয়েছে B কোনও ত্রুটি আছে তখন রক্ত ​​নষ্ট হয় না।
জিমবি

4
ধন্যবাদ @ জিমবি। দস্তাবেজগুলিতে শব্দটি হ'ল "ত্রুটিতে, কোনও প্রতিক্রিয়া এড়ানো যায়।" এটি বলা আরও সঠিক হবে "ত্রুটি হলে, প্রতিক্রিয়া বডি সর্বদা বন্ধ থাকে।"
ক্যান্ডিটা

4
না, কারণ বন্ধ করার মতো কোনও প্রতিক্রিয়া সংস্থা সাধারণত নেই। আপনি যদি ডক্সে সেই অনুচ্ছেদটি পড়া চালিয়ে যান - "চেকরাইডারেক্ট ব্যর্থ হয় কেবল তখনই নন-নীল ত্রুটিযুক্ত একটি নন-নীল প্রতিক্রিয়া দেখা দেয় এবং তারপরেও ফিরে আসা প্রতিক্রিয়া ody রক্ত ​​ইতিমধ্যে বন্ধ closed"
জিম্ব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.