All Downloads are FREE. Search and download functionalities are using the official Maven repository.

wvlet.airframe.control.Resource.scala Maven / Gradle / Ivy

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wvlet.airframe.control

import java.io.File
import scala.concurrent.{ExecutionContext, Future}

/**
  * Resource that can be closed.
  * @tparam A
  */
trait Resource[A] extends AutoCloseable {
  def get: A
  def close(): Unit

  /**
    * Use the resource within the limited scope. After existing the scope, the resource will be closed
    * @param body
    * @tparam U
    * @return
    */
  def use[U](body: A => U): U = {
    try {
      body(get)
    } finally {
      close()
    }
  }

  /**
    * Wrap a Future with this resource. After the future completes, the resource will be closed
    */
  def wrapFuture[U](body: A => Future[U])(implicit ec: ExecutionContext): Future[U] = {
    Future
      .apply(get)
      .flatMap { (a: A) => body(a) }
      .transform { case any =>
        Control.closeSafely(any, () => close())
      }
  }
}

object Resource {

  /**
    * Create a resource for a temporary file, which will be deleted after closing the resource
    * @param name
    * @param suffix
    * @param dir
    * @return
    */
  def newTempFile(name: String, suffix: String = ".tmp", dir: String = "target"): Resource[File] = newResource[File](
    resource = {
      new File(dir)
      // Create the target directory if not exists
      val d = new File(dir)
      d.mkdirs()
      File.createTempFile(name, suffix, d)
    },
    onClose = { (file: File) =>
      file.delete
    }
  )

  /**
    * Create a new Resource from an AutoClosable object
    * @param resource
    * @tparam R
    * @return
    */
  def newResource[R](
      resource: R,
      onInit: R => Unit = { (x: R) => },
      onClose: R => Unit
  ): Resource[R] = {
    new Resource[R] {
      onInit(resource)
      override def get: R = resource
      override def close(): Unit = {
        onClose(resource)
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy