การสร้างลำดับแบบเรียกซ้ำ

ฉันกำลังพยายามสร้างลำดับของส่วนต่างๆ โดยการอ่านข้อมูลจากแหล่งข้อมูลของฉันแบบวนซ้ำ

let rec read stream startFrom (conn : IEventStoreConnection) = 
    seq {
        let size = 10000
        let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

        Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

        if (slice.IsEndOfStream) then
           yield slice
        else
           yield! read stream (startFrom + 1 * size) conn 
    }

let slices = read "stream-name" 0 conn

Console.WriteLine("TOTAL slices in sequence: " + (Seq.length slices).ToString());

ฉันคาดหวังว่าลำดับนี้จะมีสามรายการ แต่ดูเหมือนว่าจะส่งคืนเพียงรายการเดียวซึ่งเป็นรายการสุดท้าย

Events in slice: 10000
Events in slice: 10000
Events in slice: 4501
TOTAL slices in sequence: 1

เหตุใดผลลัพธ์ของการโทรซ้ำของฉันจึงไม่ได้รับผลเช่นกัน สิ่งที่กำหนดขอบเขต?


person JefClaes    schedule 05.10.2014    source แหล่งที่มา
comment
ดังนั้นลองคิดดูว่าจะเกิดอะไรขึ้น ถ้าคุณไม่ได้อยู่ท้ายกระแส คุณก็จะขอกลับจนกว่าคุณจะอยู่ท้ายกระแส เฉพาะจุดสิ้นสุดของสตรีมเท่านั้นที่ส่งคืนบางสิ่งจริงๆ   -  person John Palmer    schedule 05.10.2014


คำตอบ (2)


ดังที่ John บอกคุณแล้ว คุณต้องแบ่งส่วนอื่นๆ ด้วย:

let rec read stream startFrom (conn : IEventStoreConnection) = 
    seq {
        let size = 10000
        let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

        Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

        if (slice.IsEndOfStream) 
        then
           yield slice
        else
           yield slice // here
           yield! read stream (startFrom + 1 * size) conn 
    }

ฉันคิดว่าคุณสามารถทำความสะอาดสิ่งนี้ได้เล็กน้อยโดยใช้ฟังก์ชั่นภายใน:

let read (conn : IEventStoreConnection) stream startFrom = 
    let size = 10000
    let rec loop startFrom =
       seq {
           let slice = conn.ReadStreamEventsForwardAsync(stream, startFrom, size, true).Result

           Console.WriteLine("Events in slice: " + slice.Events.Count().ToString())

           if (slice.IsEndOfStream) 
           then
              yield slice
           else
              yield slice // here
              yield! loop (startFrom + 1 * size)
       }
    loop startFrom
person Random Dev    schedule 05.10.2014

สำหรับการดำเนินการอื่นในเรื่องนี้ (ซึ่งไม่ได้พยายามห่อหุ้มการโหลดแบบแบ่งส่วนในลักษณะนี้ โดยเลือกที่จะจัดการแง่มุมนั้นแยกกันเพื่อให้ 'การเล่น' ของเหตุการณ์ขนานกัน เป็นทีต้ากับ NES หรือ GES) ดูที่ ลูปการโหลด/ดีซีเรียลไลเซชันใน FunDomain

โปรดทราบว่าโค้ดทั้งหมดใน FunDomain จริงๆ แล้วเป็นเพียง FsUno.Prod ที่ปรับโครงสร้างใหม่จำนวนมาก

person Ruben Bartelink    schedule 22.10.2014