Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync vs async API #81

Closed
Treora opened this issue May 29, 2020 · 3 comments
Closed

sync vs async API #81

Treora opened this issue May 29, 2020 · 3 comments
Labels
discussion Issues without a clear plan for action

Comments

@Treora
Copy link
Contributor

Treora commented May 29, 2020

As discussed in the call yesterday, I open this issue to park thoughts about whether/how to provide synchronous APIs, mainly future consideration.

So far, we have been using async iterables/generators as the system for returning a selector’s matches to the caller. The intention of this approach is to not block the thread for too long when dealing with e.g. a fuzzy text search (once that’s implemented) in a large document:

  • Using an iterable instead of returning all matches in an array allows the user to get the first results before the search has completed, and also pause or abort the continuation of the search if desired — this is great, no need to question this I think.
  • Using an async iterable allows such a search implementation to e.g. break up work in small chunks.

In our planned modular system, with support for different selector types and different implementations for anchoring them, some implementations may want to use the asynchronous approach, while others are quick enough to run synchronously. So far, our code only uses synchronous implementations, but it exposes them as asynchronous functions so that in the future one could swap out an implementation for an async one, and we can pass functions around without needing to distinguish between sync and async ones. Unfortunately, as Javascript lacks a way to turn a resolved promise into its value synchronously, a sync implementation with an async API cannot be wrapped to make it sync again.

Now a question may be whether, for situations where the implementations are synchronous anyway, it is a burden for users to have to use the asynchronous API when it is not needed. If so, one option would be to provide a sync and and async API, much like NodeJS does for many of its functions. It may require some reorganisation/duplication in our code and documentation, but we could consider this if the async approach is a show-stopper for some (potential) users; do leave a reply if that is the case for you.

@Treora Treora added the discussion Issues without a clear plan for action label Jul 16, 2020
@tilgovi
Copy link
Contributor

tilgovi commented Aug 16, 2020

I propose we start by making some attempt to have core pieces of our reusable code allow for synchronous iterators, but keep the asynchronous consumer API.

I started experimenting with something like this, that we could use in our definitions for cartesian product or our matcher functions.

type AbstractIterable<T> = AsyncIterable<T> | Iterable<T>;

export function isAsyncIterable<T>(
  iterable: AbstractIterable<T>,
): iterable is AsyncIterable<T> {
  return typeof iterable[Symbol.asyncIterator] === 'function';
}

export function makeAsync<T>(iterable: AbstractIterable<T>): AsyncIterable<T> {
  if (isAsyncIterable<T>(iterable)) {
    return iterable;
  }

  return {
    [Symbol.asyncIterator]() {
      const iter = iterable[Symbol.iterator]();
      return {
        next() {
          return Promise.resolve(iter.next());
        },
      };
    },
  };
}

@Treora
Copy link
Contributor Author

Treora commented Aug 17, 2020

Looks good. I’d be fine with adopting this approach, but equally fine with just keeping it in mind for when we have a need/requests for synchronous use.

@tilgovi
Copy link
Contributor

tilgovi commented Feb 4, 2021

Closing this. Sounds like we've got ideas for supporting synchronous APIs, but we don't have any urgency around it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Issues without a clear plan for action
Projects
None yet
Development

No branches or pull requests

2 participants