Example usage for io.netty.buffer ByteBuf release

List of usage examples for io.netty.buffer ByteBuf release

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf release.

Prototype

boolean release();

Source Link

Document

Decreases the reference count by 1 and deallocates this object if the reference count reaches at 0 .

Usage

From source file:dorkbox.network.serialization.Serialization.java

License:Apache License

/**
 * Called when initialization is complete. This is to prevent (and recognize) out-of-order class/serializer registration. If an ID
 * is already in use by a different type, a {@link KryoException} is thrown.
 *///from  w w w  . ja  v a2  s.c o  m
@Override
public synchronized void finishInit(final Logger wireReadLogger, final Logger wireWriteLogger) {
    this.wireReadLogger = wireReadLogger;
    this.wireWriteLogger = wireWriteLogger;

    initialized = true;

    // initialize the kryo pool with at least 1 kryo instance. This ALSO makes sure that all of our class registration is done
    // correctly and (if not) we are are notified on the initial thread (instead of on the network update thread)
    KryoExtra kryo = kryoPool.take();
    try {

        // now MERGE all of the registrations (since we can have registrations overwrite newer/specific registrations

        ArrayList<ClassRegistration> mergedRegistrations = new ArrayList<ClassRegistration>();

        for (ClassRegistration registration : classesToRegister) {
            int id = registration.id;

            // if we ALREADY contain this registration (based ONLY on ID), then overwrite the existing one and REMOVE the current one
            boolean found = false;
            for (int index = 0; index < mergedRegistrations.size(); index++) {
                final ClassRegistration existingRegistration = mergedRegistrations.get(index);
                if (existingRegistration.id == id) {
                    mergedRegistrations.set(index, registration);
                    found = true;
                    break;
                }
            }

            if (!found) {
                mergedRegistrations.add(registration);
            }
        }

        // now all of the registrations are IN ORDER and MERGED
        this.mergedRegistrations = mergedRegistrations.toArray(new ClassRegistration[0]);

        Object[][] registrationDetails = new Object[mergedRegistrations.size()][3];

        for (int i = 0; i < mergedRegistrations.size(); i++) {
            final ClassRegistration registration = mergedRegistrations.get(i);
            registration.log(logger);

            // now save all of the registration IDs for quick verification/access
            registrationDetails[i] = new Object[] { registration.id, registration.clazz.getName(),
                    registration.serializer.getClass().getName() };

            // now we have to manage caching methods (only as necessary)
            if (registration.clazz.isInterface()) {
                // can be a normal class or an RMI class...
                Class<?> implClass = null;

                if (registration instanceof ClassSerializerRmi) {
                    implClass = ((ClassSerializerRmi) registration).implClass;
                }

                CachedMethod[] cachedMethods = RmiUtils.getCachedMethods(Serialization.logger, kryo, useAsm,
                        registration.clazz, implClass, registration.id);
                methodCache.put(registration.id, cachedMethods);
            }
        }

        // save this as a byte array (so registration is faster)
        ByteBuf buffer = Unpooled.buffer(480);

        kryo.setRegistrationRequired(false);
        try {
            kryo.writeCompressed(buffer, registrationDetails);
        } catch (Exception e) {
            logger.error("Unable to write compressed data for registration details");
        }

        int length = buffer.readableBytes();

        savedRegistrationDetails = new byte[length];
        buffer.getBytes(0, savedRegistrationDetails, 0, length);

        buffer.release();
    } finally {
        if (registrationRequired) {
            kryo.setRegistrationRequired(true);
        }

        kryoPool.put(kryo);
    }
}

From source file:dorkbox.network.serialization.Serialization.java

License:Apache License

/**
 * NOTE: When this fails, the CLIENT will just time out. We DO NOT want to send an error message to the client
 *   (it should check for updates or something else). We do not want to give "rogue" clients knowledge of the
 *   server, thus preventing them from trying to probe the server data structures.
 *
 * @return true if kryo registration is required for all classes sent over the wire
 *//*w  w  w .  j av  a 2s  . c om*/
@SuppressWarnings("Duplicates")
@Override
public boolean verifyKryoRegistration(byte[] otherRegistrationData) {
    // verify the registration IDs if necessary with our own. The CLIENT does not verify anything, only the server!
    byte[] kryoRegistrationDetails = savedRegistrationDetails;
    boolean equals = java.util.Arrays.equals(kryoRegistrationDetails, otherRegistrationData);
    if (equals) {
        return true;
    }

    // now we need to figure out WHAT was screwed up so we know what to fix
    KryoExtra kryo = takeKryo();

    ByteBuf byteBuf = Unpooled.wrappedBuffer(otherRegistrationData);

    try {
        kryo.setRegistrationRequired(false);
        @SuppressWarnings("unchecked")
        Object[][] classRegistrations = (Object[][]) kryo.readCompressed(byteBuf, otherRegistrationData.length);

        int lengthOrg = mergedRegistrations.length;
        int lengthNew = classRegistrations.length;
        int index = 0;

        // list all of the registrations that are mis-matched between the server/client
        for (; index < lengthOrg; index++) {
            final ClassRegistration classOrg = mergedRegistrations[index];

            if (index >= lengthNew) {
                logger.error("Missing client registration for {} -> {}", classOrg.id, classOrg.clazz.getName());
            } else {
                Object[] classNew = classRegistrations[index];
                int idNew = (Integer) classNew[0];
                String nameNew = (String) classNew[1];
                String serializerNew = (String) classNew[2];

                int idOrg = classOrg.id;
                String nameOrg = classOrg.clazz.getName();
                String serializerOrg = classOrg.serializer.getClass().getName();

                if (idNew != idOrg || !nameOrg.equals(nameNew)
                        || !serializerNew.equalsIgnoreCase(serializerOrg)) {
                    logger.error("Registration {} Client -> {} ({})", idNew, nameNew, serializerNew);
                    logger.error("Registration {} Server -> {} ({})", idOrg, nameOrg, serializerOrg);
                }
            }
        }

        // list all of the registrations that are missing on the server
        if (index < lengthNew) {
            for (; index < lengthNew; index++) {
                Object[] holderClass = classRegistrations[index];
                int id = (Integer) holderClass[0];
                String name = (String) holderClass[1];
                String serializer = (String) holderClass[2];

                logger.error("Missing server registration : {} -> {} ({})", id, name, serializer);
            }
        }
    } catch (Exception e) {
        logger.error("Error [{}] during registration validation", e.getMessage());

    } finally {
        if (registrationRequired) {
            kryo.setRegistrationRequired(true);
        }

        returnKryo(kryo);
        byteBuf.release();
    }

    return false;
}

From source file:eastwind.webpush.WebPushHandler.java

License:Apache License

private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
    // Generate an error page if response getStatus code is not OK (200).
    if (res.status().code() != 200) {
        ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8);
        res.content().writeBytes(buf);// w  ww .j a v  a2s .c  om
        buf.release();
    }

    // Send the response and close the connection if necessary.
    res.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/json; charset=UTF-8");
    res.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    HttpUtil.setContentLength(res, res.content().readableBytes());
    ChannelFuture f = ctx.channel().writeAndFlush(res);
    if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) {
        f.addListener(ChannelFutureListener.CLOSE);
    }
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoder.java

License:Apache License

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    if (this.stagedBuffer != null) {
        throw new IllegalStateException(
                "No channel read event should be fired " + "as long as the a buffer is staged.");
    }/*www.  j a v a2s .c o  m*/

    ByteBuf in = (ByteBuf) msg;

    if (this.bytesToSkip > 0) {
        this.bytesToSkip = skipBytes(in, this.bytesToSkip);

        // we skipped over the whole buffer
        if (this.bytesToSkip > 0) {
            in.release();
            return;
        }
    }

    decodeBuffer(in, ctx);
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoder.java

License:Apache License

/**
 * Decodes all Envelopes contained in a Netty ByteBuf and forwards them in the pipeline.
 * Returns true and releases the buffer, if it was fully consumed. Otherwise, returns false and retains the buffer.
 * </p>//from www .  j ava  2s.  co  m
 * In case of no buffer availability (returns false), a buffer availability listener is registered and the input
 * buffer is staged for later consumption.
 *
 * @return <code>true</code>, if buffer fully consumed, <code>false</code> otherwise
 * @throws IOException
 */
