Search in sources :

Example 11 with Layout

use of org.corfudb.runtime.view.Layout in project CorfuDB by CorfuDB.

the class ChainReplicationProtocolTest method failedWriteCanBeRead.

/** Check to see that a read correctly
     * completes a failed write from another client.
     */
@Test
public void failedWriteCanBeRead() throws Exception {
    setupNodes();
    //begin tests
    final CorfuRuntime r = getDefaultRuntime();
    final IReplicationProtocol rp = getProtocol();
    final Layout layout = r.getLayoutView().getLayout();
    LogData incompleteWrite = getLogData(0, "incomplete".getBytes());
    // Write the incomplete write to the head of the chain
    r.getRouter(SERVERS.ENDPOINT_0).getClient(LogUnitClient.class).write(incompleteWrite);
    // At this point, a read
    // reflect the -other- clients value
    ILogData readResult = rp.read(layout, 0);
    assertThat(readResult.getPayload(r)).isEqualTo("incomplete".getBytes());
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) LogUnitClient(org.corfudb.runtime.clients.LogUnitClient) Layout(org.corfudb.runtime.view.Layout) CorfuRuntime(org.corfudb.runtime.CorfuRuntime) Test(org.junit.Test)

Example 12 with Layout

use of org.corfudb.runtime.view.Layout in project CorfuDB by CorfuDB.

the class FailureHandlerDispatcher method dispatchHandler.

/**
     * Takes in the existing layout and a set of failed nodes.
     * It first generates a new layout by removing the failed nodes from the existing layout.
     * It then seals the epoch to prevent any client from accessing the stale layout.
     * Finally we run paxos to update all servers with the new layout.
     *
     * @param currentLayout The current layout
     * @param corfuRuntime  Connected corfu runtime instance
     * @param failedServers Set of failed server addresses
     */
public void dispatchHandler(IFailureHandlerPolicy failureHandlerPolicy, Layout currentLayout, CorfuRuntime corfuRuntime, Set<String> failedServers) {
    try {
        // Generates a new layout by removing the failed nodes from the existing layout
        Layout newLayout = failureHandlerPolicy.generateLayout(currentLayout, corfuRuntime, failedServers);
        // Seals and increments the epoch.
        currentLayout.setRuntime(corfuRuntime);
        sealEpoch(currentLayout);
        // Reconfigure servers if required
        reconfigureServers(corfuRuntime, currentLayout, newLayout, false);
        // Attempts to update all the layout servers with the modified layout.
        try {
            corfuRuntime.getLayoutView().updateLayout(newLayout, prepareRank);
            prepareRank++;
        } catch (OutrankedException oe) {
            // Update rank since outranked.
            log.error("Conflict in updating layout by failureHandlerDispatcher: {}", oe);
            // Update rank to be able to outrank other competition and complete paxos.
            prepareRank = oe.getNewRank() + 1;
        }
        // Check if our proposed layout got selected and committed.
        corfuRuntime.invalidateLayout();
        if (corfuRuntime.getLayoutView().getLayout().equals(newLayout)) {
            log.info("Failed node removed. New Layout committed = {}", newLayout);
        }
    } catch (Exception e) {
        log.error("Error: dispatchHandler: {}", e);
    }
}
Also used : Layout(org.corfudb.runtime.view.Layout) OutrankedException(org.corfudb.runtime.exceptions.OutrankedException) ExecutionException(java.util.concurrent.ExecutionException) QuorumUnreachableException(org.corfudb.runtime.exceptions.QuorumUnreachableException) OutrankedException(org.corfudb.runtime.exceptions.OutrankedException)

Example 13 with Layout

use of org.corfudb.runtime.view.Layout in project CorfuDB by CorfuDB.

the class LayoutServer method handleMessageLayoutPrepare.

/**
     * Accepts a prepare message if the rank is higher than any accepted so far.
     * @param msg
     * @param ctx
     * @param r
     */
// TODO this can work under a separate lock for this step as it does not change the global components
@ServerHandler(type = CorfuMsgType.LAYOUT_PREPARE, opTimer = metricsPrefix + "prepare")
public synchronized void handleMessageLayoutPrepare(CorfuPayloadMsg<LayoutPrepareRequest> msg, ChannelHandlerContext ctx, IServerRouter r, boolean isMetricsEnabled) {
    // Check if the prepare is for the correct epoch
    if (!checkBootstrap(msg, ctx, r)) {
        return;
    }
    Rank prepareRank = new Rank(msg.getPayload().getRank(), msg.getClientID());
    Rank phase1Rank = getPhase1Rank();
    Layout proposedLayout = getProposedLayout();
    long serverEpoch = getServerEpoch();
    if (msg.getPayload().getEpoch() != serverEpoch) {
        r.sendResponse(ctx, msg, new CorfuPayloadMsg<>(CorfuMsgType.WRONG_EPOCH, serverEpoch));
        log.trace("Incoming message with wrong epoch, got {}, expected {}, message was: {}", msg.getPayload().getEpoch(), serverEpoch, msg);
        return;
    }
    // This is a prepare. If the rank is less than or equal to the phase 1 rank, reject.
    if (phase1Rank != null && prepareRank.lessThanEqualTo(phase1Rank)) {
        log.debug("Rejected phase 1 prepare of rank={}, phase1Rank={}", prepareRank, phase1Rank);
        r.sendResponse(ctx, msg, CorfuMsgType.LAYOUT_PREPARE_REJECT.payloadMsg(new LayoutPrepareResponse(phase1Rank.getRank(), proposedLayout)));
    } else {
        setPhase1Rank(prepareRank);
        log.debug("New phase 1 rank={}", getPhase1Rank());
        r.sendResponse(ctx, msg, CorfuMsgType.LAYOUT_PREPARE_ACK.payloadMsg(new LayoutPrepareResponse(prepareRank.getRank(), proposedLayout)));
    }
}
Also used : Layout(org.corfudb.runtime.view.Layout)

