<commit_before>var gestalt = require('../lib/gestalt');
var ZooKeeper = require('zookeeper');
var _ = require('underscore');

var config = new gestalt.ConfigContainer();
config.set("config:file", "./central.yaml");

var envMap = new gestalt.RemapConfig( { 
    mapper: {
	"CENTRAL_CONFIG":   "config:file",
	"CENTRAL_ZOOKEEPER":"zookeeper:options:connect",
	"CENTRAL_ELECTION": "zookeeper:election",
	"CENTRAL_NAME":     "zookeeper:names",
	"CENTRAL_CLUSTER":  "cluster:name"
    },
    original: new gestalt.ConfigEnv() 
});

var argsMap = new gestalt.RemapConfig( {					  
    mapper: {
	"config":    "config:file",
	"zookeeper": "zookeeper:options:connect",
	"election" : "zookeeper:election",
	"names":     "zookeeper:names",
	"cluster":   "cluster:name"
    },
    original: new gestalt.ConfigArgs( {
	optimist_options: {
	    z: { alias: 'zookeeper' },
	    c: { alias: 'config' },
	    e: { alias: 'election' },
	    n: { alias: 'names' },
	    C: { alias: 'cluster' }
	}
    })
});

var zookeeper = new gestalt.Configuration(); // Placeholder for zookeeper config to come

// Build the main config object
config.addDefault( zookeeper );
config.addOverride( envMap );
config.addOverride( argsMap );

config.patternListen(/^cluster:name$/, function(change) {
    if(change.value) {
	join_cluster();
    }
});    

config.patternListen(/^zk:children:leader:data$/, function(change) {
    if( change.value ) {
	console.log( change.value, "is now leader.");
    } else {
	console.log("There is no leader.");
    }
});

function election_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:election" );
}

function config_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:config" );
}

function names_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:names" );
}


// Our name in the cluster is stored at cluster:me
config.patternListen(/^cluster:me$/, function(change) {
    if(change.value) {
	var name = change.value;
	console.log( "I am", name );
	var zk_config = config.get("zk");
	// having a name set should indicate that
	// we have a valid zk_config
	if( !zk_config ) {
	    throw new Error("Expected a zk_config");
	}

	zk_config.zookeeper( function(zk) {
	    zk_cast_ballot(zk,election_path(), name, function() {
		// become leader
		console.log("I am leader");		
		zk.a_create( config_path() + "/leader", config.get("cluster:me"), 1, function(rc,err,path) {
		    if(rc) {
			throw new Error("Error becoming leader" + err);
		    }
		});
	    });
	});	
    }
});



//console.log( require.resolve( config.get('config:file')));
var file = new gestalt.ConfigFile( { source: require.resolve( config.get( 'config:file' ) ),
				     watch: true,
				     format: 'yaml'
				   } );


file.on('loaded', on_load_config_file );
file.on('invalid', function(err, source) {
    console.log(err,source);
});
config.addDefault( file );


function on_load_config_file() {
    join_cluster();
}


function join_cluster() {
    // This method currently gets triggered
    // a few times prematurely. We must
    // ensure that there is in fact a cluster name
    // and some names to choose from before we
    // really start to join.
    //
    // Seems to come from a but in the ConfigFile
    // loaded evetn...
    var cluster_name = config.get("cluster:name");
    if( ! cluster_name ) {
	//console.log("missing cluster name.");
	// Maybe we will get one later...
	return;
    }
    var names = config.get("names");
    if( !names ) {
	//console.log("no names to choose from");
	return;
    }

    var zk_config = config.get("zk");
    if( zk_config ) {
	// Clean up old zk_config object
	zk_config.zookeeper( function(zk) { zk.close(); });
    }
    var zk_connect = config.get("zookeeper:options:connect");

    console.log("\nJoining cluster: %s", cluster_name);

    var config_url = zk_connect + config_path();

    // set up zk_config object
    zk_config = new gestalt.ZookeeperConfig({<commit_msg>remember what cluster we are part of<commit_after>var gestalt = require('../lib/gestalt');
var ZooKeeper = require('zookeeper');
var _ = require('underscore');

var config = new gestalt.ConfigContainer();
config.set("config:file", "./central.yaml");

var envMap = new gestalt.RemapConfig( { 
    mapper: {
	"CENTRAL_CONFIG":   "config:file",
	"CENTRAL_ZOOKEEPER":"zookeeper:options:connect",
	"CENTRAL_ELECTION": "zookeeper:election",
	"CENTRAL_NAME":     "zookeeper:names",
	"CENTRAL_CLUSTER":  "cluster:name"
    },
    original: new gestalt.ConfigEnv() 
});

var argsMap = new gestalt.RemapConfig( {					  
    mapper: {
	"config":    "config:file",
	"zookeeper": "zookeeper:options:connect",
	"election" : "zookeeper:election",
	"names":     "zookeeper:names",
	"cluster":   "cluster:name"
    },
    original: new gestalt.ConfigArgs( {
	optimist_options: {
	    z: { alias: 'zookeeper' },
	    c: { alias: 'config' },
	    e: { alias: 'election' },
	    n: { alias: 'names' },
	    C: { alias: 'cluster' }
	}
    })
});

var zookeeper = new gestalt.Configuration(); // Placeholder for zookeeper config to come

// Build the main config object
config.addDefault( zookeeper );
config.addOverride( envMap );
config.addOverride( argsMap );

config.patternListen(/^cluster:name$/, function(change) {
    if(change.value) {
	join_cluster();
    }
});    

config.patternListen(/^zk:children:leader:data$/, function(change) {
    if( change.value ) {
	console.log( change.value, "is now leader.");
    } else {
	console.log("There is no leader.");
    }
});

function election_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:election" );
}

function config_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:config" );
}

function names_path() {
    return "/" + config.get("cluster:name" ) + config.get("zookeeper:names" );
}


// Our name in the cluster is stored at cluster:me
config.patternListen(/^cluster:me$/, function(change) {
    if(change.value) {
	var name = change.value;
	console.log( "I am", name );
	var zk_config = config.get("zk");
	// having a name set should indicate that
	// we have a valid zk_config
	if( !zk_config ) {
	    throw new Error("Expected a zk_config");
	}

	zk_config.zookeeper( function(zk) {
	    zk_cast_ballot(zk,election_path(), name, function() {
		// become leader
		console.log("I am leader");		
		zk.a_create( config_path() + "/leader", config.get("cluster:me"), 1, function(rc,err,path) {
		    if(rc) {
			throw new Error("Error becoming leader" + err);
		    }
		});
	    });
	});	
    }
});



//console.log( require.resolve( config.get('config:file')));
var file = new gestalt.ConfigFile( { source: require.resolve( config.get( 'config:file' ) ),
				     watch: true,
				     format: 'yaml'
				   } );


file.on('loaded', on_load_config_file );
file.on('invalid', function(err, source) {
    console.log(err,source);
});
config.addDefault( file );


function on_load_config_file() {
    join_cluster();
}


// This is the cluster that we are currently
// a member of or trying to become a member of.
var current_cluster;

function join_cluster() {
    // This method currently gets triggered
    // a few time. We must ensure that there is in fact a cluster name
    // and some names to choose from before we really start to join.
    var cluster_name = config.get("cluster:name");
    if( ! cluster_name ) {
	//console.log("missing cluster name.");
	// Maybe we will get one later...
	return;
    }

    var names = config.get("names");
    if( !names ) {
	//console.log("no names to choose from");
	return;
    }

    // If we are already trying to join this cluster, dont
    // start over.
    if( cluster_name == current_cluster ) {
	return;
    }

    // Make it official - we are trying to join a new cluster.
    current_cluster = cluster_name;
    console.log("\nJoining cluster: %s", cluster_name);

    var zk_config = config.get("zk");
    if( zk_config ) {
	// Clean up old zk_config object
	zk_config.zookeeper( function(zk) { zk.close(); });
    }
    var zk_connect = config.get("zookeeper:options:connect");


    var config_url = zk_connect + config_path();

    // set up zk_config object
    zk_config = new gestalt.ZookeeperConfig({
{'fraction_non_alphanumeric': 0.15822631451417493, 'fraction_numerical': 0.000242306760358614, 'mean_word_length': 3.4050160085378867, 'pattern_counts': {'":': 18, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4696565', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2754, 'n_words': 664}