self.trapExit = List(classOf[Exception])
self.faultHandler = Some(OneForOneStrategy(Integer.MAX_VALUE,
Integer.MAX_VALUE))
Any exception thrown inside the read() or write() handler is not
noticed by the supervising actor, and the I/O actor is not restarted
as expected. Exceptions thrown outside the event-handlers works fine.
init = {
....
readSource = createSource(channel, SelectionKey.OP_READ,
HawtDispatcher.queue(self));
readSource.setEventHandler(^ { read })
.....
}
/** Catch IO Exception */
private def catchio(func: => Unit): Unit = {
try {
func
} catch {
case e: IOException => debug(e.toString); socketCrash()
}
}
/** Read data from socket */
private def read(): Unit = catchio {
channel.read(readBuffer) match {
case -1 => socketCrash() // peer disconnected.
case 0 =>
case count: Int => {
handleReply(DHCPPacket.getPacket(readBuffer.array, 0,
readBuffer.position, false)) /* Factory a new packet with strict mode
disabled */
readBuffer.clear
readCounter += count
}
}
}
/** Shutdown due to socket IO error */
private def socketCrash() = {
throw new RuntimeException("Unexpected I/O interrupt")
}
Stacktrace:
java.lang.RuntimeException: Unexpected I/O interrupt
at com.psm.leasepoller.leasequery.LeaseQueryIO$class.com$psm$leasepoller$leasequery$LeaseQueryIO$$socketCrash(LeaseQueryIO.scala:96)
at com.psm.leasepoller.leasequery.LeaseQueryIO$class.catchio(LeaseQueryIO.scala:59)
at com.psm.leasepoller.leasequery.LeaseQueryIO$class.com$psm$leasepoller$leasequery$LeaseQueryIO$$read(LeaseQueryIO.scala:64)
at com.psm.leasepoller.leasequery.LeaseQueryIO$$anonfun$socketInit$1.apply$mcV$sp(LeaseQueryIO.scala:37)
at org.fusesource.hawtdispatch.ScalaDispatch$$anon$1.run(ScalaDispatch.scala:251)
at org.fusesource.hawtdispatch.internal.NioDispatchSource$4.run(NioDispatchSource.java:229)
at org.fusesource.hawtdispatch.internal.SerialDispatchQueue.dispatch(SerialDispatchQueue.java:170)
at org.fusesource.hawtdispatch.internal.SerialDispatchQueue.dispatchLoop(SerialDispatchQueue.java:120)
at org.fusesource.hawtdispatch.internal.SerialDispatchQueue.dispatch(SerialDispatchQueue.java:84)
at org.fusesource.hawtdispatch.internal.SerialDispatchQueue.run(SerialDispatchQueue.java:74)
at org.fusesource.hawtdispatch.internal.pool.SimpleThread.run(SimpleThread.java:66)
read_source.setEventHandler(^{ read })
read_source.setCancelHandler(^{ close })
This would require a change in HawtDispatch (if we want to do it cleanly)
If you link Session to Server then I guess you could do something like
this. Change the catchio fun to this:
private def catchio(func: =>Unit):Unit = {
try {
func
} catch {
case e:IOException => close
case e => server ! Exit(self, e)
}
}
That should restart the Session actor instance. This requires this
code to create the Session:
val session = actorOf(new Session(self, socket))
self.startLink(session)
sessions += session
Let me know if it works.
> --
> You received this message because you are subscribed to the Google Groups "Akka User List" group.
> To post to this group, send email to akka...@googlegroups.com.
> To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.
>
>
--
Jonas Bonér
work: http://akkasource.org
code: http://github.com/jboner
blog: http://jonasboner.com
twtr: @jboner
2010/10/20 Jonas Bonér <jo...@jonasboner.com>: