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

add evalOn(executor) #3637

Closed
wants to merge 0 commits into from
Closed

Conversation

homycdev
Copy link
Contributor

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

There is one thing I didn't think of, that we should add a test for: Scala has an ExecutionContextExecutor type that is both an ExecutionContext and an Executor. What happens if someone passes that to evalOn, how does it disambiguate?

https://www.scala-lang.org/api/2.13.10/scala/concurrent/ExecutionContextExecutor.html

Comment on lines 1824 to 1827
def evalOn[A](fa: IO[A], executor: Executor): IO[A] =
IO.executionContext
.flatMap(ec => IO(ExecutionContext.fromExecutor(executor, ec.reportFailure)))
.flatMap(ec => fa.evalOn(ec))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This looks exactly like what I imagined. We can make this the default implementation in Async.

I have one more suggestion: we can pattern match and check if the Executor is already an ExecutionContext, and skip the conversion in that case.

We do something similar here.

/**
* Obtain a reference to the current execution context as a `java.util.concurrent.Executor`.
*/
def executor: F[Executor] = map(executionContext) {
case exec: Executor => exec
case ec => ec.execute(_)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope, I got you right. Please, check new commit when you can.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding tests, i have found tests only on laws for Async's methods.
But from the comment you wrote me, i shall rather check whether the executionContext was executed through provided executor... correct me if I am wrong.

Thank you in advance!

@armanbilge armanbilge linked an issue May 17, 2023 that may be closed by this pull request
@homycdev
Copy link
Contributor Author

@armanbilge is there everything alright? or something's missing?

Copy link
Contributor

@durban durban left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what's mainly missing is the test suggested in this comment.

(@armanbilge I've figured out what's happening with the "green" CI: in the PR list, and besides the commit there is a green checkmark. However, if I log in, I see the yellow warning at the bottom. This is probably normal, just a bit strange...)

Comment on lines 35 to 36
def evalOn(executor: Executor)(implicit F: Async[F]): F[A] =
Async[F].evalOnExecutor(wrapped, executor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def evalOn(executor: Executor)(implicit F: Async[F]): F[A] =
Async[F].evalOnExecutor(wrapped, executor)
def evalOnExecutor(executor: Executor)(implicit F: Async[F]): F[A] =
Async[F].evalOnExecutor(wrapped, executor)

Would you mind also adding this method directly on IO? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@armanbilge hello! Could you please check?)

djspiewak
djspiewak previously approved these changes Jun 6, 2023
Copy link
Member

@djspiewak djspiewak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good to go. @armanbilge any thoughts?

Thank you for tackling this!

*/
def evalOnExecutor(executor: Executor): IO[A] =
executionContext
.flatMap(ec => IO(ExecutionContext.fromExecutor(executor, ec.reportFailure)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, IO#evalOnExecutor has a different behavior from Async#evalOnExecutor. I think they should behave the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should indeed! I missed that in my review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for this. I hope, I understood you correctly now!

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yes, sorry! There are a few more APIs I think it would be good to add, for consistency: startOnExecutor, backgroundOnExecutor, evalOnExecutorK

@@ -35,6 +35,7 @@ import cats.{
Traverse
}
import cats.data.Ior
import cats.effect.IO.executionContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of importing this can we call it as IO.executionContext? Sometimes unqualified methods can cause confusion 😅

@djspiewak djspiewak dismissed their stale review June 7, 2023 16:18

durban and arman are smarter

@homycdev homycdev closed this Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Async#evalOn(executor) or Async#evalOnExecutor(executor)
4 participants