<commit_before>// Given a set of nodes...
//
// - Overlapping subsets of the nodes participate in 1 or more 'rosters'.
// - We create new rosters sequentially over time whenever we add/remove nodes.
// - A newly created roster eventually takes over from the previous roster.
//
// 'cluster' ------------------------------------< node
// 'cluster' ---< 'roster' ---< roster_member >--- node
//
var assert = require('assert');

exports.open_node = function(node_name, data_dir, conf, storage, comm) {
  var time_start = new Date();
  var log_db     = null;

  console.info('replicake node...')
  console.info('  time-start = ' + time_start.toJSON());
  console.info('  node-name  = ' + node_name);
  console.info('  data-dir   = ' + data_dir);

  var node_state = { curr: 'opening' }; // A replicake node has a state machine.

  on_transition(node_state, 'opening', 'warming',
                function() {
                  storage.open(data_dir, node_name, conf.get('log_db'),
                               function(err, log_db_in) {
                                 assert(log_db == null, 'log_db should be null');
                                 log_db = log_db_in;
                                 go(node_state, 'running');
                               });
                });

  on_transition(node_state, 'warming', 'running',
                function() {
                  assert(log_db);

                  broadcast();

                  // Concurrently...
                  // -- find and/or help choose leader
                  // -- start paxos participation / log replica
                  // -- continually catchup on log holes
                  // -- help others catchup on log holes
                  // -- apply fully received log entries
                  // -- take local snapshots
                  // -- garbage collect old log entries
                  // -- handle roster changes
                });

  on_transition(node_state, 'running', 'paused', function() { assert(log_db); });
  on_transition(node_state, 'paused', 'running', function() { assert(log_db); });

  on_transition(node_state, 'running', 'cooling', cool);
  on_transition(node_state, 'warming', 'cooling', cool);
  on_transition(node_state, 'cooling', 'closed', function() { assert(!log_db); });

  function cool() {
    assert(log_db);
    log_db.save(function() {
        log_db.close();
        log_db = null;
        go(node_state, 'closed');
      });
  }

  // A roster_member object represents the participation of this node
  // in a given roster (or roster_id).  This node can participate in
  // multiple rosters at the same time; hence, we can have multiple
  // roster_member objects per node.
  //
  var roster_member_map = {}; // Keys = roster_id; values = roster_member objects.
  var max_defunct_roster_member_id = null;

  function load_roster_member(roster_id) {
    return mk_roster_member(roster_id, null).load();
  }
  function create_roster_member(roster_id, start_slot_id, members) {
    return mk_roster_member(roster_id).create(start_slot_id, members);
  }

  function mk_roster_member(roster_id) {
    var data = { start_slot_id: null,
                 members: null };

    assert(roster_member_map[roster_id] == null);

    // A roster_member has a state machine.
    var roster_member_state = { curr: 'start' };
    var finished_bcast = null;

    on_transition(roster_member_state, 'start', 'creating',
                  function() {
                    assert(data.start_slot_id != null && data.members != null);
                    storage.add(roster_id, data,
                                function(err) {
                                  if (!err) {
                                    go(roster_member_state, 'warming');
                                  } else {
                                    assert(false, "TODO");
                                  }
                                });
                  });
    on_transition(roster_member_state, 'start', 'loading',
                  function() {
                    storage.load(roster_id,
                                 function(err, in_data) {
                                   if (!err && in_data) {
                                     assert(data.start_slot_id == null && data.members == null);
                                     data = in_data;
                                     assert(data.start_slot_id != null && data.members != null);
                                     go(roster_member_state, 'warming');
                                   } else {
                                     assert(false, "TODO");
                                   }
                                 });
                  });
    on_transition(roster_member_state, 'creating', 'warming',
                  function() { need_starting_state(roster_id); });
    on_transition(roster_member_state, 'loading', 'warming',
                  function() { need_starting_state(roster_id); });
    on_transition(roster_member_state, 'warming', 'finished',
                  function() {
                    if (last_checkpoint_slot_id(storage, roster_id) >= start_slot_id) {
                      go(roster_member_state, 'running');
                    } else {
                      need_starting_state(roster_id);
                    }
                  });
    on_transition(roster_member_state, 'warming', 'running', todo);
    on_transition(roster_member_state, 'running', 'cooling', todo);
    on_transition(roster_member_state, 'cooling', 'last_entry_executed',
                  function () {
                    go(roster_member_state, 'finished');
                  });
    on_transition(roster_member_state, 'last_entry_executed', 'finished',
                  function () {
                    assert(finished_bcast == null);
                    finished_cast = bcast_periodically('finished');
                  });
    on_transition(roster_member_state, 'finished', 'defunct',
                  function () {
                    assert(finished_bcast);
                    finished_bcast.stop();
                    finished_bcast = null;
                  });

    var roster_member = roster_member_map[roster_id] = {
      'load':  function() {
        go(roster_member_state, 'loading')
        return roster_member;
      },<commit_msg>Using finished instead of last_entry_executed.<commit_after>// Given a set of nodes...
//
// - Overlapping subsets of the nodes participate in 1 or more 'rosters'.
// - We create new rosters sequentially over time whenever we add/remove nodes.
// - A newly created roster eventually takes over from the previous roster.
//
// 'cluster' ------------------------------------< node
// 'cluster' ---< 'roster' ---< roster_member >--- node
//
var assert = require('assert');

exports.open_node = function(node_name, data_dir, conf, storage, comm) {
  var time_start = new Date();
  var log_db     = null;

  console.info('replicake node...')
  console.info('  time-start = ' + time_start.toJSON());
  console.info('  node-name  = ' + node_name);
  console.info('  data-dir   = ' + data_dir);

  var node_state = { curr: 'opening' }; // A replicake node has a state machine.

  on_transition(node_state, 'opening', 'warming',
                function() {
                  storage.open(data_dir, node_name, conf.get('log_db'),
                               function(err, log_db_in) {
                                 assert(log_db == null, 'log_db should be null');
                                 log_db = log_db_in;
                                 go(node_state, 'running');
                               });
                });

  on_transition(node_state, 'warming', 'running',
                function() {
                  assert(log_db);

                  broadcast();

                  // Concurrently...
                  // -- find and/or help choose leader
                  // -- start paxos participation / log replica
                  // -- continually catchup on log holes
                  // -- help others catchup on log holes
                  // -- apply fully received log entries
                  // -- take local snapshots
                  // -- garbage collect old log entries
                  // -- handle roster changes
                });

  on_transition(node_state, 'running', 'paused', function() { assert(log_db); });
  on_transition(node_state, 'paused', 'running', function() { assert(log_db); });

  on_transition(node_state, 'running', 'cooling', cool);
  on_transition(node_state, 'warming', 'cooling', cool);
  on_transition(node_state, 'cooling', 'closed', function() { assert(!log_db); });

  function cool() {
    assert(log_db);
    log_db.save(function() {
        log_db.close();
        log_db = null;
        go(node_state, 'closed');
      });
  }

  // A roster_member object represents the participation of this node
  // in a given roster (or roster_id).  This node can participate in
  // multiple rosters at the same time; hence, we can have multiple
  // roster_member objects per node.
  //
  var roster_member_map = {}; // Keys = roster_id; values = roster_member objects.
  var max_defunct_roster_member_id = null;

  function load_roster_member(roster_id) {
    return mk_roster_member(roster_id, null).load();
  }
  function create_roster_member(roster_id, start_slot_id, members) {
    return mk_roster_member(roster_id).create(start_slot_id, members);
  }

  function mk_roster_member(roster_id) {
    var data = { start_slot_id: null,
                 members: null };

    assert(roster_member_map[roster_id] == null);

    // A roster_member has a state machine.
    var roster_member_state = { curr: 'start' };
    var finished_bcast = null;

    on_transition(roster_member_state, 'start', 'creating',
                  function() {
                    assert(data.start_slot_id != null && data.members != null);
                    storage.create(roster_id, data,
                                   function(err) {
                                     if (!err) {
                                       go(roster_member_state, 'opening');
                                     } else {
                                       assert(false, "TODO");
                                     }
                                   });
                  });

    on_transition(roster_member_state, 'start',    'opening', open);
    on_transition(roster_member_state, 'creating', 'opening', open);
    
    function open() {
      storage.open(roster_id,
                   function(err, in_data) {
                     if (!err && in_data) {
                       assert(data.start_slot_id == null && data.members == null);
                       data = in_data;
                       assert(data.start_slot_id != null && data.members != null);
                       go(roster_member_state, 'running');
                     } else {
                       assert(false, "TODO");
                     }
                   });
    }

    on_transition(roster_member_state, 'opening', 'running', todo);

    on_transition(roster_member_state, 'running', 'finishing', // Last entry executed.
                  function () {
                    go(roster_member_state, 'finished');
                  });
    on_transition(roster_member_state, 'finishing', 'finished',
                  function () {
                    assert(finished_bcast == null);
                    finished_cast = bcast_periodically('finished');
                  });
    on_transition(roster_member_state, 'finished', 'defunct',
                  function () {
                    assert(finished_bcast);
                    finished_bcast.stop();
                    finished_bcast = null;
                  });

    var roster_member = roster_member_map[roster_id] = {
      'load':  function() {
        go(roster_member_state, 'loading')
        return roster_member;
      },
{'fraction_non_alphanumeric': 0.11872069658405894, 'fraction_numerical': 0.00016744809109176155, 'mean_word_length': 1.5922309027777777, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '50613', 'n_tokens_mistral': 3323, 'n_tokens_neox': 3103, 'n_words': 711}