hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hemant <gethem...@gmail.com>
Subject Re: Exceptions getting silently eaten away
Date Thu, 06 Nov 2008 18:28:59 GMT
On Thu, Nov 6, 2008 at 7:19 PM, Oleg Kalnichevski <olegk@apache.org> wrote:
>
> One needs to differentiate two types of exceptions:
>
> (1) I/O and HTTP protocol exceptions that occur in the context of one
> particular connection, which usually result in termination of that
> connection but do not affect other connections and the I/O reactor
> itself
>
> (2) Runtime and I/O connections that are fatal and usually result in
> termination of the I/O reactor along with all active connections.
>
> What kind of exception are you referring to?

Okay, following method is from class CustomRequestHandler, which
subclasses NHttpRequestExecutionHandler :

  def responseEntity(response: HttpResponse,context: HttpContext):
ConsumingNHttpEntity = {
    val requestAttachment =
context.getAttribute("request_attachment").asInstanceOf[RequestAttachment[GenericAmtdRequest]]
    val entity = response.getEntity()
    Log.log("Status is : " + response.getStatusLine())
    val length = entity.getContentLength()
    Log.log("Length of entity is : " + length)
    new CustomEntity(requestAttachment)
  }

And this is my CustomEntity class:

class CustomEntity(request: RequestAttachment[GenericAmtdRequest])
extends ConsumingNHttpEntity {
  val parser = new NewsParser(request.request.sessionId)

  def consumeContent(decoder: ContentDecoder,ioctrl: IOControl): Unit = {
    Log.log("Calling Consuming content")
    var allRead = false

    while(!allRead) {
      val t = ByteBuffer.allocate(8*1024)
      val count = decoder.read(t)
      if(count <= 0) allRead = true
      else {
        Log.log("****** Number of Bytes read is : " + count)
        parser.add(t)
      }
    }
  }

  def finish() = {
    Log.log("Finished reading data")
  }

  def consumeContent() = { }

  def getContent() = null
  def getContentEncoding() = null
  def getContentLength() = -1
  def getContentType() = null
  def isChunked() = false
  def isStreaming() = false
  def isRepeatable() = false
  def writeTo(in: OutputStream) = { }
}


NewsParser is a state machine parser, which parses incoming bytes and
creates News objects (which is not relevant to our discussion I
think).

So, I am talking about Exception thats thrown inside NewsParser class
because I had few runtime problems with my code that does parsing in
#add method(nothing todo with any IOException and all). Unhandled
exceptions inside that class is being ignored and thats my problem (I
am yet to test if those exceptions are being captured by EventListener
properly, because since then, I have fixed those unhandled exceptions,
and I am not getting them anymore).

>
> At any rate, HttpCore should _never_ ever silently discard exceptions
> (barring a few special cases such as a force-shutdown of a Socket)

Good to know. :)

>
> Happily! I'd be delighted

Will do that.

Okay, I am not sure, If I want to start a new thread about this, but
calling #cancel() on a SessionRequest Object doesn't seem to be
working (or may be I do not understand this). My typical code looks
like this:


# open new httpconnection for servicing this client.
#Store the session info in a HashMap

def openNewConnection[T <: GenericAmtdRequest](authInfo:
AuthInfo,request: T): ActivityContainer[T] = {
    val hostInfo = new HttpHost(authInfo.streamerInfo.url,443)
    Log.log("Opening new connection for async http on url : " +
authInfo.streamerInfo.url)
    val httpSession = ioReactor.connect(
      new InetSocketAddress(authInfo.streamerInfo.url,443),
      null,
      new RequestAttachment(authInfo,request,hostInfo),
      new CustomRequestCallback()
    )
    Log.log("Http Connection opened successfully")
    new ActivityContainer[T](new Date(),httpSession,request)
  }

When Client disconnects call #cancel() on the SessionRequest object like this:

  def handleRemoveClient(request: RemoveClient) =
openConnections.get(request.sessionId) match {
    case Some(x: ActivityContainer[GenericAmtdRequest]) => {
      Log.info("Sending Client removal request to AmtdChannel for
sessionId in AmtdChannel: " + request.sessionId)
      x.httpSession.cancel()
      openConnections.removeKey(request.sessionId)
      Log.info("############################## Connection successfully
removed ##############################")
    }
    case _ => Log.info("Removing session failed")
  }


So, I can see #cancel() getting called properly, but httpcore is still
reading data from that connection (long after #cancel() is called). I
can say data is still coming from that connection because
#consumeContent() is still getting called in the class that implements
ConsumingNHttpEntity.

I am trying to debug this on my own (by compiling httpcore libs and
adding few debug messages), but any pointers will be awesome.

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Mime
View raw message