Skip to content
Snippets Groups Projects
timeserver.cc 2.34 KiB
Newer Older
// -*- mode: c++; c-file-style: "k&r"; c-basic-offset: 4 -*-
/***********************************************************************
 *
 * timeserver/timeserver.cc:
 *   Single TimeStamp Server.
 *
 **********************************************************************/

#include "timeserver/timeserver.h"

TimeStampServer::TimeStampServer()
{
    ts = 0;
}

TimeStampServer::~TimeStampServer() { }

string
TimeStampServer::newTimeStamp()
{
    ts++;
    return to_string(ts);
}

void
TimeStampServer::ReplicaUpcall(opnum_t opnum,
                               const string &str1,
                               string &str2)
{
    Debug("Received Upcall: %lu, %s", opnum, str1.c_str());
    // Get a new timestamp from the TimeStampServer
    str2 = newTimeStamp();
}

static void Usage(const char *progName)
{
    fprintf(stderr, "usage: %s -c conf-file -i replica-index\n",
            progName);
    exit(1);
}

int
main(int argc, char **argv)
{
  int index = -1;
  const char *configPath = NULL;

  // Parse arguments
  int opt;
  while ((opt = getopt(argc, argv, "c:i:")) != -1) {
    switch (opt) {
      case 'c':
        configPath = optarg;
        break;

      case 'i':
        {
          char *strtolPtr;
          index = strtoul(optarg, &strtolPtr, 10);
          if ((*optarg == '\0') || (*strtolPtr != '\0') || (index < 0))
          {
            fprintf(stderr,
                "option -i requires a numeric arg\n");
            Usage(argv[0]);
          }
          break;
        }

      default:
        fprintf(stderr, "Unknown argument %s\n", argv[optind]);
        break;
    }
  }

  if (!configPath) {
    fprintf(stderr, "option -c is required\n");
    Usage(argv[0]);
  }

  if (index == -1) {
    fprintf(stderr, "option -i is required\n");
    Usage(argv[0]);
  }

  // Load configuration
  std::ifstream configStream(configPath);
  if (configStream.fail()) {
    fprintf(stderr, "unable to read configuration file: %s\n",
        configPath);
    Usage(argv[0]);
  }
  specpaxos::Configuration config(configStream);

  if (index >= config.n) {
    fprintf(stderr, "replica index %d is out of bounds; "
        "only %d replicas defined\n", index, config.n);
    Usage(argv[0]);
  }

  UDPTransport transport(0.0, 0.0, 0);

  TimeStampServer server;
  specpaxos::vr::VRReplica replica(config, index, &transport, 1, &server);
  
  transport.Run();

  return 0;
}