private boolean decodeBuffer(ByteBuf in, ChannelHandlerContext ctx) throws IOException {

    DecoderState decoderState;
    while ((decoderState = decodeEnvelope(in)) != DecoderState.PENDING) {
        if (decoderState == DecoderState.COMPLETE) {
            ctx.fireChannelRead(this.currentEnvelope);
            this.currentEnvelope = null;
        } else if (decoderState == DecoderState.NO_BUFFER_AVAILABLE) {
            switch (this.currentBufferProvider.registerBufferAvailabilityListener(this)) {
            case SUCCEEDED_REGISTERED:
                if (ctx.channel().config().isAutoRead()) {
                    ctx.channel().config().setAutoRead(false);

                    if (LOG.isDebugEnabled()) {
                        LOG.debug(String.format("Set channel %s auto read to false.", ctx.channel()));
                    }
                }

                this.stagedBuffer = in;
                this.stagedBuffer.retain();
                return false;

            case FAILED_BUFFER_AVAILABLE:
                continue;

            case FAILED_BUFFER_POOL_DESTROYED:
                this.bytesToSkip = skipBytes(in, this.currentBufferRequestSize);

                this.currentBufferRequestSize = 0;
                this.currentEventsBuffer = null;
                this.currentEnvelope = null;
            }
        }
    }

    if (in.isReadable()) {
        throw new IllegalStateException("Every buffer should have been fully"
                + "consumed after *successfully* decoding it (if it was not successful, "
                + "the buffer will be staged for later consumption).");
    }

    in.release();
    return true;
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoderTest.java

License:Apache License

@Test
public void testBufferStaging() throws Exception {
    final InboundEnvelopeDecoder decoder = new InboundEnvelopeDecoder(this.bufferProviderBroker);
    final EmbeddedChannel ch = new EmbeddedChannel(new OutboundEnvelopeEncoder(), decoder);

    when(this.bufferProviderBroker.getBufferProvider(anyJobId(), anyChannelId()))
            .thenReturn(this.bufferProvider);

    // --------------------------------------------------------------------

    Envelope[] envelopes = nextEnvelopes(3, true);

    ByteBuf buf = encode(ch, envelopes);

    when(this.bufferProvider
            .registerBufferAvailabilityListener(Matchers.<BufferAvailabilityListener>anyObject()))
                    .thenReturn(BufferAvailabilityRegistration.SUCCEEDED_REGISTERED);

    Buffer buffer = allocBuffer(envelopes[2].getBuffer().size());

    when(this.bufferProvider.requestBuffer(anyInt())).thenReturn(null, null, buffer, null);

    // --------------------------------------------------------------------

    // slices: [0] => full envelope, [1] => half envelope, [2] => remaining half + full envelope
    ByteBuf[] slices = slice(buf, OutboundEnvelopeEncoder.HEADER_SIZE + envelopes[0].getBuffer().size(),
            OutboundEnvelopeEncoder.HEADER_SIZE + envelopes[1].getBuffer().size() / 2);

    // 1. no buffer available, incoming slice contains all data
    int refCount = slices[0].refCnt();

    decodeAndVerify(ch, slices[0]);//  www .  j a  v  a 2 s  .  com

    Assert.assertEquals(refCount + 1, slices[0].refCnt());
    Assert.assertFalse(ch.config().isAutoRead());

    // notify of available buffer (=> bufferAvailable() callback does return a buffer
    // of the current network buffer size; the decoder needs to adjust its size to the
    // requested size
    decoder.bufferAvailable(allocBuffer(envelopes[0].getBuffer().size() * 2));
    ch.runPendingTasks();

    Assert.assertEquals(refCount - 1, slices[0].refCnt());
    Assert.assertTrue(ch.config().isAutoRead());

    decodeAndVerify(ch, envelopes[0]);

    // 2. no buffer available, incoming slice does NOT contain all data
    refCount = slices[1].refCnt();

    decodeAndVerify(ch, slices[1]);

    Assert.assertEquals(refCount + 1, slices[1].refCnt());
    Assert.assertFalse(ch.config().isAutoRead());

    decoder.bufferAvailable(allocBuffer());
    ch.runPendingTasks();

    Assert.assertEquals(refCount - 1, slices[1].refCnt());
    Assert.assertTrue(ch.config().isAutoRead());

    decodeAndVerify(ch);

    // 3. buffer available
    refCount = slices[2].refCnt();

    decodeAndVerify(ch, slices[2], envelopes[1], envelopes[2]);

    Assert.assertEquals(refCount - 1, slices[2].refCnt());
    Assert.assertTrue(ch.config().isAutoRead());

    Assert.assertEquals(1, buf.refCnt());
    buf.release();
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoderTest.java

License:Apache License

@Test
public void testBufferStagingStagedBufferException() throws Exception {
    final EmbeddedChannel ch = new EmbeddedChannel(new OutboundEnvelopeEncoder(),
            new InboundEnvelopeDecoder(this.bufferProviderBroker));

    when(this.bufferProviderBroker.getBufferProvider(anyJobId(), anyChannelId()))
            .thenReturn(this.bufferProvider);

    // --------------------------------------------------------------------

    ByteBuf buf = encode(ch, nextEnvelope(true));

    when(this.bufferProvider.requestBuffer(anyInt())).thenReturn(null);

    when(this.bufferProvider
            .registerBufferAvailabilityListener(Matchers.<BufferAvailabilityListener>anyObject()))
                    .thenReturn(BufferAvailabilityRegistration.SUCCEEDED_REGISTERED);

    // --------------------------------------------------------------------

    int refCount = buf.refCnt();

    decodeAndVerify(ch, buf);//from  w w w .j  ava2  s. com

    Assert.assertFalse(ch.config().isAutoRead());
    Assert.assertEquals(refCount + 1, buf.refCnt());

    try {
        decodeAndVerify(ch, buf);
        Assert.fail("Expected IllegalStateException not thrown");
    } catch (IllegalStateException e) {
        // expected exception
    }

    buf.release();
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoderTest.java

License:Apache License

@Test
public void testEncodeDecode() throws Exception {
    final EmbeddedChannel ch = new EmbeddedChannel(new OutboundEnvelopeEncoder(),
            new InboundEnvelopeDecoder(this.bufferProviderBroker));

    when(this.bufferProviderBroker.getBufferProvider(anyJobId(), anyChannelId()))
            .thenReturn(this.bufferProvider);

    when(this.bufferProvider.requestBuffer(anyInt())).thenAnswer(new Answer<Object>() {
        @Override//from   w w w . j a  v  a2s .  c o  m
        public Object answer(InvocationOnMock invocation) throws Throwable {
            // fulfill the buffer request
            return allocBuffer((Integer) invocation.getArguments()[0]);
        }
    });

    // --------------------------------------------------------------------

    Envelope[] envelopes = new Envelope[] { nextEnvelope(0), nextEnvelope(2), nextEnvelope(32768),
            nextEnvelope(3782, new TestEvent1(34872527)),
            nextEnvelope(88, new TestEvent1(8749653), new TestEvent1(365345)),
            nextEnvelope(0, new TestEvent2(34563456), new TestEvent1(598432), new TestEvent2(976293845)),
            nextEnvelope(23) };

    ByteBuf buf = encode(ch, envelopes);

    // 1. complete ByteBuf as input
    int refCount = buf.retain().refCnt();

    decodeAndVerify(ch, buf, envelopes);
    Assert.assertEquals(refCount - 1, buf.refCnt());

    // 2. random slices
    buf.readerIndex(0);
    ByteBuf[] slices = randomSlices(buf);

    ch.writeInbound(slices);

    for (ByteBuf slice : slices) {
        Assert.assertEquals(1, slice.refCnt());
    }

    decodeAndVerify(ch, envelopes);

    buf.release();
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoderTest.java

License:Apache License

@Test
public void testEncodeDecodeRandomEnvelopes() throws Exception {
    final InboundEnvelopeDecoder decoder = new InboundEnvelopeDecoder(this.bufferProviderBroker);
    final EmbeddedChannel ch = new EmbeddedChannel(new OutboundEnvelopeEncoder(), decoder);

    when(this.bufferProviderBroker.getBufferProvider(anyJobId(), anyChannelId()))
            .thenReturn(this.bufferProvider);

    when(this.bufferProvider.requestBuffer(anyInt())).thenAnswer(new Answer<Object>() {
        @Override//from w ww  .j a  v a  2s .  c om
        public Object answer(InvocationOnMock invocation) throws Throwable {
            // fulfill the buffer request with the requested size
            return allocBuffer((Integer) invocation.getArguments()[0]);
        }
    });

    Random randomAnswerSource = new Random(RANDOM_SEED);

    RandomBufferRequestAnswer randomBufferRequestAnswer = new RandomBufferRequestAnswer(randomAnswerSource);

    RandomBufferAvailabilityRegistrationAnswer randomBufferAvailabilityRegistrationAnswer = new RandomBufferAvailabilityRegistrationAnswer(
            randomAnswerSource, randomBufferRequestAnswer);

    when(this.bufferProvider.requestBuffer(anyInt())).thenAnswer(randomBufferRequestAnswer);

    when(this.bufferProvider
            .registerBufferAvailabilityListener(Matchers.<BufferAvailabilityListener>anyObject()))
                    .thenAnswer(randomBufferAvailabilityRegistrationAnswer);

    // --------------------------------------------------------------------

    Envelope[] envelopes = nextRandomEnvelopes(1024);

    ByteBuf buf = encode(ch, envelopes);

    ByteBuf[] slices = randomSlices(buf);

    for (ByteBuf slice : slices) {
        int refCount = slice.refCnt();
        ch.writeInbound(slice);

        // registered BufferAvailabilityListener => call bufferAvailable(buffer)
        while (randomBufferAvailabilityRegistrationAnswer.isRegistered()) {
            randomBufferAvailabilityRegistrationAnswer.unregister();

            Assert.assertFalse(ch.config().isAutoRead());
            Assert.assertEquals(refCount + 1, slice.refCnt());

            // return a buffer of max size => decoder needs to limit buffer size
            decoder.bufferAvailable(allocBuffer(MAX_BUFFER_SIZE));
            ch.runPendingTasks();
        }

        Assert.assertEquals(refCount - 1, slice.refCnt());
        Assert.assertTrue(ch.config().isAutoRead());
    }

    Envelope[] expected = randomBufferAvailabilityRegistrationAnswer.removeSkippedEnvelopes(envelopes);

    decodeAndVerify(ch, expected);

    Assert.assertEquals(1, buf.refCnt());

    buf.release();
}

From source file:eu.stratosphere.runtime.io.network.netty.OutboundEnvelopeEncoderTest.java

License:Apache License

@Test
public void testEncodedSizeAndBufferRecycling() {
    final ByteBuffer events = ByteBuffer.allocate(MAX_EVENTS_SIZE);
    final MemorySegment segment = new MemorySegment(new byte[MAX_BUFFER_SIZE]);

    final Buffer buffer = mock(Buffer.class);
    when(buffer.getMemorySegment()).thenReturn(segment);

    final EmbeddedChannel channel = new EmbeddedChannel(new OutboundEnvelopeEncoder());

    int numBuffers = 0;
    for (int i = 0; i < NUM_RANDOM_ENVELOPES; i++) {
        Envelope env = new Envelope(i, new JobID(), new ChannelID());
        int expectedEncodedMsgSize = OutboundEnvelopeEncoder.HEADER_SIZE;

        if (random.nextBoolean()) {
            int eventsSize = random.nextInt(MAX_EVENTS_SIZE + 1);
            expectedEncodedMsgSize += eventsSize;

            events.clear();// ww  w . java 2  s.c om
            events.limit(eventsSize);

            env.setEventsSerialized(events);
        }

        if (random.nextBoolean()) {
            numBuffers++;

            int bufferSize = random.nextInt(MAX_BUFFER_SIZE + 1);
            when(buffer.size()).thenReturn(bufferSize);
            env.setBuffer(buffer);

            expectedEncodedMsgSize += bufferSize;
        }

        Assert.assertTrue(channel.writeOutbound(env));

        // --------------------------------------------------------------------
        // verify encoded ByteBuf size
        // --------------------------------------------------------------------
        ByteBuf encodedMsg = (ByteBuf) channel.readOutbound();
        Assert.assertEquals(expectedEncodedMsgSize, encodedMsg.readableBytes());

        encodedMsg.release();
    }

    // --------------------------------------------------------------------
    // verify buffers are recycled
    // --------------------------------------------------------------------
    verify(buffer, times(numBuffers)).recycleBuffer();
}