c5db.replication.C5GeneralizedReplicationService.java Source code

Java tutorial

Introduction

Here is the source code for c5db.replication.C5GeneralizedReplicationService.java

Source

/*
 * Copyright 2014 WANdisco
 *
 *  WANdisco licenses this file to you under the Apache License,
 *  version 2.0 (the "License"); you may not use this file except in compliance
 *  with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *  License for the specific language governing permissions and limitations
 *  under the License.
 */

package c5db.replication;

import c5db.interfaces.GeneralizedReplicationService;
import c5db.interfaces.LogModule;
import c5db.interfaces.ReplicationModule;
import c5db.interfaces.log.Reader;
import c5db.interfaces.replication.GeneralizedReplicator;
import c5db.interfaces.replication.Replicator;
import c5db.interfaces.replication.ReplicatorEntry;
import c5db.log.OLogToReplicatorEntryCodec;
import c5db.util.FiberSupplier;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.jetlang.core.Disposable;
import org.jetlang.fibers.Fiber;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

/**
 * A GeneralizedReplicationService implementing a variation of the Raft algorithm; internally
 * it bundles a ReplicationModule and a LogModule (based on OLog). This class just wraps
 * the modules, and doesn't do any lifecycle management; it assumes they are started elsewhere
 * and have finished starting up before any of the GeneralizedReplicationService methods are called.
 */
public class C5GeneralizedReplicationService implements GeneralizedReplicationService {

    private final FiberSupplier fiberSupplier;
    private final Fiber fiber;
    private final LogModule logModule;
    private final ReplicationModule replicationModule;

    private final List<Disposable> disposables = new ArrayList<>();

    public C5GeneralizedReplicationService(ReplicationModule replicationModule, LogModule logModule,
            FiberSupplier fiberSupplier) {

        this.replicationModule = replicationModule;
        this.logModule = logModule;
        this.fiberSupplier = fiberSupplier;

        fiber = fiberSupplier.getNewFiber(this::notifyFailed);
        fiber.start();
    }

    @Override
    public ListenableFuture<GeneralizedReplicator> createReplicator(String quorumId, Collection<Long> peerIds) {
        return Futures.transform(replicationModule.createReplicator(quorumId, peerIds), (Replicator replicator) -> {
            return new C5GeneralizedReplicator(replicator, createAndStartFiber(this::notifyFailed));
        });
    }

    @Override
    public Reader<ReplicatorEntry> getLogReader(String quorumId) {
        return logModule.getLogReader(quorumId, new OLogToReplicatorEntryCodec());
    }

    public void dispose() {
        fiber.dispose();
        disposables.forEach(Disposable::dispose);
    }

    private Fiber createAndStartFiber(Consumer<Throwable> throwableConsumer) {
        Fiber newFiber = fiberSupplier.getNewFiber(throwableConsumer);
        fiber.execute(() -> disposables.add(newFiber));
        newFiber.start();
        return newFiber;
    }

    private void notifyFailed(Throwable throwable) {
        // TODO log and/or propagate the exception
    }
}