2017-09-24 19 views
6

मैं निम्नलिखित कोड है coroutines करने के लिए कैसे:पुराना वापस अवरुद्ध ग्राहक के साथ एक सीमित कॉल को लागू करने और

val context = newFixedThreadPoolContext(nThreads = 10, name="myThreadPool") 
val total = 1_000_000 //can be other number as well 
val maxLimit = 1_000 
return runBlocking { 
    (0..total step maxLimit).map { 
    async(context) { 
     val offset = it 
     val limit = it + maxLimit 
     blockingHttpCall(offset, limit) 
    } 
    }.flatMap { 
    it.await() 
    }.associateBy { 
    ... 
    }.toMutableMap() 
} 

मैं अवरुद्ध api के लिए एक साथ होने के लिए केवल 10 कॉल करना चाहते हैं। हालांकि, ऐसा लगता है कि उपरोक्त कोड ऐसा नहीं कर रहा है जैसा कि मुझे उम्मीद है (मुझे लगता है कि सभी कॉल तुरंत शुरू होते हैं), या कम से कम मुझे समझ में नहीं आता है कि यह करता है या नहीं।
इसे लागू करने का सही तरीका क्या है? क्या वही समाधान काम करेगा यदि मैं रेट्रोफिट के एसिंक एपीआई का उपयोग करता हूं?

+0

आपको क्या लगता है कि सभी कॉल एक साथ होते हैं? –

उत्तर

2

मैं बिल्कुल अपने मामले हैं, लेकिन सबसे आसान तरीका है पता नहीं है - संगामिति स्तर कॉन्फ़िगर करने के लिए एपीआई OkHttp उपयोग करते हैं, उदाहरण के लिए, इस default concurrency strategy of OkHttp

है लेकिन आप खुद रणनीति हो सकता है अगर आप OkHttpClient.Builder

को खुद Dispatcher उदाहरण सेट बेशक

, तो आप उपयोग कर सकते हैं भी coroutines

आपका वर्तमान कार्यान्वयन सही नहीं है, क्योंकि आप प्रत्येक आइटम के लिए coroutines डिस्पैचर बनाने के लिए, लेकिन धागे की पूल सभी coroutines ही डिस्पैचर का उपयोग करना चाहिए साझा किया है, बस ले जाने केलूप के बाहरसृजन (अब आपके पास 10 धागे वाले प्रत्येक 1000 प्रेषक हैं)।

लेकिन मैं तुम्हें coroutines उपयोग करने के लिए अवरुद्ध कॉल +, बेहतर संगामिति OkHttp कॉन्फ़िगर करने के लिए (यह अधिक सुविधाजनक है) और गैर अवरुद्ध कॉल के साथ coroutines का उपयोग की सलाह नहीं देते (आप खुद एडाप्टर लिख सकते हैं या kotlin-coroutines-retrofit तरह मौजूदा और पुस्तकालय का उपयोग कर सकते हैं) । यह आपको अपने http अनुरोध और यूआई कोड या अन्य कार्यों को मिश्रण करने की अनुमति देगा।

तो यदि आप गैर-अवरुद्ध एपीआई + ओकेएचटीपी आंतरिक समेकन का उपयोग करते हैं, तो आपको समेकन को नियंत्रित करने के लिए विशेष कोड रखने की आवश्यकता नहीं है, बेशक, आप उपरोक्त उदाहरण में समवर्ती कॉल की संख्या सीमित कर सकते हैं (निश्चित प्रेषक के साथ निर्माण), लेकिन मुझे सच में नहीं लगता कि यह बहुत समझ में आता है, क्योंकि आप इसे समेकित स्तर कम कर सकते हैं, इसे बढ़ा नहीं सकते हैं।

गैर-अवरुद्ध एपीआई में जाने के बाद आप अपने सभी कोरआउट को समानांतर (यहां तक ​​कि यूआई थ्रेड में) में किसी भी कोरआउट डिस्पैचर में चला सकते हैं और बिना अवरुद्ध किए परिणामों के इंतजार कर सकते हैं।

इसके अलावा, ओकेएचटीपी क्लाइंट कॉन्फ़िगरेशन का उपयोग करके समेकन का निहित नियंत्रण आर्किटेक्चर के मामले में एक और सही तरीका के रूप में दिखता है (आपके पास डीआई कोड हो सकता है जो रेट्रोफिट + ओकेएचटीपी को कॉन्फ़िगर करता है और इसे पूर्व-कॉन्फ़िगर किए गए समवर्ती नीति के साथ आपके क्लाइंट कोड में प्रदान करता है)। बेशक, आप अन्य दृष्टिकोणों का उपयोग करके इसे प्राप्त कर सकते हैं, लेकिन यह मेरे लिए अधिक प्राकृतिक दिखता है।

+0

मैंने थ्रेड पूल के लिए कार्यान्वयन संपादित किया, वास्तव में मैंने सवाल को सरल बनाने के लिए 'वैल' को रेखांकित किया, इसलिए सवाल में यह एक गलती थी। तो उस मामले में, क्या मैं वास्तव में समवर्ती स्तर को सीमित करता हूं? क्या ऐसा इसलिए है क्योंकि पूल कॉल में निष्पादित करते समय पूल में मेरे थ्रेड अवरुद्ध हो जाते हैं ताकि उन्हें निलंबित नहीं किया जा सके? – oshai

+1

हां, आप अपने उदाहरण में समवर्ती स्तर को सीमित करते हैं, सभी धागे अवरुद्ध हैं और आप "थ्रेड की संख्या" अनुरोधों से अधिक नहीं चला सकते हैं। 'थ्रेड.sleep()' + 'println' के साथ 'blockingHttpCall' को प्रतिस्थापित करने पर आप इसे आसानी से देख सकते हैं, लेकिन आप गैर-अवरुद्ध कॉल के लिए इस दृष्टिकोण का उपयोग नहीं कर सकते हैं (आप' थ्रेड.sleep()' को देरी के साथ बदल सकते हैं () 'और जांचें कि उसके बाद व्यवहार कैसे बदल गया) – gildor

+1

लेकिन यदि आप अनुरोधों के अगले भाग शुरू होने पर अपने उदाहरण को फिर से लिखते हैं तो आपके समेकन को सीमित कर सकते हैं (आपके उदाहरण अनुरोध में आपने पिछले समाप्त होने के बाद' async' का उपयोग करके कोरआउट का निर्माण किया)। लेकिन फिर यह आपके मामले पर निर्भर करता है (उदाहरण के लिए बड़ी बात यह है कि आप परिणाम कैसे संभालते हैं) और रेट्रोफिट के मामले में मुझे अभी भी लगता है कि OkHttp को समवर्ती नियंत्रण को नियंत्रित करने के लिए बेहतर है। – gildor

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