Asynchronous call using service callout and a passthrough proxy

I am trying to create a service callout policy to log some messages to an external http listener. I understand that by having my policy call a local passthrough proxy, I can reduce the time taken by the service callout and make it work asynchronously. I have also removed the response tags to achieve this. Below are the snippets of my policies:

Service callout in main proxy:

 

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout continueOnError="false" enabled="true" name="SC-main">
  <DisplayName>SC-main</DisplayName>
  <Request clearPayload="true" variable="myRequest">
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <Set>
      <Verb>POST</Verb>
      <Payload contentType="text/html">
{request.content}
      </Payload>
    </Set>
  </Request>
  <LocalTargetConnection>
    <APIProxy>asynclogger</APIProxy>
    <ProxyEndpoint>default</ProxyEndpoint>
  </LocalTargetConnection>
</ServiceCallout>

 

 

Service callout in passthrough proxy"

 

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout continueOnError="true" enabled="true" name="SC-asynclog">
  <DisplayName>SC-asynclog</DisplayName>
  <Request clearPayload="true" variable="myRequest">
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <Set>
      <Verb>POST</Verb>
      <Payload contentType="text/html">
{message.content}
      </Payload>
    </Set>
  </Request>
  <HTTPTargetConnection>
    <Properties>
      <Property name="io.timeout.millis">3000</Property>
      <Property name="connect.timeout.millis">3000</Property>
    </Properties>
    <URL>http://<ipaddress></URL>
  </HTTPTargetConnection>
</ServiceCallout>

 

 

This setup works as expected, as in when I call the main proxy, I can see the expected response and messages get logged to the http listener. 

But I could not see any difference in terms of the time it takes for this to execute, compared to making a service callout directly from the main proxy.

Also, I need to handle a specific case where if for any reason the http listener is not reachable, the pipeline should not be broken. I assumed that making a 'fire and forget' call to a passthrough proxy will achieve this. Is there a quicker way to fulfill this requirement? As of now I have set 'continueOnError=true' in the passthrough service callout, but it still takes 7-8 seconds.

Thanks in advance.

0 1 109
1 REPLY 1

I think 

  • in your passthrough proxy you should not use ServiceCallout.  You should specify your logging endpoint as the target. There should be no servicecallout in the passthrough. 
  • In the calling proxy, use ServiceCallout and specify no Response.
  • Ideally for logging you should insert that into the PostClientFlow of the original proxy, so the cost for logging is not borne by the calling client. It does not matter if logging consumes 3ms or 7ms, the client will be unaffected, if the logging is done from within PostClientFlow. Unfortunately at this moment there is no PostClientFlow flowhook, so you need to add that ServiceCallout to each proxy "manually".
  • Be careful taking performance measurements on a one-off basis. What matters is performance at the request volume you will see in production. With HTTP1.1 keep-alives, you should be able to see a perf benefit , with many requests flowing through the same proxies.  You will not see this benefit if you test one or two calls at a time and examine the trace output.