Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: JRuby 1.1RC2
    • Fix Version/s: None
    • Labels:
      None
    • Environment:
      Windows XP
    • Testcase included:
      yes
    • Number of attachments :
      2

      Description

      The Stomp gem uses TCPSocket#gets inside a thread for synchronous reads, and writes to the socket using TCPSocket#puts. With the current NIO refactoring, this causes the sending thread to block. The attached test (test_duplex_socket.rb) shows it timing out after 5 seconds.

      I tried immediately turning off blocking in RubyTCPSocket.java, which caused the test to pass. However, it knocked out open-uri for reading over HTTP, so that doesn't look like the solution.

      Both test cases pass under MRI.

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        Confirmed....MRI does these reads as non-blocking, waiting for the IO to become readable via a select. In our case, I would have expected that having separate native threads would serve the same purposes, but it appears that the blocking on gets interferes with the puts calls. Researching a bit.

        Show
        Charles Oliver Nutter added a comment - Confirmed....MRI does these reads as non-blocking, waiting for the IO to become readable via a select. In our case, I would have expected that having separate native threads would serve the same purposes, but it appears that the blocking on gets interferes with the puts calls. Researching a bit.
        Hide
        Charles Oliver Nutter added a comment -

        I think the proper way to fix this is by making our IO use a Selector for most operations. But I've been unable to determine the proper way to safely manage one or more Selector instances to be used by multiple threads. My current theory goes like this:

        • Assume we're not concerned about having multiple CPU threads handle selection for us...some documents recommend one selector per CPU.
        • We create a global Selector for a runtime, or for a whole application
        • For each new SelectableChannel we register with that Selector
        • Blocking operations then become Selector.select() loops on the calling thread, waiting for the appropriate SelectionKey to be chosen. This allows the one selector to pump all threads working with selectable channels.

        Questions in my mind, which we'll need to research:

        • One selector per runtime? One per JVM? What are the down sides of too many selectors and what are the down sides of having too many threads using a single selector?
        • Is this usage pattern even correct?
        • Will a single Selector impact us negatively on large multi-way boxes, or could we safely assume the selection process will be minimal that parallelizing it isn't important
        Show
        Charles Oliver Nutter added a comment - I think the proper way to fix this is by making our IO use a Selector for most operations. But I've been unable to determine the proper way to safely manage one or more Selector instances to be used by multiple threads. My current theory goes like this: Assume we're not concerned about having multiple CPU threads handle selection for us...some documents recommend one selector per CPU. We create a global Selector for a runtime, or for a whole application For each new SelectableChannel we register with that Selector Blocking operations then become Selector.select() loops on the calling thread, waiting for the appropriate SelectionKey to be chosen. This allows the one selector to pump all threads working with selectable channels. Questions in my mind, which we'll need to research: One selector per runtime? One per JVM? What are the down sides of too many selectors and what are the down sides of having too many threads using a single selector? Is this usage pattern even correct? Will a single Selector impact us negatively on large multi-way boxes, or could we safely assume the selection process will be minimal that parallelizing it isn't important
        Hide
        Galin Yordanov added a comment -

        I think that this same issue im having, and it more or less renders xmpp4r lib/gem useless under jruby.

        Xmpp4r spawn a read thread that waits, and then sends message to the server, at this point the write blocks and here we stop ..
        is there a easy way around this issue ? i need xmpp4r to work as its acting as a nice gateway to a old java api i still need to use.

        Let me know if i can help with any more information and tests, tried that on jruby1.1.3 and fresh svn checkout on osx leopard (java build 1.5.0_13-b05-237),
        did not seem to make a difference using java 1.6 or running it on debian stable with java build 1.5.0_14-b03.

        Regards,
        Galin

        Show
        Galin Yordanov added a comment - I think that this same issue im having, and it more or less renders xmpp4r lib/gem useless under jruby. Xmpp4r spawn a read thread that waits, and then sends message to the server, at this point the write blocks and here we stop .. is there a easy way around this issue ? i need xmpp4r to work as its acting as a nice gateway to a old java api i still need to use. Let me know if i can help with any more information and tests, tried that on jruby1.1.3 and fresh svn checkout on osx leopard (java build 1.5.0_13-b05-237), did not seem to make a difference using java 1.6 or running it on debian stable with java build 1.5.0_14-b03. Regards, Galin
        Hide
        Charles Oliver Nutter added a comment -

        Here's an attempt at fixing this, but I think it adds too much overhead to gets and seems to freeze up other parts of our test run.

        Show
        Charles Oliver Nutter added a comment - Here's an attempt at fixing this, but I think it adds too much overhead to gets and seems to freeze up other parts of our test run.
        Hide
        Eric Anderson added a comment -

        This just bit me, re: xmpp4r

        Show
        Eric Anderson added a comment - This just bit me, re: xmpp4r
        Hide
        Hiroshi Nakamura added a comment -

        Eric: I think this problem would not be happen on recent jruby releases. Can you show us more detail of your problem?

        • JRuby version?
        • Are you using JRuby-OSSL?
        Show
        Hiroshi Nakamura added a comment - Eric: I think this problem would not be happen on recent jruby releases. Can you show us more detail of your problem? JRuby version? Are you using JRuby-OSSL?
        Hide
        Charles Oliver Nutter added a comment -

        gets does appear to still go straight into a blocking call rather than doing selection logic. It shouldn't be hard to add, but there are many paths that "gets" can follow based on input and stream state.

        Show
        Charles Oliver Nutter added a comment - gets does appear to still go straight into a blocking call rather than doing selection logic. It shouldn't be hard to add, but there are many paths that "gets" can follow based on input and stream state.

          People

          • Assignee:
            Unassigned
            Reporter:
            Adam Payne
          • Votes:
            4 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

            • Created:
              Updated: