Java ReadableByteChannel Read readAnerisHeader(ReadableByteChannel from, ByteBuffer buffer)

Here you can find the source of readAnerisHeader(ReadableByteChannel from, ByteBuffer buffer)

Description

Reads a header from the given channel connected to the Aneris service using the provided buffer.

License

Open Source License

Declaration

public static int readAnerisHeader(ReadableByteChannel from, ByteBuffer buffer) throws Exception 

Method Source Code

//package com.java2s;
/* Copyright 2012 Cornell University
 * Copyright 2013 Cornell University/*from  w w w.  j a va  2  s .  co m*/
 *
 *
 * This file is part of ShadowDB - a replicated database based on
 * an formally-verified implementation of an atomic broadcast service.
 * The normal case processing is written in Java, while failure-handling is taken
 * care of by an atomic broadcast service called Aneris. Aneris contains
 * two formally-verified implementations of atomic broadcast, one is
 * based on Paxos, the other one is based on two-third consensus.
 * 
 * The three code contributors of this project are:
 * Vincent Rahli (Aneris)
 * Nicolas Schiper (ShadowDB)
 * Mark Bickford (Aneris)
 * 
 * ShadowDB was implemented at Cornell University, Ithaca, NY.
 *
 * ShadowDB is a free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ShadowDB is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ShadowDB.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  o Authors:     Nicolas Schiper
 *  o Affiliation: Cornell University
 *  o Date:        13 May 2013
 *  o File name:   NIOUtils.java
 *  o Description: A utility class to interact with non-blocking channels.
 */

import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

public class Main {
    public static final int ERROR_HEADER_INT = -2;
    /**
     * When reading from an Aneris channel, we will retry a couple
     * of times before giving up and considering the other end crashed.
     * More specifically, we will retry {@code RETRIAL_COUNT} times and
     * sleep {@code SLEEP_TIME_BETWEEN_TRIALS} number of times.
     */
    private static final int RETRIAL_COUNT = 1000;
    private static final int SLEEP_TIME_BETWEEN_TRIALS = 1;

    /**
     * <p> Reads a header from the given channel connected to the Aneris service using the provided buffer.
     * The header is returned as an integer. If the header could not be read,
     * {@code ERROR_HEADER_INT} is returned.
     * 
     * <p> This method uses an "ad-hoc" way to detect that the end host crashed: if after reading data
     * {@value #RETRIAL_COUNT} times from the channel (and sleeping {@value #SLEEP_TIME_BETWEEN_TRIALS} ms between
     * trials) no bytes could be read, we consider the end host dead and return {@code ERROR_HEADER_INT}.
     */
    public static int readAnerisHeader(ReadableByteChannel from, ByteBuffer buffer) throws Exception {

        int headerLength = 0;
        int trialNo = 1;

        do {
            buffer.position(headerLength);
            headerLength++;
            buffer.limit(headerLength);

            while (buffer.hasRemaining()) {
                int bytesRead = from.read(buffer);

                if (bytesRead == 0) {
                    Thread.sleep(SLEEP_TIME_BETWEEN_TRIALS);
                    trialNo++;
                    if (trialNo == RETRIAL_COUNT) {
                        return ERROR_HEADER_INT;
                    }
                } else if (bytesRead < 0) {
                    return ERROR_HEADER_INT;
                }
            }
        } while (buffer.get(headerLength - 1) != '!');

        // The returned header does not include the '!'.
        byte[] headerBytes = new byte[headerLength - 1];
        buffer.flip();
        buffer.get(headerBytes);
        String headerStr = new String(headerBytes);
        return Integer.parseInt(headerStr);
    }
}

Related

  1. read(ReadableByteChannel channel, ByteBuffer[] dsts)
  2. read(ReadableByteChannel channel, ByteBuffer[] dsts, int offset, int length)
  3. read(ReadableByteChannel channel, int amount, ByteBuffer dest)
  4. readAll(ReadableByteChannel ch, ByteBuffer dst)
  5. readAllBytesOrNone(ReadableByteChannel channel, ByteBuffer buffer, int numBytes)
  6. readBuffer(ReadableByteChannel chan, ByteBuffer buf)
  7. readCharArray(ReadableByteChannel channel, ByteBuffer buffer, char[] charArray)
  8. readFromAnerisChannel(ReadableByteChannel chan, ByteBuffer buffer)
  9. readFromChannel(ReadableByteChannel channel, ByteBuffer buffer)