mauricio / postgresql-async

Async, Netty based, database drivers for PostgreSQL and MySQL written in Scala
Apache License 2.0
1.43k stars 222 forks source link

Fixed ByteBuf leaks #181

Closed manshengyang closed 8 years ago

manshengyang commented 8 years ago

PostgreSQLConnection.onDataRow should release the raw ByteBufs after decoding the data

These ByteBufs are allocated by DataRowParser and later passed to PostgreSQLConnection. Since on one will use them after PostgreSQLConnection, they should be released and returned to the pool.

Some context:

[info] 2016-05-12 02:58:52 ERROR ResourceLeakDetector:171 - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
[info] Recent access records: 2
[info] #2:
[info]  io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:459)
[info]  com.github.mauricio.async.db.column.ColumnDecoder$class.decode(ColumnDecoder.scala:27)
[info]  com.github.mauricio.async.db.column.StringEncoderDecoder$.decode(StringEncoderDecoder.scala:20)
[info]  com.github.mauricio.async.db.postgresql.column.PostgreSQLColumnDecoderRegistry.decode(PostgreSQLColumnDecoderRegistry.scala:51)
[info]  com.github.mauricio.async.db.postgresql.PostgreSQLConnection.onDataRow(PostgreSQLConnection.scala:198)
[info]  com.github.mauricio.async.db.postgresql.codec.PostgreSQLConnectionHandler.channelRead0(PostgreSQLConnectionHandler.scala:203)
[info]  io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
[info]  io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
[info]  io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
[info]  io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354)
[info]  io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145)
[info]  io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
[info]  io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:372)
[info]  io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245)
[info]  io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
[info]  io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
[info]  io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354)
[info]  io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145)
[info]  io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078)
[info]  io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398)
[info]  io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370)
[info]  io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742)
[info]  java.lang.Thread.run(Thread.java:745)
[info] #1:
[info]  io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:561)
[info]  io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:790)
[info]  com.github.mauricio.async.db.postgresql.parsers.DataRowParser$$anonfun$parseMessage$1.apply$mcVI$sp(DataRowParser.scala:35)
[info]  scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:166)
[info]  com.github.mauricio.async.db.postgresql.parsers.DataRowParser$.parseMessage(DataRowParser.scala:28)
[info]  com.github.mauricio.async.db.postgresql.parsers.MessageParsersRegistry.parse(MessageParsersRegistry.scala:55)
[info]  com.github.mauricio.async.db.postgresql.codec.MessageDecoder.decode(MessageDecoder.scala:75)
[info]  io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:387)
[info]  io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245)
[info]  io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
[info]  io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
[info]  io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354)
[info]  io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145)
[info]  io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078)
[info]  io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398)
[info]  io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370)
[info]  io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742)
[info]  java.lang.Thread.run(Thread.java:745)
[info] Created at:
[info]  io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:271)
[info]  io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179)
[info]  io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:115)
[info]  io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:789)
[info]  com.github.mauricio.async.db.postgresql.parsers.DataRowParser$$anonfun$parseMessage$1.apply$mcVI$sp(DataRowParser.scala:35)
[info]  scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:166)
[info]  com.github.mauricio.async.db.postgresql.parsers.DataRowParser$.parseMessage(DataRowParser.scala:28)
[info]  com.github.mauricio.async.db.postgresql.parsers.MessageParsersRegistry.parse(MessageParsersRegistry.scala:55)
[info]  com.github.mauricio.async.db.postgresql.codec.MessageDecoder.decode(MessageDecoder.scala:75)
[info]  io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:387)
[info]  io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245)
[info]  io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83)
[info]  io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154)
[info]  io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354)
[info]  io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145)
[info]  io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078)
[info]  io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484)
[info]  io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398)
[info]  io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370)
[info]  io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742)
[info]  java.lang.Thread.run(Thread.java:745)
mauricio commented 8 years ago

This is awesome, thanks man!