Beispiel #1
0
  /** Test of createTimer method, of class FleaseStage. */
  @Test
  public void testGetState() throws Exception {
    FleaseStage fs =
        new FleaseStage(
            cfg,
            "/tmp/xtreemfs-test/",
            new FleaseMessageSenderInterface() {

              @Override
              public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
                // ignore me
              }
            },
            true,
            new FleaseViewChangeListenerInterface() {

              @Override
              public void viewIdChangeEvent(ASCIIString cellId, int viewId) {}
            },
            new FleaseStatusListener() {

              @Override
              public void statusChanged(ASCIIString cellId, Flease lease) {}

              @Override
              public void leaseFailed(ASCIIString cellId, FleaseException error) {
                fail(error.toString());
              }
            },
            null);

    FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
    msg.setCellId(new ASCIIString("testcell"));

    fs.start();
    fs.waitForStartup();

    FleaseFuture f = fs.openCell(new ASCIIString("testcell"), new ArrayList(), false);
    final AtomicBoolean done = new AtomicBoolean(false);
    f.get();

    Thread.sleep(100);

    Map<ASCIIString, FleaseMessage> m = fs.getLocalState();

    // for (ASCIIString cellId : m.keySet()) {
    // System.out.println("cell "+cellId+" "+m.get(cellId));
    // }

    fs.shutdown();
    fs.waitForShutdown();
  }
Beispiel #2
0
  /** Test of createTimer method, of class FleaseStage. */
  @Test
  public void testCreateTimer() throws Exception {
    FleaseStage fs =
        new FleaseStage(
            cfg,
            "/tmp/xtreemfs-test/",
            new FleaseMessageSenderInterface() {

              @Override
              public void sendMessage(FleaseMessage messages, InetSocketAddress recipient) {
                // ignore me
              }
            },
            true,
            new FleaseViewChangeListenerInterface() {

              @Override
              public void viewIdChangeEvent(ASCIIString cellId, int viewId) {}
            },
            new FleaseStatusListener() {

              @Override
              public void statusChanged(ASCIIString cellId, Flease lease) {
                throw new UnsupportedOperationException("Not supported yet.");
              }

              @Override
              public void leaseFailed(ASCIIString cellId, FleaseException error) {
                throw new UnsupportedOperationException("Not supported yet.");
              }
            },
            null);

    FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
    msg.setCellId(new ASCIIString("testcell"));

    fs.start();
    fs.waitForStartup();
    fs.createTimer(msg, TimeSync.getLocalSystemTime() + 20);
    Thread.sleep(100);
    fs.shutdown();
    fs.waitForShutdown();
  }
  /**
   * Handles paxos learn messages. Removes oudated instances and updates maxLearnedInstId
   * accordingly
   *
   * @param msg incomming message
   */
  public void handleLEARN(FleaseMessage msg) {
    final FleaseAcceptorCell cc = getCell(msg);

    cc.touch();
    if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))
        || (cc.getAccepted() != null) && (cc.getAccepted().after(msg))) {
      if (Logging.isDebug() && config.isDebugPrintMessages())
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A ignore outdated LEARN message " + msg.getProposalNo());
    } else {
      if (Logging.isDebug() && config.isDebugPrintMessages()) {
        final String preped =
            (cc.getPrepared() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getPrepared().getProposalNo().toString();
        final String acced =
            (cc.getAccepted() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getAccepted().getProposalNo()
                    + "="
                    + cc.getAccepted().getLeaseHolder()
                    + "/"
                    + cc.getAccepted().getLeaseTimeout();
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A learn        p:"
                + preped
                + " a: "
                + acced
                + " -> "
                + msg.getProposalNo()
                + "="
                + msg.getLeaseHolder()
                + "/"
                + msg.getLeaseTimeout());
      }

      cc.setAccepted(msg);
      cc.setPrepared(msg);
      cc.setLatestLearn(msg);
      evtListener.learnedEvent(
          msg.getCellId(), msg.getLeaseHolder(), msg.getLeaseTimeout(), msg.getMasterEpochNumber());
    }
  }
