2017-02-21 13 views
6

गोलांग में, मैं इरादे पर contexts पास करने के लिए अन्य तरीकों और कार्यों के लिए काफी नया हूं। मैं समझता हूं कि कैसे context काम करता है, इसका उपयोग कैसे किया जाता है, यह कैसे मूल्य रखता है, यह माता-पिता context और उनके व्यवहार से कैसे संबंधित है - मैं पहले संदर्भ में उपयोग करने के लिए क्यों समझ नहीं पा रहा हूं।किसी संदर्भ के बीच निर्णय कैसे लें। डेडलाइन या एक साधारण टाइमर?

एक और विशिष्ट उदाहरण में, जो कंपनी मैं काम करता हूं, उसमें वास्तविक प्रश्न है, हमने कुछ बहुत लंबे समय से चलने वाले प्रश्नों की पहचान की है जो कि किनारे के मामले के कारण अक्सर होते हैं।

एक स्पष्ट समाधान जिसे हमने लेने का फैसला किया, हमारी बाधाओं को देखते हुए जब तक कि हम मूल कारण को ठीक करने के लिए समय निवेश नहीं करते हैं, उन प्रश्नों को मारना है जो 5 मिनट से अधिक समय लेते हैं।

हमारे लेन-देन को चलाने वाली विधि context स्वीकार करती है जिसे मूल रूप से एपीआई कॉल में शुरू किया जाता है। यह context लेनदेन समारोह के लिए सभी तरह से पारित किया गया है।

1) एक नया संदर्भ का उपयोग करना::

  • एक go routine में एक नया context.WithTimeout(ctx, time.Duration(5 * time.Minute))

  • घड़ी Done चैनल आरंभ करें और लेन-देन को मारने के उस पल में मुझे लगता है कि क्वेरी को मारने के लिए 2 समाधान पाया जब वहां एक संकेत होता है

  • यदि लेन-देन समय-समय पर सफलतापूर्वक समाप्त हो गया है, तो संदर्भ cancel संदर्भ और लेनदेन को अपेक्षित रूप से प्रतिबद्ध करें।

2) एक Timer का उपयोग करना:

  • एक Timer 5 के साथ मिनट अवधि
  • बनाएं समय खत्म हो गया है, तो लेन-देन,
  • वरना मारने लेन-देन के लिए प्रतिबद्ध।

तार्किक रूप से, वे एक ही समाधान कर रहे हैं, हालांकि, कब और कैसे एक सेट समय सीमा या एक अच्छे पुराने Timer के साथ एक context उपयोग करने के लिए तय करने के लिए?

+2

1,8 [ 'डेटाबेस/sql'] (के रूप में https://golang.org/pkg/database/sql /#DB.BeginTx0Z) किसी संदर्भ के उपयोग का समर्थन करता है। मुझे कल्पना है कि यह आपके निर्णय को सरल बना सकता है। – jmaloney

उत्तर

2

उत्तर में यह बताया गया है कि context.Context और time.Timer सिग्नल (रद्द) सिग्नल प्रदान करता है।

context.Context आप Context.Done() विधि जो बंद कर दिया जाएगा जब goroutines का उपयोग कर इसे समाप्त करना चाहिए के माध्यम से एक चैनल तक पहुँच देता है।

time.Timer आप Timer.C struct क्षेत्र जिस पर एक मूल्य निश्चित समय अवधि के बाद भेजा जाएगा किसी चैनल से पहुँच देता है (कि मूल्य वर्तमान समय होगा, लेकिन यहां महत्वपूर्ण नहीं)।

वहां, मुख्य बिंदु हाइलाइट किए गए हैं। चैनल बंद किसी भी संख्या में goroutines, और अनंत संख्या द्वारा देखा जा सकता है।Spec: Receive operator:

एक एक closed चैनल पर आपरेशन प्राप्त हमेशा तुरंत आगे बढ़ सकते हैं, उपज तत्व प्रकार के zero value किसी भी पूर्व में भेजे गए मूल्यों के बाद प्राप्त किया गया है।

तो Context का उपयोग मनोनीत और स्थानों की मनमानी संख्या को रद्द करने के संकेत के लिए किया जा सकता है। एक Timer का उपयोग केवल एक लक्ष्य को सिग्नल करने के लिए किया जा सकता है, जो उसके चैनल से मूल्य प्राप्त करता है। यदि एकाधिक ग्राहक सुन रहे हैं या अपने चैनल से प्राप्त करने का प्रयास कर रहे हैं, तो केवल इसे प्राप्त करने के लिए भाग्यशाली होगा।

यदि आप कोड के साथ काम कर रहे/काम कर रहे हैं जो पहले से ही context.Context का समर्थन करता/उम्मीद करता है, तो यह एक प्रश्न नहीं होना चाहिए जिसका उपयोग करना है। जाओ 1.8 भी more context support जोड़ा गया। संदर्भ समर्थन के साथ database/sql पैकेज में significant additions रहा है; DB.BeginTx() सहित:

प्रदान किया गया संदर्भ तब तक उपयोग किया जाता है जब तक लेनदेन प्रतिबद्ध नहीं होता है या वापस लुढ़काया जाता है। यदि संदर्भ रद्द कर दिया गया है, तो एसक्यूएल पैकेज लेनदेन को वापस लाएगा। Tx.Commit एक त्रुटि लौटाएगा यदि BeginTx को प्रदान किया गया संदर्भ रद्द कर दिया गया है।

यह context.Context का प्राथमिक उपयोग है: एपीआई सीमाओं के पार एक समय सीमा और संकेत निरस्तीकरण ले जाने के लिए, और यह (एक समवर्ती-सुरक्षित तरीके से किया जाता है के रूप में Context मूल्यों अपरिवर्तनीय हैं, और चैनल भी समवर्ती उपयोग के लिए सुरक्षित कर रहे हैं, डेटा रेस डिज़ाइन द्वारा नहीं हो सकते हैं; इस पर अधिक: If I am using channels properly should I need to use mutexes?)।

संबंधित ब्लॉग पोस्ट:

The Go Blog: Go Concurrency Patterns: Context

Pitfalls of context values and how to avoid or mitigate them in Go

Dave Cheney: Context is for cancelation

संबंधित मुद्दे

 संबंधित मुद्दे