接口 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() 必须仅支持那些在调用close()时才显示输出的输出流,例如由S3A文件系统返回的输出流。

前提条件

数据流必须实现 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