Thunderbird is playing very strange games with me this morning, somehow
deleting the original post. Anyway, here are my comments on this.
I'd like to propose changes to enable some basic stat collection
and/or instrumentation to have visibility into performance of AHC.
For a given *AsyncHttpClient*, one might want to know metrics like
- total request count
- total success count
- total exception count
- total timeout count
- connection attempt count
- connection failure count
- connect time average
- connection close count
- average response time (as measured from the invocation time to
having the response ready)
- and others?
Collection of metric information would, I think, be a good thing.
However, I think we should separate the consolidation of the information
from the collection. That is, the client should just have different
types of events for data collection, and the event listener would be
responsible for presenting the information appropriately.
For example, to create the list above, I'd see the following set of
events needed:
- request made
- request completed
- request failed
- request timeout
- connection attempt started
- connection failed
- connection closed
All events would be timestamped, which would allow metrics like "average
request time" to be calculated. This set of events would mean the
client would not need to maintain any metric accumulators, and if the
event information is done correctly, would even allow more fine grained
monitoring (e.g., average connection time for requests to domain
"foo.bar.com").
Collecting these metrics should have little effect on the overall
performance. There would be an API to access these stats.
I was initially thinking of an IoFilter to consolidate these hooks,
but I realize some of these metrics are not readily available to an
IoFilter (e.g. connect-related numbers). It might be unavoidable to
spread the instrumentation in a couple of places (IoHandler,
ConnectFutureListener, etc.).
Taking this one step further, one might think of callbacks or
listeners for various key events such as connect complete, request
sent, etc., so callers can provide instrumenting/logging code via
event notification. However, I think this should be used judiciously
as such injected code may cause havoc.
I think listeners would be the way to go. This would allow multiple
monitoring types to be attached to the pipe to gather data as needed.
Perhaps the approached used with the javamail API might be of use here.
The javamail Store APIs have a number of listener events that are
broadcast (new mail arrived, message delete, folder created, etc.).
Because there are similar concerns of havoc, the events get posted to a
queue, and are dispatched on to a separate thread. The queue is only
created (and the associated thread) are only created when there are
listeners available to handle the events. This allows the events to
very low overhead when there are no interested parties and prevents the
listeners from interfering with normal javamail operations by being
processed on a different thread.
Thoughts? Suggestions?