Генерация рекурсивной последовательности

Я пытаюсь создать последовательность срезов, рекурсивно считывая данные из моего источника данных.

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)


Как уже сказал вам Джон, вы должны получить и другие слайсы:

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