When WispService.stop is called, its internal ActorPools are stopped. This causes a problem for restarting the service:
Fantom Shell v1.0.54 ('?' for help)
fansh> wisp::WispService { port = 8080 }.start
fan.wisp.WispService@1309e87
fansh> [18:33:07 05-Oct-10] [info] [web] WispService started on port 8080
fansh> Service.find(wisp::WispService#).stop
fan.wisp.WispService@1309e87
fansh> Service.find(wisp::WispService#).start
sys::Err: ActorPool is stopped
at fan.sys.Err.make(Err.java:78)
at fan.sys.Err.make(Err.java:75)
at fan.concurrent.Actor._send(Actor.java:140)
at fan.concurrent.Actor.send(Actor.java:91)
at fan.wisp.WispService.onStart(WispService.fan:39)
at fan.sys.Service$.start(Service$.java:205)
at fan.wisp.WispService.start(WispService.fan)
at fan.sh2.FanshEval._eval(fansh:5)
...
fan.wisp.WispService@1309e87
Uninstalling WispService has no effect, as the old service instance does not release the port:
Fantom Shell v1.0.54 ('?' for help)
fansh> wisp::WispService { port = 8080 }.start
fan.wisp.WispService@19ce060
fansh> [18:38:58 05-Oct-10] [info] [web] WispService started on port 8080
fansh> Service.find(wisp::WispService#).uninstall
fan.wisp.WispService@19ce060
fansh> wisp::WispService { port = 8080 }.start
fan.wisp.WispService@5a67c9
fansh> [18:39:17 05-Oct-10] [err] [web] WispService cannot bind to port 8080
sys::IOErr: java.net.BindException: Address already in use
java.net.PlainSocketImpl.socketBind (PlainSocketImpl.java)
java.net.PlainSocketImpl.bind (PlainSocketImpl.java:365)
java.net.ServerSocket.bind (ServerSocket.java:319)
inet::TcpListenerPeer.bind (TcpListenerPeer.java:83)
inet::TcpListener.bind (TcpListener.fan)
inet::TcpListener.bind (TcpListener.fan)
wisp::WispService.listen (WispService.fan:59)
wisp::WispService.onStart (WispService.fan:39)
fan.sys.Func$Indirect0.call (Func.java:121)
concurrent::Actor.receive (Actor.java:99)
concurrent::Actor._dispatch (Actor.java:225)
concurrent::Actor._work (Actor.java:196)
concurrent::ThreadPool$Worker.run (ThreadPool.java:255)
Ideally WispService should be able to resume after a stop / start cycle. If this is not possible (which seems likely due to the const requirement on sys::Service and the fact that an concurrent::ActorPool cannot be restarted once stopped) then the documentation should state this limitation.
In any case, the fact that WispService does not unbind from the port when stop is invoked is a bug and should be fixed. Looks like wisp::WispService.listen is missing a call to TcpListener.close.
brianWed 6 Oct 2010
Not too good.
I pushed a changeset which does a couple of things:
releases the port on shutdown and logs a messages
makes shutdown more robust in case root WebMod raises an exception
cleared up exception/documentation about reuse after stop
qualidafialWed 6 Oct 2010
Should this be promoted to a ticket for tracking purposes?
brianWed 6 Oct 2010
Should this be promoted to a ticket for tracking purposes?
Yeah good question. I think once we have a real release we probably want to track everything formally.
The loose process I am using now is basically this: if I am not going to fix immediately, I turn it into a ticket just to track for myself. If I fix it immediately then I don't promote it into a ticket, although I do note the topic number in the changeset and in the changelog.
qualidafial Wed 6 Oct 2010
When
WispService.stopis called, its internal ActorPools are stopped. This causes a problem for restarting the service:Fantom Shell v1.0.54 ('?' for help) fansh> wisp::WispService { port = 8080 }.start fan.wisp.WispService@1309e87 fansh> [18:33:07 05-Oct-10] [info] [web] WispService started on port 8080 fansh> Service.find(wisp::WispService#).stop fan.wisp.WispService@1309e87 fansh> Service.find(wisp::WispService#).start sys::Err: ActorPool is stopped at fan.sys.Err.make(Err.java:78) at fan.sys.Err.make(Err.java:75) at fan.concurrent.Actor._send(Actor.java:140) at fan.concurrent.Actor.send(Actor.java:91) at fan.wisp.WispService.onStart(WispService.fan:39) at fan.sys.Service$.start(Service$.java:205) at fan.wisp.WispService.start(WispService.fan) at fan.sh2.FanshEval._eval(fansh:5) ... fan.wisp.WispService@1309e87Uninstalling
WispServicehas no effect, as the old service instance does not release the port:Fantom Shell v1.0.54 ('?' for help) fansh> wisp::WispService { port = 8080 }.start fan.wisp.WispService@19ce060 fansh> [18:38:58 05-Oct-10] [info] [web] WispService started on port 8080 fansh> Service.find(wisp::WispService#).uninstall fan.wisp.WispService@19ce060 fansh> wisp::WispService { port = 8080 }.start fan.wisp.WispService@5a67c9 fansh> [18:39:17 05-Oct-10] [err] [web] WispService cannot bind to port 8080 sys::IOErr: java.net.BindException: Address already in use java.net.PlainSocketImpl.socketBind (PlainSocketImpl.java) java.net.PlainSocketImpl.bind (PlainSocketImpl.java:365) java.net.ServerSocket.bind (ServerSocket.java:319) inet::TcpListenerPeer.bind (TcpListenerPeer.java:83) inet::TcpListener.bind (TcpListener.fan) inet::TcpListener.bind (TcpListener.fan) wisp::WispService.listen (WispService.fan:59) wisp::WispService.onStart (WispService.fan:39) fan.sys.Func$Indirect0.call (Func.java:121) concurrent::Actor.receive (Actor.java:99) concurrent::Actor._dispatch (Actor.java:225) concurrent::Actor._work (Actor.java:196) concurrent::ThreadPool$Worker.run (ThreadPool.java:255)Ideally WispService should be able to resume after a
stop/startcycle. If this is not possible (which seems likely due to theconstrequirement onsys::Serviceand the fact that anconcurrent::ActorPoolcannot be restarted once stopped) then the documentation should state this limitation.In any case, the fact that WispService does not unbind from the port when
stopis invoked is a bug and should be fixed. Looks like wisp::WispService.listen is missing a call toTcpListener.close.brian Wed 6 Oct 2010
Not too good.
I pushed a changeset which does a couple of things:
qualidafial Wed 6 Oct 2010
Should this be promoted to a ticket for tracking purposes?
brian Wed 6 Oct 2010
Yeah good question. I think once we have a real release we probably want to track everything formally.
The loose process I am using now is basically this: if I am not going to fix immediately, I turn it into a ticket just to track for myself. If I fix it immediately then I don't promote it into a ticket, although I do note the topic number in the changeset and in the changelog.