ओब्जर्वेबल बनाम फ्लोएबल rxJava2


128

मैं नए आरएक्स जावा 2 को देख रहा हूं और मुझे यकीन नहीं है कि मैं backpressureअब के विचार को समझता हूं ...

मुझे पता है कि हमारे Observableपास backpressureसमर्थन है और Flowableउसके पास नहीं है।

तो उदाहरण के आधार पर, मैं कहता हूं कि मेरे पास flowableहै interval:

        Flowable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

यह लगभग 128 मूल्यों के बाद दुर्घटनाग्रस्त होने जा रहा है, और यह स्पष्ट है कि मैं आइटम प्राप्त करने की तुलना में धीमी खपत कर रहा हूं।

लेकिन फिर हमारे साथ भी ऐसा ही है Observable

     Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

यह बिल्कुल भी दुर्घटनाग्रस्त नहीं होगा, तब भी जब मैं इसके सेवन पर कुछ देरी करता हूं। Flowableकाम करने के लिए मैं कहता हूं कि मैं onBackpressureDropऑपरेटर डाल रहा हूं , दुर्घटना हो गई है, लेकिन सभी मूल्यों को उत्सर्जित नहीं किया जाता है।

इसलिए आधार प्रश्न मैं वर्तमान में मेरे सिर में उत्तर नहीं पा सकता है, मुझे इस बात की परवाह क्यों करनी चाहिए कि मैं backpressureसादे का उपयोग कर सकता हूं फिर Observableभी सभी मूल्यों को प्रबंधित किए बिना प्राप्त कर सकता हूं buffer? या हो सकता है कि दूसरी तरफ, backpressureउपभोग को संभालने और संभालने के पक्ष में मुझे क्या फायदे हों ?


जवाबों:


123

व्यवहार Flowable.observeOnमें जो बैकप्रेशर प्रकट होता है, वह बफ़र से जुड़ा होता है, इसमें 128 तत्वों का एक बफर होता है जो कि जितनी जल्दी हो सके उतनी तेज़ी से बाहर निकलता है। आप व्यक्तिगत रूप से बर्फीले स्रोत को संभालने के लिए इस बफ़र के आकार को बढ़ा सकते हैं और सभी बैकप्रेशर-प्रबंधन अभ्यास अभी भी 1.x से लागू होते हैं। Observable.observeOnएक अनबाउंड बफर है जो तत्वों को इकट्ठा करता रहता है और आपका ऐप मेमोरी से बाहर हो सकता है।

आप Observableउदाहरण के लिए उपयोग कर सकते हैं :

  • GUI इवेंट्स को हैंडल करना
  • छोटे अनुक्रमों के साथ काम करना (कुल 1000 से कम तत्व)

आप Flowableउदाहरण के लिए उपयोग कर सकते हैं :

  • ठंड और गैर-समय पर स्रोत
  • स्रोतों की तरह जनरेटर
  • नेटवर्क और डेटाबेस एक्सेसर्स

चूंकि यह आ गया है एक और सवाल में - यह सही है कि की तरह अधिक प्रतिबंधित प्रकार है Maybe, Singleऔर Completableकर सकते हैं हमेशा के स्थान पर किया Flowableजब वे अर्थ की दृष्टि से उपयुक्त हैं?
david.mihola

1
हाँ, Maybe, Single, और Completableकर रहे हैं अब तक भी backpressure अवधारणा के किसी भी आवश्यकता के लिए छोटा है। ऐसा कोई मौका नहीं है कि एक निर्माता जितनी तेजी से वस्तुओं का उपभोग कर सकता है उससे अधिक का उत्सर्जन कर सकता है, क्योंकि 0-1 आइटम कभी भी उत्पादित या उपभोग किए जाएंगे।
एंड्रयूएफ

शायद मैं सही नहीं हूं, लेकिन मेरे लिए फ्लोएबल और ऑब्जर्वेबल के उदाहरणों की अदला-बदली होनी चाहिए।
बजे यूरा गैलावे

मुझे लगता है कि प्रश्न में वह बैकपेचर रणनीति को याद कर रहा है जो हमें फ़्लोएबल को प्रदान करने की आवश्यकता है, जो बताता है कि लापता बैकपेचर अपवाद क्यों फेंका गया है, यह भी बताता है कि उसके द्वारा लागू होने के बाद यह अपवाद क्यों गायब हो जाता है ।onBackpressureDrop ()। और ऑब्जर्वेबल के लिए, चूंकि इसमें यह रणनीति नहीं है और इसे प्रदान नहीं किया जा सकता है, इसलिए यह OOM के कारण बाद में विफल हो जाएगा
Haomin

111

Backpressure तब होता है जब आपका पर्यवेक्षक (प्रकाशक) आपके सब्सक्राइबर को संभालने से अधिक ईवेंट बना रहा हो। तो आप ग्राहकों को गुम होने वाली घटनाओं को प्राप्त कर सकते हैं, या आप उन घटनाओं की एक बड़ी कतार प्राप्त कर सकते हैं जो अंततः स्मृति से बाहर हो जाते हैं। Flowableविचार में backpressure लेता है। Observableनहीं करता। बस।

