मैं Play 2.0 ढांचे की प्रतिक्रियाशील I/O अवधारणाओं को समझने की कोशिश कर रहा हूं। शुरुआत से बेहतर समझ प्राप्त करने के लिए मैंने फ्रेमवर्क के हेल्पर्स को अलग-अलग प्रकार के इटरेटेट बनाने और एकको स्क्रैच से लिखने के लिए अनुरोध किया है ताकि अनुरोध निकाय को पार्स करने के लिए BodyParser
द्वारा उपयोग किया जा सके।बॉडीपार्सर Iteratee में कॉलिंग त्रुटि या निष्पादन क्यों करता है अनुरोध फ्रेम फ्रेम 2.0 में लटका है?
import play.api.mvc._
import play.api.mvc.Results._
import play.api.libs.iteratee.{Iteratee, Input}
import play.api.libs.concurrent.Promise
import play.api.libs.iteratee.Input.{El, EOF, Empty}
01 object Upload extends Controller {
02 def send = Action(BodyParser(rh => new SomeIteratee)) { request =>
03 Ok("Done")
04 }
05 }
06
07 case class SomeIteratee(state: Symbol = 'Cont, input: Input[Array[Byte]] = Empty, received: Int = 0) extends Iteratee[Array[Byte], Either[Result, Int]] {
08 println(state + " " + input + " " + received)
09
10 def fold[B](
11 done: (Either[Result, Int], Input[Array[Byte]]) => Promise[B],
12 cont: (Input[Array[Byte]] => Iteratee[Array[Byte], Either[Result, Int]]) => Promise[B],
13 error: (String, Input[Array[Byte]]) => Promise[B]
14 ): Promise[B] = state match {
15 case 'Done => { println("Done"); done(Right(received), Input.Empty) }
16 case 'Cont => cont(in => in match {
17 case in: El[Array[Byte]] => copy(input = in, received = received + in.e.length)
18 case Empty => copy(input = in)
19 case EOF => copy(state = 'Done, input = in)
20 case _ => copy(state = 'Error, input = in)
21 })
22 case _ => { println("Error"); error("Some error.", input) }
23 }
24 }
(टिप्पणी: सभी इन बातों ने मुझे के लिए नए हैं
जानकारी Iteratees और ScalaBodyParser डॉक्स और खेलने प्रतिक्रियाशील मैं के बारे में दो प्रस्तुतियों में उपलब्ध के साथ शुरू/ओ यह है कि क्या मैं के साथ आया है , तो कृपया क्षमा करें अगर इसके बारे में कुछ कुल बकवास है।) Iteratee बहुत गूंगा है, यह सिर्फ सभी हिस्सों को पढ़ता है, प्राप्त बाइट्स की संख्या बताता है और कुछ संदेशों को प्रिंट करता है। जब मैं कुछ डेटा के साथ नियंत्रक कार्रवाई को कॉल करता हूं तो सब कुछ अपेक्षित काम करता है - मैं देख सकता हूं कि सभी हिस्सों को इटरेटे द्वारा प्राप्त किया जाता है और जब सभी डेटा पढ़ा जाता है तो यह राज्य में स्विच हो जाता है और अनुरोध समाप्त होता है।
- राज्य त्रुटि में स्विच करने से पहले सभी इनपुट पढ़ा जाता है:
अब मैं क्योंकि मैं इन दो मामलों के लिए व्यवहार देखना चाहता था कोड के साथ चारों ओर खेलने के लिए शुरू कर दिया।
- सभी इनपुट से पहले किए गए राज्य में स्विचिंग
Int
के बजायResult
को पढ़ और वापस कर रहा है।
ऊपर वर्णित दस्तावेज की मेरी समझ यह है कि दोनों संभव होना चाहिए लेकिन असल में मैं मनाए गए व्यवहार को समझने में सक्षम नहीं हूं। पहले मामले में मैं करने के लिए ऊपर दिए गए कोड की लाइन 17 बदल परीक्षण करने के लिए:
17 case in: El[Array[Byte]] => copy(state = if(received + in.e.length > 10000) 'Error else 'Cont, input = in, received = received + in.e.length)
तो मैं सिर्फ एक शर्त है, तो 10000 से अधिक बाइट्स प्राप्त हुए थे त्रुटि राज्य में स्विच करने के लिए जोड़ा। मुझे प्राप्त होने वाला आउटपुट यह है:
'Cont Empty 0
'Cont El([[email protected]) 8192
'Error El([[email protected]) 16384
Error
Error
Error
Error
Error
Error
Error
Error
Error
Error
Error
फिर अनुरोध हमेशा के लिए लटकता है और कभी समाप्त नहीं होता है। उपरोक्त उल्लिखित दस्तावेज़ों से मेरी अपेक्षा यह थी कि जब मैं फ़ंक्शन को fold
के अंदर एक Iteratee के अंदर दबाता हूं तो प्रसंस्करण को रोका जाना चाहिए। यहां क्या हो रहा है कि इटरेटे की फोल्ड विधि को error
के बाद कई बार बुलाया जाता है - ठीक है और फिर अनुरोध लटकता है।
जब मैं सभी इनपुट पढ़ने से पहले किए गए राज्य में स्विच करता हूं तो व्यवहार काफी समान होता है।
15 case 'Done => { println("Done with " + input); done(if (input == EOF) Right(received) else Left(BadRequest), Input.Empty) }
और लाइन से 17: करने के लिए लाइन 15 बदलने
17 case in: El[Array[Byte]] => copy(state = if(received + in.e.length > 10000) 'Done else 'Cont, input = in, received = received + in.e.length)
निम्नलिखित उत्पादन का उत्पादन:
'Cont Empty 0
'Cont El([[email protected]) 8192
'Done El([[email protected]) 16384
Done with El([[email protected])
Done with El([[email protected])
Done with El([[email protected])
Done with El([[email protected])
और फिर से अनुरोध हमेशा के लिए लटका हुआ है।
मेरा मुख्य प्रश्न यह है कि उपर्युक्त मामलों में अनुरोध क्यों लटक रहा है। अगर कोई इस पर प्रकाश डाल सकता है तो मैं इसकी सराहना करता हूं!
फिक्स और दयालु शब्दों के लिए धन्यवाद, यह ठीक करने की कोशिश करेगा! – lost