diff --git a/src/eimap.erl b/src/eimap.erl --- a/src/eimap.erl +++ b/src/eimap.erl @@ -211,6 +211,21 @@ wait_response({ data, Data }, #state{ current_command = #command{ response_type = ResponseType, parse_state = CommandState , tag = Tag } } = State) -> Response = eimap_command:parse_response(ResponseType, Data, Tag, CommandState), %%lager:info("Response from parser was ~p ~p, size of queue ~p", [More, Response, queue:len(State#state.command_queue)]), + % FIXME + % Because several commands can be in flight at the same time, it can happen that we have something like: + % * Client send: CMD1, CMD2 (triggering a request for metadata) + % * Because we immediately after processing CMD2 from the client request metadata and start waiting for the response, + % a response that actually still belongs to CMD1 will not be recognized as such (will end up in here). + % + % Below is a workaround for that case; If we fail to parse the repsonse we simply assume it's none of our business and pass it trough. + % + % For a proper fix more work would be required, here are some ideas: + % * Track pending tags and only start associating with this command once we have all outstanding tags completed. The problem is that we don't know about pending tags because normally we don't look for them while passing through. + % * Buffer data and watch out for any tag. If its not ours pass the data through (would result in performance penalty only while waiting for the command). + case Response of + {more,{<<>>,[],_}} -> passthrough({data, Data}, State); + _ -> {} + end, NewState = cancel_timeout(State), next_command_after_response(Response, NewState); wait_response(process_command_queue, State) ->