-
Notifications
You must be signed in to change notification settings - Fork 39
bug fix + ci / sbt / scala upgrades #95
bug fix + ci / sbt / scala upgrades #95
Conversation
@timperrett I get the same exception as in #93 - It only happens when using oraclejdk8 - I see the same error on shippable, so I suppose we have some sort of a bug. Here is the failure:
with this exception (note that it is an empty string it cannot parse):
thrown here: Odd thing being is that shippable with oraclejdk8 passes with 2.11.7, but fails with 2.10.5 and travis does the opposite. The JDK versions are a little bit different: shippable:
travis:
|
Agreed - it looks like a bug. Hmmmmm. What would you like to do here? Is it passing locally for you? |
I'll try to reproduce with same setup on a linux machine locally when I find the time. It passes locally, but I am on OSX :) |
I have tried to run tests with scala 2.11.7 / 2.10.5 with same JDK version as Travis on Ubuntu 15.04 and all tests pass. A bit lost here. |
@timperrett @stew I have done a little bit of debugging and I think I have found the error. Did the following in order to isolate what is messing things up: // Capabilities.scala
def parseHelloString(str: String): Attempt[Capabilities] = {
val debugParser = log(helloString)("Capabilities Parser")
val pr = parseAll(debugParser, str)
if(pr.successful) Attempt.successful(pr.get)
else Attempt.failure(Err("could not parse greeting from server: " + str))
} Getting this output (both on my OS X and Linux machines):
That made me focus on what happens in // ClientConnectionPool.scala
val validateCapabilities: ((Capabilities,Channel)) => Task[Channel] = {
case (capabilties, channel) =>
val missing = Capabilities.required -- capabilties.capabilities
if(missing.isEmpty) {
Task {
val pipe = channel.pipeline()
pipe.removeLast()
pipe.addLast("enframe", Enframe)
pipe.addLast("deframe", new Deframe)
channel
}
}
else {
channel.close()
Task.fail(IncompatibleServer("server missing required capabilities: " + missing))
}
} I realized that If I do this: else {
channel.pipeline().removeLast()
channel.close()
Task.fail(IncompatibleServer("server missing required capabilities: " + missing))
} we do not end up invoking parseHelloString with an empty string. |
Furthermore, perhaps it would be better to register handlers with name and remove them by name using addLast(String name, ChannelHandler handler);
ChannelHandler remove(String name); |
e0e0df1
to
7d99c65
Compare
My guess for @timperrett I am not sure that my fix is sound, I think @stew and you can make that call. However, as you see this is making Travis happy. My shippable CI setup of remotely is also happy :) |
@@ -77,6 +78,7 @@ class NettyConnectionPool(hosts: Process[Task,InetSocketAddress], | |||
} | |||
} | |||
else { | |||
pipe.removeLast() | |||
channel.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jedesah channel.close
bothers me a bit as it returns a ChannelFuture
that is not handled in the same way as:
Task.async[Channel] { cb =>
val _ = fut.addListener(new ChannelFutureListener {
def operationComplete(cf: ChannelFuture): Unit = {
if(cf.isSuccess) cb(\/-(cf.channel)) else cb(-\/(cf.cause))
}
})
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that would be included then I suppose it could be done like this:
Task.async[Channel] { cb =>
pipe.removeLast()
val listener = new ChannelFutureListener {
def operationComplete(cf: ChannelFuture): Unit = {
if(cf.isSuccess) cb(\/-(cf.channel)) else cb(-\/(cf.cause))
}
}
val _ = channel.close().addListener(listener)
} flatMap { case _ => Task.fail(IncompatibleServer("...")) }
However, I am a bit ignorant when it comes to the netty stuff and whether a simple channel.close
is ok in this scenario.
0f8ef24
to
4b12d6d
Compare
- adjust .travis.yml to separate compilation from test in order to have more memory when running tests. - change `NettyConnectionPool` to remove `ClientNegotiateCapabilities` when validation of capabilities fails in order to avoid having it try parsing an empty string just before failing with `IncompatibleServer`. Moreover, instruct sbt to use more memory for heap and stack. - bump dependencies `scodec-core` to `1.8.2`, `scalaz-stream` to `0.7.3a` and `scalaz-core` to `7.1.3`. - bump version of scala to `2.11.7` and `2.10.6`, and sbt to `0.13.9`.
4b12d6d
to
5180f42
Compare
adjust
.travis.yml
to separate compilation fromtest in order to have more memory when running
tests.
change
NettyConnectionPool
to removeClientNegotiateCapabilities
when validation of capabilities fails in order to avoid having it
try parsing an empty string just before failing with
IncompatibleServer
.Moreover, instruct sbt to use more memory
for heap and stack.
bump dependencies
scodec-core
to1.8.2
,scalaz-stream
to0.7.3a
andscalaz-core
to
7.1.3
.bump version of scala to
2.11.7
and2.10.6
,and sbt to
0.13.9
.