Skip to content

evaluate the possibility of Future API surface #533

Description

@baywet

Context: java's equivalent to Promises/Tasks are Futures. Adding an API surface that returns Futures (and potentially removing the callback one??) would enable our customers to write modern Java in their applications

I suppose so but my callback wrapper is pretty straightforward; it wasn't a huge deal writing it.

object ICallbackWrapper extends StrictLogging {

  private def cbF[T](): (Future[T], ICallback[T]) = {
    val p = Promise[T]()
    val cb = new ICallback[T] {
      override def success(result: T): Unit = {
        val _ = p.trySuccess(result)
      }

      override def failure(ex: ClientException): Unit = {
        val _ = p.tryFailure(ex)
      }
    }

    (p.future, cb)
  }

  def toFut[T](fun: ICallback[T] => Unit)(
      implicit
      ec: ExecutionContext,
  ): Future[T] = {
    val (f, cb) = cbF[T]()

    Limiter.apiFut {
      () =>
        fun(cb)
        f
    }
  }

  def toFut[V, T](v: V, fun: (V, ICallback[T]) => Unit)(
      implicit
      ec: ExecutionContext,
  ): Future[T] = {
    val (f, cb) = cbF[T]()

    Limiter.apiFut {
      () =>
        fun(v, cb)
        f
    }
  }

  def uploadFut[V, T](v: V, len: Long, fun: (V, ICallback[T]) => Unit)(
      implicit
      ec: ExecutionContext,
  ): Future[T] = {
    val (f, cb) = cbF[T]()

    Limiter.attachFut(
      () => {
        fun(v, cb)
        f
      },
      len,
    )
  }
}

By far the biggest issue with using graph are the very restrictive rate limits... I shimmed a "rate limiter" into the above wrapper so I'm able to limit both number of simultaneous connections as well as ensure uploads don't go over the 15mb/30 sec limit. It took a lot of trial and error getting the futures passed just right so I didn't go over the max 4 connection cap, but it seems to be working well in practice.

Originally posted by Adam Lesperance (@lespea) in https://github.com/microsoftgraph/msgraph-sdk-java/issue_comments/705202102
AB#6315

Activity

  1. ghost removed on Oct 8, 2020
  2. added this to the 3.0.0 milestone on Oct 8, 2020
  3. baywet commented on Nov 17, 2020

    @baywet
    MemberAuthor
  4. baywet commented on Nov 26, 2020

    @baywet
    MemberAuthor

    alternatively the azure identity is using Mono, which requires API level 26 but apparently has a better design

  5. baywet commented on Dec 14, 2020

    @baywet
    MemberAuthor

    alternatively, android had asyncTask

  6. baywet commented on Dec 18, 2020

    @baywet
    MemberAuthor

    update: whatever solution we come up with should work with API level 21.

  7. baywet commented on Dec 29, 2020

    @baywet
    MemberAuthor

    additionally, most http client libraries seem to be providing a native support for Futures (not okhttpclient though)
    https://www.mocklab.io/blog/which-java-http-client-should-i-use-in-2020/

  8. baywet commented on Jan 8, 2021

    @baywet
    MemberAuthor

    alternatively, CompletableFuture API level 24 (java allows for chaining the futures (comparatively to "plain" futures)

  9. baywet commented on Jan 8, 2021

    @baywet
    MemberAuthor

    Recap of the solution and work to be done:
    We'll provide a Future API surface which will replace the callback API surface, as having both seems unnecessary and providing a future API surface seems superior to a callback one to comply with our compatibility requirements.
    This API surface needs to be wired all the way down to the okhttp call, using FutureTasks, and wrapping the enqueue call. (execute needs to be replaced where used)
    Any custom Callback and executor definition needs to be stripped out.

    We might need to rely on guava's ListenableFutures to chain the work as basic Futures don't seem to provide that kind of support and as CompletableFuture is only available on API level 24.

    Lastly, we'll keep providing a synchronous API to align with Azure SDKs

    Note: azure provides completable futures and monos in their SDK, but they have separate SDKs for android and java

  10. baywet commented on Jan 13, 2021

    @baywet
    MemberAuthor

    Update, after investigating and looking in depth at telemetry, we'll switch to CompletableFutures and raise the API level to 26 see the original comment

  11. linked a pull request that will close this issuefeature/future #610on Jan 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions