インターフェース org.apache.hadoop.fs.Abortable

出力を表示しないように、アクティブな操作を中止します。

特に、出力ストリームでサポートされている場合、成功したabort()は、close()操作でストリームが表示されないことを保証する必要があります。

@InterfaceAudience.Public
@InterfaceStability.Unstable
public interface Abortable {

  /**
   * Abort the active operation without the output becoming visible.
   *
   * This is to provide ability to cancel the write on stream; once
   * a stream is aborted, the write MUST NOT become visible.
   *
   * @throws UnsupportedOperationException if the operation is not supported.
   * @return the result.
   */
  AbortableResult abort();

  /**
   * Interface for the result of aborts; allows subclasses to extend
   * (IOStatistics etc) or for future enhancements if ever needed.
   */
  interface AbortableResult {

    /**
     * Was the stream already closed/aborted?
     * @return true if a close/abort operation had already
     * taken place.
     */
    boolean alreadyClosed();

    /**
     * Any exception caught during cleanup operations,
     * exceptions whose raising/catching does not change
     * the semantics of the abort.
     * @return an exception or null.
     */
    IOException anyCleanupException();
  }
}

メソッドabort()

進行中の操作を中止し、操作が完了したときに、出力が可視にならないようにします。

他のファイルシステムクラスがAbortableを実装するまでは、このインターフェースは出力ストリームのみを対象として指定されます。

出力ストリームでのメソッドabort()

Abortable.abort()は、例えばS3Aファイルシステムによって返される出力ストリームのように、close()が呼び出されたときにのみ出力が表示される出力ストリームでのみサポートする必要があります。

事前条件

ストリームは、AbortableStreamCapabilitiesを実装する必要があります。

 if unsupported:
  throw UnsupportedException

if not isOpen(stream):
  no-op

StreamCapabilities.hasCapability("fs.capability.outputstream.abortable") == True

事後条件

abort()が返された後、ファイルシステムは変更されていない必要があります。

FS' = FS

成功したabort()操作は、ストリームclose()が呼び出されたときに、出力が表示されないことを保証する必要があります。

  • ストリームは、アボートの結果を強制するために必要なリモート呼び出しを再試行する必要があります。
  • 宛先パスにファイルが存在する場合、そのファイルは変更されないままである必要があります。

厳密に言えば

Abortable.abort()UnsupportedOperationExceptionを発生させずに返される場合、書き込みは表示されず、宛先パスのファイルシステム内の既存のデータは引き続き利用可能であることを保証します。

  1. write()メソッドの呼び出しは失敗する必要があります。
  2. flush()の呼び出しは、何もしない必要があります(アプリケーションは、クローズされたストリームでこれを呼び出すことがあります)。
  3. 後続のabort()の呼び出しは、何もしない必要があります。
  4. close()は、ファイルを表示してはいけません。また、例外を発生させてはいけません。

つまり、close()の事後条件は次のようになります

FS' = FS

クリーンアップ

  • 一時データがローカルファイルシステムまたはストアのアップロードインフラストラクチャに保存されている場合、これはクリーンアップされる場合があります。ここでは、最善の努力が期待されます。

  • ストリームはクリーンアップ操作を再試行しないでください。そこでの失敗はすべてキャッチされ、AbortResultに追加される必要があります。

返されるAbortResult

返されるAbortResultの値は、主にテストとロギング用です。

alreadyClosed(): 書き込みがすでに中止またはクローズされている場合は、trueを返す必要があります。

anyCleanupException();: オプションのクリーンアップ操作中に発生したIOExceptionを返す必要があります。

スレッドセーフと原子性

出力ストリーム自体は、正式にはスレッドセーフである必要はありませんが、アプリケーションが時々そうであると仮定するため、この呼び出しはスレッドセーフである必要があります。

パス/ストリーム機能「fs.capability.outputstream.abortable」

アプリケーションは、実際に呼び出すことなく、ストリームがAbortable.abort()操作をサポートしていることを検証できる必要があります。これは、StreamCapabilitiesインターフェースを介して行われます。

  1. ストリームインスタンスがAbortableをサポートしている場合は、プローブhasCapability("fs.capability.outputstream.abortable")trueを返す必要があります。

  2. ストリームインスタンスがAbortableをサポートしていない場合は、プローブhasCapability("fs.capability.outputstream.abortable")falseを返す必要があります。

つまり、ストリームがその機能のサポートを宣言した場合、abort()の呼び出しは、操作の定義されたセマンティクスを満たす必要があります。

FileSystem/FileContextの実装は、アプリケーションが宛先ディレクトリ/パスの機能をプローブできるように、同様にサポートを宣言する必要があります。

ファイルシステムがパスPの下でAbortableをサポートしている場合、PathCababilities.hasPathCapability(path, "fs.capability.outputstream.abortable")に対してtrueを返す必要があります。これは、ストアがこの機能をサポートしていることをアプリケーションが検証できるようにするためです。

ファイルシステムがパスPの下でAbortableをサポートしていない場合、PathCababilities.hasPathCapability(path, "fs.capability.outputstream.abortable")に対してfalseを返す必要があります。