protected QueueState checkQueueState() {
    QueueState newState = QueueState.UNBLOCKED;
    AbstractTransaction ts = super.peek();
    if (ts == null) {
      if (t) LOG.trace(String.format("Partition %d :: Queue is empty.", this.partitionId));
      newState = QueueState.BLOCKED_EMPTY;
    }
    // Check whether can unblock now
    else if (ts == this.nextTxn && this.state != QueueState.UNBLOCKED) {
      if (EstTime.currentTimeMillis() < this.blockTime) {
        newState = QueueState.BLOCKED_SAFETY;
      } else if (d) {
        LOG.debug(
            String.format(
                "Partition %d :: Wait time for %s has passed. Unblocking...",
                this.partitionId, this.nextTxn));
      }
    }
    // This is a new txn and we should wait...
    else if (this.nextTxn != ts) {
      long txnTimestamp =
          TransactionIdManager.getTimestampFromTransactionId(ts.getTransactionId().longValue());
      long timestamp = EstTime.currentTimeMillis();
      long waitTime = Math.max(0, this.waitTime - (timestamp - txnTimestamp));
      newState = (waitTime > 0 ? QueueState.BLOCKED_SAFETY : QueueState.UNBLOCKED);
      this.blockTime = timestamp + waitTime;
      this.nextTxn = ts;

      if (d) {
        String debug = "";
        if (t) {
          Map<String, Object> m = new LinkedHashMap<String, Object>();
          m.put("Txn Init Timestamp", txnTimestamp);
          m.put("Current Timestamp", timestamp);
          m.put("Block Time Remaining", (this.blockTime - timestamp));
          debug = "\n" + StringUtil.formatMaps(m);
        }
        LOG.debug(
            String.format(
                "Partition %d :: Blocking %s for %d ms [maxWait=%d]%s",
                this.partitionId, ts, (this.blockTime - timestamp), this.waitTime, debug));
      }
    }

    if (newState != this.state) {
      this.state = newState;
      if (d)
        LOG.debug(
            String.format(
                "Partition %d :: State:%s / NextTxn:%s",
                this.partitionId, this.state, this.nextTxn));
    }
    return this.state;
  }
  /** Only return transaction state objects that are ready to run. */
  @Override
  public AbstractTransaction poll() {
    AbstractTransaction retval = null;

    // These invocations of poll() can return null if the next
    // txn was speculatively executed
    if (this.nextTxn == null) this.checkQueueState();

    if (this.state == QueueState.BLOCKED_SAFETY) {
      if (EstTime.currentTimeMillis() >= this.blockTime) {
        retval = super.poll();
      }
    } else if (this.state == QueueState.UNBLOCKED) {
      //            assert(checkQueueState() == QueueState.UNBLOCKED);
      retval = super.poll();
    }
    if (retval != null) {
      assert (this.nextTxn.equals(retval))
          : String.format(
              "Partition %d :: Next txn is %s but our poll returned %s\n"
                  + StringUtil.SINGLE_LINE
                  + "%s",
              this.partitionId,
              this.nextTxn,
              retval,
              this.debug());
      this.nextTxn = null;
      this.lastTxnPopped = retval.getTransactionId();
    }

    if (d && retval != null)
      LOG.debug(String.format("Partition %d :: poll() -> %s", this.partitionId, retval));
    this.checkQueueState();
    return retval;
  }
 public String debug() {
   Map<String, Object> m = new LinkedHashMap<String, Object>();
   m.put("PartitionId", this.partitionId);
   m.put("# of Elements", this.size());
   m.put("Wait Time", this.waitTime);
   m.put("Next Time Remaining", Math.max(0, EstTime.currentTimeMillis() - this.blockTime));
   m.put("Next Txn", this.nextTxn);
   m.put("Last Popped Txn", this.lastTxnPopped);
   m.put("Last Seen Txn", this.lastSeenTxn);
   return (StringUtil.formatMaps(m));
 }
  @Override
  public void remoteHandler(
      RpcController controller,
      TransactionMapRequest request,
      RpcCallback<TransactionMapResponse> callback) {
    assert (request.hasTransactionId())
        : "Got " + request.getClass().getSimpleName() + " without a txn id!";
    Long txn_id = Long.valueOf(request.getTransactionId());
    if (debug.val)
      LOG.debug(String.format("Got %s for txn #%d", request.getClass().getSimpleName(), txn_id));

    // The mr_ts handle will be null if this HStoreSite is not where the
    // base partition for the original MRTransaction
    MapReduceTransaction mr_ts = hstore_site.getTransaction(txn_id);
    if (mr_ts == null) {
      mr_ts =
          hstore_site
              .getTransactionInitializer()
              .createMapReduceTransaction(
                  txn_id,
                  EstTime.currentTimeMillis(),
                  request.getClientHandle(),
                  request.getBasePartition(),
                  request.getProcedureId(),
                  request.getParams().asReadOnlyByteBuffer());
    }
    assert (mr_ts.isMapPhase());
    mr_ts.initTransactionMapWrapperCallback(callback);

    /*
     * Here we would like to start MapReduce Transaction on the remote partition except the base partition of it.
     * This is to avoid the double invoke for remote task.
     * */
    for (int partition : hstore_site.getLocalPartitionIds()) {
      if (partition != mr_ts.getBasePartition()) {
        LocalTransaction ts = mr_ts.getLocalTransaction(partition);
        hstore_site.transactionStart(ts);
      }
    } // FOR
  }
Ejemplo n.º 5
0
 protected FixedEstimatorState(CatalogContext catalogContext, Long txn_id, int base_partition) {
   super(catalogContext);
   this.init(txn_id, base_partition, EstTime.currentTimeMillis());
 }