DxlException: Synchronous requests may not be invoked while handling an incoming message.

  • Hi-


    I have a Python OpenDXL application that listens for TIE reputation change events. Once a reputation change event is received, I want to make a call to VirusTotal to get information about the file whose reputation has changed. My application currently uses the TIE Client Library as well as the VirusTotal Client Library (and its associated service).


    However, I receive the following error message when a reputation change event is received and I attempt to invoke the VirusTotal service:


    DxlException: Synchronous requests may not be invoked while handling an incoming message. The synchronous request must be made on a different thread.


    Here's the code for my callback:


    Any ideas why this might be happening?


    Greatly appreciate any help,

    Mark

  • The error is occurring due to the fact that a synchronous request is being made during the handling of an event message. The reason this is not allowed is that a synchronous request will result in a response message being sent back to the invoking client.


    The pool of handlers for incoming messages in the Python OpenDXL client is common for all message types. Therefore, deadlock could occur if all of the threads were busy handling incoming events and synchronous requests were made on them. There would be no available threads to handle the response messages (they would all be consumed by the event handling threads).


    The simple answer is to make the VirusTotal service invocation on a thread other than the event handler thread. However, this is such a common use case that it is something that is handled by the OpenDXL Bootstrap application.


    I put together a quick application using bootstrap that handles your particular use case.


    Here is the application template that I used:



    The important property to note is separateThread. This property causes the event handler to be invoked on a thread other than the incoming message thread. See the following Wiki page for additional information.


    After I generated the application using OpenDXL bootstrap I had to modify the default event handler code to incorporate your logic.


    Here is the updated eventhandlers.py file (the original file was generated by bootstrap):



    The modifications I made to the handler are as follows:

    • Changed the base class from EventCallback to ReputationChangeCallback to match your handler
    • Replaced the generated on_event method with your on_reputation_change method implementation
    • Instead of passing the client to the constructor like you were doing, I used the client that is available via the generated application (self._app.client).

    I tested the generated application and I am able to successfully perform VirusTotal lookups when reputation change events are received.


    Hope this helps,

    Chris