Beispiel #4
0
  /** Test of createTimer method, of class FleaseStage. */
  @Test
  public void testOpenAndGetLease() throws Exception {
    final ASCIIString CELL_ID = new ASCIIString("testcell");

    final AtomicReference<Flease> result = new AtomicReference();

    FleaseStage fs =
        new FleaseStage(
            cfg,
            "/tmp/xtreemfs-test/",
            new FleaseMessageSenderInterface() {

              @Override
              public void sendMessage(FleaseMessage message, InetSocketAddress recipient) {
                // ignore me
              }
            },
            true,
            new FleaseViewChangeListenerInterface() {

              @Override
              public void viewIdChangeEvent(ASCIIString cellId, int viewId) {}
            },
            new FleaseStatusListener() {

              @Override
              public void statusChanged(ASCIIString cellId, Flease lease) {
                // System.out.println("state change: "+cellId+" owner="+lease.getLeaseHolder());
                synchronized (result) {
                  result.set(
                      new Flease(
                          cellId,
                          lease.getLeaseHolder(),
                          lease.getLeaseTimeout_ms(),
                          lease.getMasterEpochNumber()));
                  result.notify();
                }
              }

              @Override
              public void leaseFailed(ASCIIString cellId, FleaseException error) {
                fail(error.toString());
              }
            },
            null);

    FleaseMessage msg = new FleaseMessage(FleaseMessage.MsgType.EVENT_RESTART);
    msg.setCellId(CELL_ID);

    fs.start();
    fs.waitForStartup();

    fs.openCell(CELL_ID, new ArrayList(), false);

    synchronized (result) {
      if (result.get() == null) result.wait(1000);
      if (result.get() == null) fail("timeout!");
    }

    assertEquals(result.get().getLeaseHolder(), cfg.getIdentity());

    FleaseFuture f = fs.closeCell(CELL_ID, false);
    f.get();

    Thread.sleep(12000);

    result.set(null);

    fs.openCell(CELL_ID, new ArrayList(), false);

    synchronized (result) {
      if (result.get() == null) result.wait(1000);
      if (result.get() == null) fail("timeout!");
    }

    assertEquals(result.get().getLeaseHolder(), cfg.getIdentity());

    fs.shutdown();
    fs.waitForShutdown();
  }
  /** main loop */
  public FleaseMessage processMessage(FleaseMessage msg) {

    assert (!quit);

    /*if (Logging.isDebug())
    Logging.logMessage(Logging.LEVEL_DEBUG,this,"received %s",msg.toString());*/

    final long now = TimeSync.getLocalSystemTime();
    if (msg.getSendTimestamp() + config.getMessageTimeout() < TimeSync.getGlobalTime()) {
      // old message, ignore
      if (Logging.isDebug() && config.isDebugPrintMessages())
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A outdated message discarded: %s",
            msg.toString());
      return null;
    }
    if (this.waitUntilTimestamp_ms >= now) {
      if (Logging.isDebug() && config.isDebugPrintMessages())
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A message discarded, acceptor is still in recovery period");
      return null;
    }

    assert (msg.getCellId() != null);
    final FleaseAcceptorCell cc = getCell(msg.getCellId());

    if (cc.getViewId() < msg.getViewId()) {
      // If the local view is lower than the delivered one, the view listener has to be informed to
      // update
      // the local view. But the request can still be answered.
      viewListener.viewIdChangeEvent(msg.getCellId(), msg.getViewId());

    } else if (cc.getViewId() > msg.getViewId()
        || (cc.getViewId() == msg.getViewId() && cc.isViewInvalidated())) {
      // If the request is from an older view, or the a view that has been invalidated on this
      // AcceptorCell, the request has to be aborted.
      FleaseMessage response = new FleaseMessage(FleaseMessage.MsgType.MSG_WRONG_VIEW, msg);
      response.setViewId(cc.getViewId());
      return response;
    }

    FleaseMessage response = null;
    if (msg.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE) response = handlePREPARE(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT) response = handleACCEPT(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN) handleLEARN(msg);
    /*else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_GET_LEASE)
        response = handleGETLEASE(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_RENEW_LEASE)
        response = handleRENEWINSTANCE(msg);*/
    else
      Logging.logMessage(
          Logging.LEVEL_ERROR,
          Category.replication,
          this,
          "A invalid message type received: %s",
          msg.toString());

    /*if (Logging.isDebug())
    Logging.logMessage(Logging.LEVEL_DEBUG,this,"response %s",(response != null) ? response.toString() : "<empty>");*/

    return response;
  }
  /**
   * Handles paxos accept (vote) messages.
   *
   * @param msg incomming message
   * @return a response message or null
   */
  public FleaseMessage handleACCEPT(FleaseMessage msg) {

    final FleaseAcceptorCell cc = getCell(msg);

    cc.touch();
    if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) {
      // reject the request
      if (Logging.isDebug() && config.isDebugPrintMessages()) {
        final String preped =
            (cc.getPrepared() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getPrepared().getProposalNo().toString();
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A accept  NACK p:" + preped + " is after " + msg.getProposalNo() + "");
      }
      FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_ACCEPT_NACK, msg);
      tmp.setSendTimestamp(TimeSync.getGlobalTime());
      tmp.setLeaseHolder(null);
      tmp.setLeaseTimeout(0);
      tmp.setPrevProposalNo(cc.getPrepared().getProposalNo());
      return tmp;
    } else {
      // okay accept it
      if (Logging.isDebug() && config.isDebugPrintMessages()) {
        final String preped =
            (cc.getPrepared() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getPrepared().getProposalNo().toString();
        final String acced =
            (cc.getAccepted() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getAccepted().getProposalNo()
                    + "="
                    + cc.getAccepted().getLeaseHolder()
                    + "/"
                    + cc.getAccepted().getLeaseTimeout();
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A accept  ACK  p:"
                + preped
                + " a: "
                + acced
                + " -> "
                + msg.getProposalNo()
                + "="
                + msg.getLeaseHolder()
                + "/"
                + msg.getLeaseTimeout());
      }
      assert (msg.getLeaseHolder() != null);
      cc.setAccepted(msg);
      cc.setPrepared(msg);

      FleaseMessage tmp = new FleaseMessage(FleaseMessage.MsgType.MSG_ACCEPT_ACK, msg);
      tmp.setSendTimestamp(TimeSync.getGlobalTime());
      return tmp;
    }
  }
  /**
   * Handles paxos prepare messages
   *
   * @param msg the incomming message
   * @return a response message
   */
  public FleaseMessage handlePREPARE(FleaseMessage msg) {

    final FleaseAcceptorCell cc = getCell(msg);
    cc.touch();

    if ((cc.getPrepared() != null) && (cc.getPrepared().after(msg))) {
      if (Logging.isDebug() && config.isDebugPrintMessages()) {
        final String preped =
            (cc.getPrepared() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getPrepared().getProposalNo().toString();
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A prepare NACK p:" + preped + " is after " + msg.getProposalNo() + "");
      }
      FleaseMessage reject = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE_NACK, msg);
      reject.setPrevProposalNo(cc.getPrepared().getProposalNo());
      reject.setLeaseHolder(null);
      reject.setLeaseTimeout(0);
      reject.setSendTimestamp(TimeSync.getGlobalTime());
      return reject;
    } else {
      if (Logging.isDebug() && config.isDebugPrintMessages()) {
        final String preped =
            (cc.getPrepared() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getPrepared().getProposalNo().toString();
        final String acced =
            (cc.getAccepted() == null)
                ? ProposalNumber.EMPTY_PROPOSAL_NUMBER.toString()
                : cc.getAccepted().getProposalNo()
                    + "="
                    + cc.getAccepted().getLeaseHolder()
                    + "/"
                    + cc.getAccepted().getLeaseTimeout();
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A prepare ACK  p:" + preped + " -> " + msg.getProposalNo() + " a:" + acced);
      }
      // lastPrepared = msg;
      cc.setPrepared(msg);
      // FIXME:Persistently write to disk
      FleaseMessage response = new FleaseMessage(FleaseMessage.MsgType.MSG_PREPARE_ACK, msg);

      if (cc.getAccepted() != null) {

        response.setPrevProposalNo(cc.getAccepted().getProposalNo());
        response.setLeaseHolder(cc.getAccepted().getLeaseHolder());
        assert (response.getLeaseHolder() != null);
        response.setLeaseTimeout(cc.getAccepted().getLeaseTimeout());
      }
      response.setSendTimestamp(TimeSync.getGlobalTime());
      return response;
    }
  }
 private FleaseAcceptorCell getCell(FleaseMessage msg) {
   assert (msg != null);
   return getCell(msg.getCellId());
 }