org.corfudb.infrastructure.SimpleSequencerServer.java Source code

Java tutorial

Introduction

Here is the source code for org.corfudb.infrastructure.SimpleSequencerServer.java

Source

/**
 *
 * Licensed 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 org.corfudb.infrastructure;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;

import lombok.Getter;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TFastFramedTransport;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.corfudb.infrastructure.thrift.SimpleSequencerService;

import java.util.Map;

public class SimpleSequencerServer implements SimpleSequencerService.Iface, ICorfuDBServer {

    private int port = 0;
    private Logger log = LoggerFactory.getLogger(SimpleSequencerServer.class);
    @Getter
    Thread thread;
    boolean running;
    TServer server;
    AtomicLong pos = new AtomicLong(0);
    boolean simFailure;

    @Override
    public long nextpos(int range) throws TException {
        // if (pos % 10000 == 0) System.out.println("issue token " + pos + "...");
        if (simFailure) {
            throw new TException("Simulated failure mode!");
        }
        long ret = pos.getAndAdd(range);
        return ret;
    }

    @Override
    public void reset() throws TException {
        log.info("Reset requested, setting sequence to 0");
        simFailure = false;
        pos = new AtomicLong(0);
    }

    @Override
    public void recover(long lowbound) throws TException {
        if (simFailure) {
            throw new TException("Simulated failure mode!");
        }
        pos.set(lowbound);
    }

    @Override
    public boolean ping() throws TException {
        if (simFailure) {
            throw new TException("Simulated failure mode!");
        }
        return true;
    }

    public ICorfuDBServer getInstance(final Map<String, Object> config) {
        final SimpleSequencerServer st = this;
        st.port = (Integer) config.get("port");
        thread = new Thread(this);
        return this;
    }

    @Override
    public void close() {
        running = false;
        server.stop();
    }

    @Override
    public void simulateFailure(boolean fail, long length) throws TException {
        if (fail && length != -1) {
            this.simFailure = true;
            final SimpleSequencerServer t = this;
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    t.simFailure = false;
                }
            }, length);
        } else {
            this.simFailure = fail;
        }
    }

    public void serverloop() {
        TServerSocket serverTransport;
        SimpleSequencerService.Processor<SimpleSequencerServer> processor;
        log.debug("Simple sequencer entering service loop.");
        try {
            serverTransport = new TServerSocket(port);
            processor = new SimpleSequencerService.Processor<SimpleSequencerServer>(this);
            server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor)
                    .protocolFactory(TCompactProtocol::new)
                    .inputTransportFactory(new TFastFramedTransport.Factory())
                    .outputTransportFactory(new TFastFramedTransport.Factory()));
            log.info("Simple sequencer starting on port " + port);
            server.serve();
        } catch (TTransportException e) {
            log.warn("SimpleSequencer encountered exception, restarting.", e);
        }
    }

    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        running = true;
        while (running) {
            this.serverloop();
        }
    }
}