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/