/// <summary> /// Returns the next batch of events in the stream or null if no new /// batches are currently available. /// </summary> /// <exception cref="System.IO.IOException"> /// because of network error or edit log /// corruption. Also possible if JournalNodes are unresponsive in the /// QJM setting (even one unresponsive JournalNode is enough in rare cases), /// so catching this exception and retrying at least a few times is /// recommended. /// </exception> /// <exception cref="Org.Apache.Hadoop.Hdfs.Inotify.MissingEventsException"> /// if we cannot return the next batch in the /// stream because the data for the events (and possibly some subsequent /// events) has been deleted (generally because this stream is a very large /// number of transactions behind the current state of the NameNode). It is /// safe to continue reading from the stream after this exception is thrown /// The next available batch of events will be returned. /// </exception> public virtual EventBatch Poll() { TraceScope scope = Trace.StartSpan("inotifyPoll", traceSampler); try { // need to keep retrying until the NN sends us the latest committed txid if (lastReadTxid == -1) { Log.Debug("poll(): lastReadTxid is -1, reading current txid from NN"); lastReadTxid = namenode.GetCurrentEditLogTxid(); return(null); } if (!it.HasNext()) { EventBatchList el = namenode.GetEditsFromTxid(lastReadTxid + 1); if (el.GetLastTxid() != -1) { // we only want to set syncTxid when we were actually able to read some // edits on the NN -- otherwise it will seem like edits are being // generated faster than we can read them when the problem is really // that we are temporarily unable to read edits syncTxid = el.GetSyncTxid(); it = el.GetBatches().GetEnumerator(); long formerLastReadTxid = lastReadTxid; lastReadTxid = el.GetLastTxid(); if (el.GetFirstTxid() != formerLastReadTxid + 1) { throw new MissingEventsException(formerLastReadTxid + 1, el.GetFirstTxid()); } } else { Log.Debug("poll(): read no edits from the NN when requesting edits " + "after txid {}" , lastReadTxid); return(null); } } if (it.HasNext()) { // can be empty if el.getLastTxid != -1 but none of the // newly seen edit log ops actually got converted to events return(it.Next()); } else { return(null); } } finally { scope.Close(); } }