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
CodePudding user response:
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.