Thanks, Jerome. That sounds like great progress.

Rather than exposing a new method, what about tracking things internally?

The pseudocode I'm thinking of is like this:

   public void setPort(int port) {
if (started()) throw new IllegalStateException("can't change port on running server");
       this.requestedPort = port;
   }

   public void start() {
       this.serverHelper = new StreamServerHelper(requestedPort);
   }

   public int getPort() {
       if (started()) return serverHelper.getPort();
       return requestedPort;
   }

That would let you provide the stop/start functionality without having to change the API or making people remember to use a different call under particular circumstances.

If you don't like that, then I'd suggest changing it from getPort() and getEphemeralPort() to getRequestedPort() and getPortInUse() or something like that.

Thanks again,

William

Jerome Louvel wrote:
Hi William,

I wasn't aware of those ephemeral ports, but that looks like a very useful
feature to support! Thanks for proposing some implementation alternatives.
I went ahead and added a "getEphemeralPort()" public method on Server. I
didn't want to modify the "port" property because it would remove the
ability to start/stop several times a server without loosing the request to
use an ephemeral port.

For the implementation, I've extended Helper to add an attributes map where
I stuff the ephemeral port (or '-1' if not available). I've implemented and
tested it for all connectors (Internal, Grizzly, Simple and Jetty).

The code is checked in SVN trunk. Let me know if it covers your need
properly.

Best regards,
Jerome
-----Message d'origine-----
De : William Pietri [mailto:[EMAIL PROTECTED] Envoyé : lundi 28 janvier 2008 00:29
À : [email protected]
Objet : Starting servers on ephemeral ports

Hi! I came across another interesting issue while writing tests for my
Restlet app. This time it involves using Selenium, which talks to my app
over HTTP.

Because it's an automated test, I don't really care what port something is running on, and I don't want the test to fail because a hard-coded port number is already in use. Happily, a port number of zero means that the OS should just pick an arbitrary port. I would thus expect code like this to
work:

    Server server = new Server(Protocol.HTTP, port, new MyApp());
    server.start();
    String root = "http://127.0.0.1:"; + server.getPort() + "/";
    Selenium browser = new DefaultSelenium(SELENIUM__SERVER,
          SELENIUM_PORT, BROWSER, root);


It comes close, but doesn't totally work. My app does indeed start up on what InetSocketAddress calls an ephemeral port. However, the Server object never learns that port number; it assumes that the port assigned is the
port requested.

I was trying to figure out a reasonable patch for this. I can see two
approaches.

One would be to type the helper as a ServerHelper, add getAddress() and getPort() methods to that, and then delegate those methods on Server to
the ServerHelper.

The other is to have the StreamServerHelper stuff the address and port
information back into the Server once the bind completes. That would
involve touching less code, but would introduce a method or methods on
Server's public interface that I don't like much.

Any suggestions on how to proceed?

Thanks,

William



--
William Pietri - [EMAIL PROTECTED] - +1-415-643-1024
Agile consulting, coaching, and development: http://www.scissor.com/
Use your geek-fu to fight poverty: http://www.mifos.org/

Reply via email to