All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.gondola.Gondola Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015, Yahoo Inc.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */
package com.yahoo.gondola;

import com.yahoo.gondola.core.CoreCmd;
import com.yahoo.gondola.core.CoreMember;
import com.yahoo.gondola.core.Message;
import com.yahoo.gondola.core.MessagePool;
import com.yahoo.gondola.core.Peer;
import com.yahoo.gondola.core.Stats;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.management.MBeanServer;
import javax.management.ObjectName;

/**
 * Usage to commit a command:
 * Config config = Config.fromFile(confFile));
 * Gondola gondola = new Gondola(config, hostId);
 * Cluster cluster = gondola.getCluster(clusterId);
 * Command command = cluster.checkoutCommand();
 * byte[] buffer = new byte[]{0, 1, 2, 3}; // some data to commit
 * // Blocks until command has been committed
 * command.commit(buffer, 0, buffer.length);
 * 

* Usage to get a committed command: * // Blocks until command at index 500 has been committed * Command command = cluster.getCommittedCommand(500); */ public class Gondola implements Stoppable { final static Logger logger = LoggerFactory.getLogger(Gondola.class); final Config config; final String hostId; final Stats stats = new Stats(); final MessagePool messagePool; final Clock clock; final Network network; final Storage storage; // Get the pid of this process final String processId = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; List clusters = new ArrayList(); Map clusterMap = new HashMap<>(); Map memberMap = new HashMap<>(); Observable roleChangeObservable = new Observable() { @Override public void notifyObservers(Object arg) { super.setChanged(); super.notifyObservers(arg); } }; // Change events are done by a separate thread, to avoid delaying the gondola timeouts. // This queue is used to deliver the change events to the thread. BlockingQueue roleChangeEventQueue = new LinkedBlockingQueue<>(); // List of threads running in this class List threads = new ArrayList<>(); static MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); /** * @param hostId the non-null id of the current host on which to start Gondola. */ public Gondola(Config config, String hostId) throws Exception { this.config = config; this.hostId = hostId; logger.info("------- Gondola init: {}, {}, pid={} -------", hostId, config.getAddressForHost(hostId), processId); // Mbean ObjectName objectName = new ObjectName("com.yahoo.gondola." + hostId + ":type=Stats"); mbs.registerMBean(stats, objectName); // Initialize static config values CoreCmd.initConfig(config); Message.initConfig(config); Peer.initConfig(config); messagePool = new MessagePool(config, stats); // Create implementations String clockClassName = config.get(config.get("clock.impl") + ".class"); clock = (Clock) Class.forName(clockClassName).getConstructor(Gondola.class, String.class) .newInstance(this, hostId); String networkClassName = config.get(config.get("network.impl") + ".class"); network = (Network) Class.forName(networkClassName).getConstructor(Gondola.class, String.class) .newInstance(this, hostId); String storageClassName = config.get(config.get("storage.impl") + ".class"); storage = (Storage) Class.forName(storageClassName).getConstructor(Gondola.class, String.class) .newInstance(this, hostId); // Create the clusters running on a host List clusterIds = config.getClusterIds(hostId); for (String clusterId : clusterIds) { Cluster cluster = new Cluster(this, clusterId); clusters.add(cluster); clusterMap.put(clusterId, cluster); } } public void start() throws Exception { logger.info("Starting up Gondola..."); clock.start(); network.start(); storage.start(); for (Cluster c : clusters) { c.start(); } // Start local threads assert threads.size() == 0; threads.add(new RoleChangeNotifier()); threads.forEach(t -> t.start()); } public void stop() { logger.info("Shutting down Gondola..."); // Shut down all local threads threads.forEach(t -> t.interrupt()); for (Thread t : threads) { try { t.join(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } threads.clear(); // Shut down threads in all dependencies clusters.forEach(Cluster::stop); storage.stop(); network.stop(); clock.stop(); } /******************** methods *********************/ public String getHostId() { return hostId; } public String getProcessId() { return processId; } /** * Returns the clusters that reside on the host as specified in the constructor. * * @return non-null list of clusters. * @throw IllegalArgumentException if host is not found */ public List getClustersOnHost() { return clusters; } public Cluster getCluster(String id) { return clusterMap.get(id); } Cluster get(String id) { return clusterMap.get(id); } public Storage getStorage() { return storage; } public Config getConfig() { return config; } public MessagePool getMessagePool() { return messagePool; } public Clock getClock() { return clock; } public Network getNetwork() { return network; } public Stats getStats() { return stats; } public void registerForRoleChanges(Observer observer) { roleChangeObservable.addObserver(observer); } public void unregisterForRoleChanges(Observer observer) { roleChangeObservable.deleteObserver(observer); } public void notifyRoleChange(RoleChangeEvent evt) { roleChangeEventQueue.add(evt); } class RoleChangeNotifier extends Thread { public void run() { while (true) { try { RoleChangeEvent evt = roleChangeEventQueue.take(); roleChangeObservable.notifyObservers(evt); } catch (InterruptedException e) { return; } catch (Exception e) { logger.error(e.getMessage(), e); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy