struct IB
    client::IBKRCore.IBClient
    host::String
    port::CxxInt
    client_id::CxxInt
    function IB(host, port, client_id)
        new(IBKRCore.IBClient(), host, port, client_id) 
    end
end

function IB(; host=IB_DEFAULT_HOST, port=IB_DEFAULT_PORT, client_id=IB_DEFAULT_CLIENT_ID)
    IB(host, port, client_id)
end

function (ib::IB)(f::Function)
    IBKRCore.connect(ib.client, ib.host, ib.port, ib.client_id) 
    ev = Threads.Event()
    t = Threads.@spawn process_messages_loop($(ib.client), $ev)
    wait(ev)
    try
        f()
    finally
        IBKRCore.isConnected(ib.client) && IBKRCore.disconnect(ib.client)
        # IBKRCore.issueSignal(c)
        wait(t)
    end
    return nothing
end

function process_messages_loop(client::IBKRCore.IBClient, ev::Event)
    try
        while !IBKRCore.isConnected(client) sleep(0.001) end
        notify(ev)
        while IBKRCore.isConnected(client) 
            IBKRCore.processMessages(client)
        end
    finally
        IBKRCore.isConnected(client) && IBKRCore.disconnect(client)
    end
    @debug "DONE process_messages_loop"
end



# function start_request(ib::IB)
#     ev = Threads.Event()
#     push!
#
# function managed_accounts(ib::IB)
#     IBKRCore.reqManagedAccounts(c)

