internal RedundantEditLogInputStream(ICollection <EditLogInputStream> streams, long startTxId) { this.curIdx = 0; this.prevTxId = (startTxId == HdfsConstants.InvalidTxid) ? HdfsConstants.InvalidTxid : (startTxId - 1); this.state = (streams.IsEmpty()) ? RedundantEditLogInputStream.State.Eof : RedundantEditLogInputStream.State .SkipUntil; this.prevException = null; // EditLogInputStreams in a RedundantEditLogInputStream must be finalized, // and can't be pre-transactional. EditLogInputStream first = null; foreach (EditLogInputStream s in streams) { Preconditions.CheckArgument(s.GetFirstTxId() != HdfsConstants.InvalidTxid, "invalid first txid in stream: %s" , s); Preconditions.CheckArgument(s.GetLastTxId() != HdfsConstants.InvalidTxid, "invalid last txid in stream: %s" , s); if (first == null) { first = s; } else { Preconditions.CheckArgument(s.GetFirstTxId() == first.GetFirstTxId(), "All streams in the RedundantEditLogInputStream must have the same " + "start transaction ID! " + first + " had start txId " + first.GetFirstTxId() + ", but " + s + " had start txId " + s.GetFirstTxId()); } } this.streams = Sharpen.Collections.ToArray(streams, new EditLogInputStream[0]); // We sort the streams here so that the streams that end later come first. Arrays.Sort(this.streams, new _IComparer_117()); }
protected internal override FSEditLogOp NextValidOp() { try { if (state == RedundantEditLogInputStream.State.StreamFailed) { state = RedundantEditLogInputStream.State.StreamFailedResync; } return(NextOp()); } catch (IOException) { return(null); } }
/// <exception cref="System.IO.IOException"/> protected internal override FSEditLogOp NextOp() { while (true) { switch (state) { case RedundantEditLogInputStream.State.SkipUntil: { try { if (prevTxId != HdfsConstants.InvalidTxid) { Log.Info("Fast-forwarding stream '" + streams[curIdx].GetName() + "' to transaction ID " + (prevTxId + 1)); streams[curIdx].SkipUntil(prevTxId + 1); } } catch (IOException e) { prevException = e; state = RedundantEditLogInputStream.State.StreamFailed; } state = RedundantEditLogInputStream.State.Ok; break; } case RedundantEditLogInputStream.State.Ok: { try { FSEditLogOp op = streams[curIdx].ReadOp(); if (op == null) { state = RedundantEditLogInputStream.State.Eof; if (streams[curIdx].GetLastTxId() == prevTxId) { return(null); } else { throw new RedundantEditLogInputStream.PrematureEOFException("got premature end-of-file " + "at txid " + prevTxId + "; expected file to go up to " + streams[curIdx].GetLastTxId ()); } } prevTxId = op.GetTransactionId(); return(op); } catch (IOException e) { prevException = e; state = RedundantEditLogInputStream.State.StreamFailed; } break; } case RedundantEditLogInputStream.State.StreamFailed: { if (curIdx + 1 == streams.Length) { throw prevException; } long oldLast = streams[curIdx].GetLastTxId(); long newLast = streams[curIdx + 1].GetLastTxId(); if (newLast < oldLast) { throw new IOException("We encountered an error reading " + streams[curIdx].GetName () + ". During automatic edit log " + "failover, we noticed that all of the remaining edit log " + "streams are shorter than the current one! The best " + "remaining edit log ends at transaction " + newLast + ", but we thought we could read up to transaction " + oldLast + ". If you continue, metadata will be lost forever!" ); } Log.Error("Got error reading edit log input stream " + streams[curIdx].GetName() + "; failing over to edit log " + streams[curIdx + 1].GetName(), prevException); curIdx++; state = RedundantEditLogInputStream.State.SkipUntil; break; } case RedundantEditLogInputStream.State.StreamFailedResync: { if (curIdx + 1 == streams.Length) { if (prevException is RedundantEditLogInputStream.PrematureEOFException) { // bypass early EOF check state = RedundantEditLogInputStream.State.Eof; } else { streams[curIdx].Resync(); state = RedundantEditLogInputStream.State.SkipUntil; } } else { Log.Error("failing over to edit log " + streams[curIdx + 1].GetName()); curIdx++; state = RedundantEditLogInputStream.State.SkipUntil; } break; } case RedundantEditLogInputStream.State.Eof: { return(null); } } } }