NIO - OP_READ fired on client disconnect

Discussion in 'Java' started by farseer, Apr 13, 2005.

  1. farseer

    farseer Guest

    I have a server that listens for connections. A selector is opened,
    configured for non-blocking and the serverchannel is used to register
    OP_ACCEPT on this selector. in the main loop, once i accept a
    connection, i immediately register OP_READ on the selector.
    So far so good...A connection request is made by a client, i accept, i
    register to read; when the client sends data, i read the data and send
    back an ACK. All good!

    Now, i created a client which simply connects to the server, sends a
    message and recieves back an acknowledgement from the server. about
    100 to 500 client threads are created for testing. They all work
    flawlessly, almost. the server accepts each connection, process the
    data each thread sends and then when it's done with all connections,
    blocks on select() it appears.

    THE PROBLEM IS: when i now kill the client process (the one with 100
    to 500 threads), the server immediately wakes up and tries to process a
    READ_OP event. I currently handle this by closing/canceling the key
    and channel if an IOException is detected in the method that reads, but
    i am wondering why does the Server wake up when clients abruptly
    disconnects?
    I also noticed the converse happens..if the server is killed, the
    client tries to process a OP_READ event.

    Anyone with some thoughts?
     
    farseer, Apr 13, 2005
    #1
    1. Advertising

  2. farseer

    Esmond Pitt Guest

    farseer wrote:
    > I have a server that listens for connections. A selector is opened,
    > configured for non-blocking and the serverchannel is used to register
    > OP_ACCEPT on this selector. in the main loop, once i accept a
    > connection, i immediately register OP_READ on the selector.
    > So far so good...A connection request is made by a client, i accept, i
    > register to read; when the client sends data, i read the data and send
    > back an ACK. All good!
    >
    > Now, i created a client which simply connects to the server, sends a
    > message and recieves back an acknowledgement from the server. about
    > 100 to 500 client threads are created for testing. They all work
    > flawlessly, almost. the server accepts each connection, process the
    > data each thread sends and then when it's done with all connections,
    > blocks on select() it appears.
    >
    > THE PROBLEM IS: when i now kill the client process (the one with 100
    > to 500 threads), the server immediately wakes up and tries to process a
    > READ_OP event. I currently handle this by closing/canceling the key
    > and channel if an IOException is detected in the method that reads, but
    > i am wondering why does the Server wake up when clients abruptly
    > disconnects?
    > I also noticed the converse happens..if the server is killed, the
    > client tries to process a OP_READ event.
    >
    > Anyone with some thoughts?


    OP_READ is fired if either data or an EOF is available or the connection
    has been reset.
     
    Esmond Pitt, Apr 14, 2005
    #2
    1. Advertising

  3. farseer

    farseer Guest

    ok, thanks and that would explain it.

    Question, when a READ is fired and i retrieve the key, is there away to
    prevent that from firing again, but still keep the channel open for
    sending?
    The problem i am having now is that when i read, i add an object to a
    synchronized "queue". I have a number of threads then blocking on that
    queue when it's empty...so that when something is added, one of the
    threads picks it up and processes it.

    However, i find that the same key is added a number of times to that
    queue because the read is constantly fired until i do a read from that
    channel's socket. so basically, if a thread is a bit slow to pick an
    object from the queue that was just added, that object may be added
    more than once.
    I can fix this by ensureing the items in the queue is unique, but that
    seems like a lame fix, since it still means processing time.
     
    farseer, Apr 20, 2005
    #3
  4. farseer

    Esmond Pitt Guest

    farseer wrote:
    >
    > Question, when a READ is fired and i retrieve the key, is there away to
    > prevent that from firing again, but still keep the channel open for
    > sending?
    > The problem i am having now is that when i read, i add an object to a
    > synchronized "queue". I have a number of threads then blocking on that
    > queue when it's empty...so that when something is added, one of the
    > threads picks it up and processes it.
    >
    > However, i find that the same key is added a number of times to that
    > queue because the read is constantly fired until i do a read from that
    > channel's socket. so basically, if a thread is a bit slow to pick an
    > object from the queue that was just added, that object may be added
    > more than once.


    Eh??? This can only happen if you can somehow manage to read the object
    from the socket more than once, which you can't, or unless you have a
    bug in your code, which is at least possible.
     
    Esmond Pitt, Apr 21, 2005
    #4
  5. farseer

    farseer Guest

    the confusion is from me. when i say "read", i should have said when i
    PROCESS THE READ EVENT. at that point i am not actually reading form
    the buffer, but adding the the object to a queue for processing. the
    threads actually do the reading...but, at times, before the actually
    complete reading, the event could fire again.
     
    farseer, Apr 21, 2005
    #5
  6. farseer

    Esmond Pitt Guest

    farseer wrote:
    > the confusion is from me. when i say "read", i should have said when i
    > PROCESS THE READ EVENT. at that point i am not actually reading form
    > the buffer, but adding the the object to a queue for processing. the
    > threads actually do the reading...but, at times, before the actually
    > complete reading, the event could fire again.


    then surely you just have to defer adding the object to a queue until
    the read completes? ...

    also why the baroque architecture? the read won't block, why not do it
    in the same thread?
     
    Esmond Pitt, Apr 22, 2005
    #6
  7. farseer

    farseer Guest

    i think i solved it...by removing the OP_READ event after i recieve
    that event, and adding it back after i finish reading prevents the
    events for that channel from being fired.

    to answer your questions:
    -first question - well, it's kind of the chicken and egg problem. The
    threads block on an empty queue. when there is something in the queue,
    the awake and process it. so i have to add something to the queue each
    time an event is fired.
    -yes, you're right, i should read in the same thread since it doesnt'
    block....but i still would need to to "turn off" OP_READ when
    processing buffer, since that is done in a different thread and i don't
    want that buffer being updated while i am reading.
     
    farseer, Apr 22, 2005
    #7
  8. farseer

    Esmond Pitt Guest

    farseer wrote:
    > i think i solved it...by removing the OP_READ event after i recieve
    > that event, and adding it back after i finish reading prevents the
    > events for that channel from being fired.
    >
    > to answer your questions:
    > -first question - well, it's kind of the chicken and egg problem. The
    > threads block on an empty queue. when there is something in the queue,
    > the awake and process it. so i have to add something to the queue each
    > time an event is fired.
    > -yes, you're right, i should read in the same thread since it doesnt'
    > block....but i still would need to to "turn off" OP_READ when
    > processing buffer, since that is done in a different thread and i don't
    > want that buffer being updated while i am reading.


    I have been thinking about this and you have hit on the correct
    solution. You were treating OP_READ as a discrete event corresponding
    precisely to a client request, and it just isn't.
     
    Esmond Pitt, Apr 23, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. iksrazal

    NIO with timeouts != NIO?

    iksrazal, Jun 17, 2004, in forum: Java
    Replies:
    1
    Views:
    6,327
    iksrazal
    Jun 18, 2004
  2. =?Utf-8?B?QXJuZSBHYXJ2YW5kZXI=?=

    Client Disconnect

    =?Utf-8?B?QXJuZSBHYXJ2YW5kZXI=?=, Nov 3, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    389
    =?Utf-8?B?QXJuZSBHYXJ2YW5kZXI=?=
    Nov 3, 2006
  3. sss

    EJB Client disconnect

    sss, Nov 18, 2006, in forum: Java
    Replies:
    1
    Views:
    462
  4. sk
    Replies:
    0
    Views:
    343
  5. Bryan
    Replies:
    6
    Views:
    898
    Bryan
    Dec 20, 2006
Loading...

Share This Page