Example 14 with Layout

use of org.corfudb.runtime.view.Layout in project CorfuDB by CorfuDB.

the class CorfuRuntime method fetchLayout.

/**
     * Return a completable future which is guaranteed to contain a layout.
     * This future will continue retrying until it gets a layout. If you need this completable future to fail,
     * you should chain it with a timeout.
     *
     * @return A completable future containing a layout.
     */
private CompletableFuture<Layout> fetchLayout() {
    return CompletableFuture.<Layout>supplyAsync(() -> {
        while (true) {
            List<String> layoutServersCopy = layoutServers.stream().collect(Collectors.toList());
            Collections.shuffle(layoutServersCopy);
            // Iterate through the layout servers, attempting to connect to one
            for (String s : layoutServersCopy) {
                log.debug("Trying connection to layout server {}", s);
                try {
                    IClientRouter router = getRouter(s);
                    // Try to get a layout.
                    CompletableFuture<Layout> layoutFuture = router.getClient(LayoutClient.class).getLayout();
                    // Wait for layout
                    Layout l = layoutFuture.get();
                    l.setRuntime(this);
                    // this.layout should only be assigned to the new layout future once it has been
                    // completely constructed and initialized. For example, assigning this.layout = l
                    // before setting the layout's runtime can result in other threads trying to access a layout
                    // with  a null runtime.
                    //FIXME Synchronization START
                    // We are updating multiple variables and we need the update to be synchronized across all variables.
                    // Since the variable layoutServers is used only locally within the class it is acceptable
                    // (at least the code on 10/13/2016 does not have issues)
                    // but setEpoch of routers needs to be synchronized as those variables are not local.
                    l.getAllServers().stream().map(getRouterFunction).forEach(x -> x.setEpoch(l.getEpoch()));
                    layoutServers = l.getLayoutServers();
                    layout = layoutFuture;
                    //FIXME Synchronization END
                    log.debug("Layout server {} responded with layout {}", s, l);
                    return l;
                } catch (Exception e) {
                    log.warn("Tried to get layout from {} but failed with exception:", s, e);
                }
            }
            log.warn("Couldn't connect to any layout servers, retrying in {}s.", retryRate);
            try {
                Thread.sleep(retryRate * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (isShutdown) {
                return null;
            }
        }
    });
}
Also used : Layout(org.corfudb.runtime.view.Layout)

Example 15 with Layout

use of org.corfudb.runtime.view.Layout in project CorfuDB by CorfuDB.

the class LayoutClientTest method canGetNewLayoutInDifferentEpoch.

@Test
public void canGetNewLayoutInDifferentEpoch() throws Exception {
    Layout l = TestLayoutBuilder.single(SERVERS.PORT_0);
    final long NEW_EPOCH = 42L;
    l.setEpoch(NEW_EPOCH);
    assertThat(client.bootstrapLayout(l).get()).isEqualTo(true);
    assertThat(client.getLayout().get().getEpoch()).isEqualTo(NEW_EPOCH);
}
Also used : Layout(org.corfudb.runtime.view.Layout) Test(org.junit.Test)

Aggregations

Layout (org.corfudb.runtime.view.Layout)44 Test (org.junit.Test)29 CorfuRuntime (org.corfudb.runtime.CorfuRuntime)10 ILogData (org.corfudb.protocols.wireprotocol.ILogData)5 AbstractViewTest (org.corfudb.runtime.view.AbstractViewTest)5 LogData (org.corfudb.protocols.wireprotocol.LogData)4 HashSet (java.util.HashSet)3 ExecutionException (java.util.concurrent.ExecutionException)3 Gson (com.google.gson.Gson)2 GsonBuilder (com.google.gson.GsonBuilder)2 ArrayList (java.util.ArrayList)2 FailureDetectorMsg (org.corfudb.protocols.wireprotocol.FailureDetectorMsg)2 LayoutMsg (org.corfudb.protocols.wireprotocol.LayoutMsg)2 OutrankedException (org.corfudb.runtime.exceptions.OutrankedException)2 com.google.common.collect (com.google.common.collect)1 TypeToken (com.google.common.reflect.TypeToken)1 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)1 ByteBuf (io.netty.buffer.ByteBuf)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 java.lang.invoke (java.lang.invoke)1