简体   繁体   中英

Accumulate results of each intermediate recursive call using F# and Bloomberg API

I'm using the B-Pipe API to request financial securities data from Bloomberg. Large requests are divided into small groups and returned as PARTIAL_RESPONSE with the final response being RESPONSE . The recursive handleSingleEvent function recurses until a final RESPONSE is returned by reqEventQueue.NextEvent() .

My problem is that only the final RESPONSE group of securities are returned. The intermediate PARTIAL_RESPONSE groups are not returned by the function. However, these PARTIAL_RESPONSE groups are received from Bloomberg.

I'm thinking I might need some accumulator parameters or should use something similar to List.collect, but I don't have a clue how to get started.

// list<Request> * EventQueue * Session -> list<list<string>>
let handleEvents (requests: Request list, reqEventQueue: EventQueue, session: Session) =
      let rec handleSingleEvent (request: Request) =
        try
          let eventObj = reqEventQueue.NextEvent()

          match eventObj.Type with          
          | Event.EventType.PARTIAL_RESPONSE ->
            processReferenceResponseEvent eventObj
            |> makeJson
            |> ignore

            handleSingleEvent request
          | Event.EventType.RESPONSE -> processReferenceResponseEvent eventObj |> makeJson
          | _ -> processMiscEvents eventObj |> makeJson
        with
        | ex -> failwithf "%s" ex.Message

      List.map (fun request -> handleSingleEvent request) requests

Update I made edits, but now code seems to enter infinite recursion.

let handleEvents (requests: Request list, reqEventQueue: EventQueue, session: Session)  =
      let rec handleSingleEvent (request: Request) : seq<list<string>> =
        seq {
          
              let eventObj = reqEventQueue.NextEvent()

              match eventObj.Type with
              | Event.EventType.REQUEST_STATUS -> yield processMiscEvents eventObj |> makeJson
              | Event.EventType.ADMIN -> yield processAdminEvent eventObj |> makeJson
              | Event.EventType.AUTHORIZATION_STATUS -> yield processAuthEvent eventObj session |> makeJson
              | Event.EventType.PARTIAL_RESPONSE ->
                yield processReferenceResponseEvent eventObj
                |> makeJson
                yield! handleSingleEvent request
              | Event.EventType.RESPONSE -> yield processReferenceResponseEvent eventObj |> makeJson
              | _ -> yield processMiscEvents eventObj |> makeJson
        } |> ignore
        handleSingleEvent request
      List.map (fun request -> handleSingleEvent request) requests

I'm not familiar with the Bloomberg API, but this is a fairly common pattern. I think the easiest way to handle it is to generate a sequence of JSON strings recursively, using yield to process the current event and yield! to process the remainder of the queue recursively. That way you don't have to worry about accumulating the results manually. So something like this:

let rec loop () : seq<string> =   // assumption: makeJson has type _ -> string
    seq {
        let eventObj = reqEventQueue.NextEvent()
        match eventObj.Type with          
            | Event.EventType.PARTIAL_RESPONSE ->
                yield processReferenceResponseEvent eventObj
                    |> makeJson
                yield! loop ()
            | Event.EventType.RESPONSE ->
                yield processReferenceResponseEvent eventObj
                    |> makeJson
            | _ ->
                yield processMiscEvents eventObj
                    |> makeJson
    }
loop ()

There are some other issues in your code that I haven't attempted to address, such as the fact that the request and session values aren't used at all. I assume you can fix that easily enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM