Thursday, January 22, 2015

Saying goodbye to internal HTTP connections

Orbeon Forms often needs to perform calls to itself, for example to:

  • call persistence layer implementations,
  • load internationalized resources,
  • navigate between pages,
  • proxy requests for dynamic XForms resources,
  • and request CSS, JavaScript and image assets when producing PDFs.

In previous versions, Orbeon Forms performed actual HTTP connections on itself. This caused problems:

  • Configuration: Orbeon Forms needed a host and port to connect. In some cases, this could be guessed, but in others, for example when a front-end was placed in front of Orbeon Forms, you had to override a configuration property. There were also reported cases of interference with some servlet filters installed by our users.
  • Authentication and authorization: Internal services typically need the same credentials as the incoming request. To do this we were forwarding cookies and other headers, which could fail in some corner cases and was sometimes difficult to configure.
  • Thread usage: This required more servlet container threads than needed. In some cases, a external request to Orbeon could cause 3 threads to be used, 2 of them just waiting on HTTP connections.
  • Deadlocks: When the pool of threads provided by Tomcat was exhausted, deadlocks could occur, especially since we recommended a small pool in order to avoid overloading the forms processor. [1]
  • Performance: Page and service calls were slower than needed, as HTTP connections needed to be established, and communicating over HTTP has a certain cost.

In short, change was needed! So with Orbeon Forms 4.7, we got on this and entirely removed of the use of HTTP for internal calls!

How did we do this?

We were already using an abstraction to perform requests within Orbeon Forms. This abstraction unifies how we access internal resources stored in the Orbeon application itself, as well as calls such as HTTP calls.

So we built on this [2] to provide an additional HTTP abstraction. We now have an ApacheHttpClient, which uses HTTP proper, and a new InternalHttpClient, which behaves like the real HTTP client from the perspective of the caller but in fact does its work entirely internally, without any network access.

From the perspective of the page or service called, it is as if the request was coming from an external HTTP client (with some minor twists).

This in one shot addresses all the issues listed above. So we are quite happy with this change!

  1. Orbeon Forms 4.8 introduces a new limiter filter to deal with this in a much better way.  ↩

  2. Including some fairly massive refactoring along the way!  ↩

No comments:

Post a Comment