यह मुझे एक फ़नल की याद दिलाता है, जब इसमें बहुत अधिक तरल ओवरफ्लो होता है। फ़्लोएबल ऐसा न करने के लिए मदद कर सकता है:

जबरदस्त बैकप्रेस के साथ:

यहाँ छवि विवरण दर्ज करें

लेकिन प्रवाह के उपयोग के साथ, बहुत कम बैकप्रेशर है:

यहाँ छवि विवरण दर्ज करें

Rxjava2 में आपके बैकस्पेस के आधार पर आपके द्वारा उपयोग की जाने वाली कुछ बैकस्पेस की रणनीतियाँ हैं। रणनीति से मेरा मतलब है कि Rxjava2 उन वस्तुओं को संभालने का एक तरीका है जो अतिप्रवाह (बैकप्रेस) के कारण संसाधित नहीं किया जा सकता है।

यहां की रणनीतियां हैं। मैं उन सभी के माध्यम से जाना नहीं है, लेकिन उदाहरण के लिए यदि आप उन वस्तुओं के बारे में चिंता नहीं करना चाहते हैं जो अतिप्रवाहित हैं तो आप इसके लिए एक ड्रॉप रणनीति का उपयोग कर सकते हैं:

observable.toFlowable (BackpressureStrategy.DROP)

जहां तक ​​मुझे पता है कि कतार पर 128 आइटम की सीमा होनी चाहिए, उसके बाद एक अतिप्रवाह (बैकस्पेस) हो सकता है। भले ही इसका 128 उस नंबर के करीब न हो। आशा है कि यह किसी की मदद करता है।

यदि आपको बफर आकार को 128 से बदलने की आवश्यकता है, तो ऐसा लगता है कि यह इस तरह किया जा सकता है (लेकिन किसी भी स्मृति बाधाओं को देखें:

myObservable.toFlowable(BackpressureStrategy.MISSING).buffer(256); //but using MISSING might be slower.  

सॉफ्टवेयर डेवलपमेंट में आमतौर पर बैक प्रेशर स्ट्रैटेजी का मतलब है कि आपका एमिटर को थोड़ा धीमा करना क्योंकि उपभोक्ता आपके उत्सर्जन की घटनाओं को वेग से नहीं संभाल सकता है।


मैं हमेशा सोचता था कि तंत्र के एक परिवार का नाम
बैकप्योर है

मामला हो सकता है। हां
j2emanue

क्या कोई फ़्लोबल का उपयोग करने के लिए कोई डाउनसाइड है?
इगोरगानापल्स्की

ये चित्र मेरे पास पड़े हैं। ड्रॉपिंग ईवेंट नीचे के "अधिक पैसे" के साथ समाप्त नहीं होंगे।
एपिकपांडाफर्स

1
@ j2emanue, आप ऑपरेटरों और Flowable.buffer (int) ऑपरेटर के लिए बफर आकार को भ्रमित कर रहे हैं। कृपया javadocs cafefully पढ़ सकते हैं और उसके अनुसार अपने जवाब को ठीक: reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html
टोमेक

15

तथ्य यह है कि आपके Flowableबैकपचर हैंडलिंग के बिना 128 मानों को छोड़ने के बाद दुर्घटनाग्रस्त हो गया, इसका मतलब यह नहीं है कि यह हमेशा बिल्कुल 128 मानों के बाद दुर्घटनाग्रस्त हो जाएगा: कभी-कभी यह 10 के बाद दुर्घटनाग्रस्त हो जाएगा, और कभी-कभी यह बिल्कुल भी दुर्घटनाग्रस्त नहीं होगा। मेरा मानना ​​है कि ऐसा तब हुआ जब आपने उदाहरण के साथ कोशिश की Observable- कोई बैकप्रेशर नहीं हुआ, इसलिए आपके कोड ने सामान्य रूप से काम किया, अगली बार ऐसा नहीं होगा। RxJava 2 में अंतर यह है कि अब बैकपेक्चर की कोई अवधारणा Observableनहीं है, और इसे संभालने का कोई तरीका नहीं है। आप एक प्रतिक्रियाशील अनुक्रम डिज़ाइन कर रहे हैं शायद स्पष्ट backpressure से निपटने की आवश्यकता होगी कि - तो Flowableतुम्हारा सबसे अच्छा विकल्प है।


हां मैंने देखा है कि कभी-कभी यह कम मूल्यों के बाद टूट जाता है, कभी-कभी ऐसा नहीं होता है। लेकिन फिर से अगर उदाहरण के लिए मैं केवल intervalबिना ही संभाल रहा हूं तो backpressureक्या मुझे कुछ अजीब व्यवहार या मुद्दों की उम्मीद होगी?
user2141889

यदि आपको लगता है कि कोई विशिष्ट अवलोकन अनुक्रम में कोई समस्या नहीं हो सकती है, तो मुझे लगता है कि यह ठीक है कि बैकस्पेस को अनदेखा किया जाए।
ईगोर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.