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

org.http4s.client.jdkhttpclient.package.scala Maven / Gradle / Ivy

/*
 * Copyright 2021 http4s.org
 *
 * 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 org.http4s.client

import java.util.concurrent.CancellationException
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionException

import cats.effect._
import cats.syntax.all._

package object jdkhttpclient {

  /** Convert a [[java.util.concurrent.CompletableFuture]] into an effect type.
    *
    * If the effect type terminates in cancellation or error, the underlying
    * [[java.util.concurrent.CompletableFuture]] is terminated in an analogous
    * manner. This is important, otherwise a resource leak may occur.
    */
  // TODO upstream?
  private[jdkhttpclient] def fromCompletableFuture[F[_], A](
      fcs: F[CompletableFuture[A]]
  )(implicit F: Async[F]): F[A] =
    F.bracketCase(fcs) { cs =>
      F.async_[A] { cb =>
        cs.handle[Unit] { (result, err) =>
          err match {
            case null => cb(Right(result))
            case _: CancellationException => ()
            case ex: CompletionException if ex.getCause ne null => cb(Left(ex.getCause))
            case ex => cb(Left(ex))
          }
        }; ();
      }
    }((cs, o) =>
      (o match {
        case Outcome.Succeeded(_) => F.unit
        case Outcome.Errored(e) =>
          F.delay(cs.completeExceptionally(e)).void
        case Outcome.Canceled() =>
          F.delay(cs.cancel(true)).void
      })
    )

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy