-
-
Notifications
You must be signed in to change notification settings - Fork 244
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 Task.forkAndForget #530
Changes from 3 commits
8197ec6
80a21ed
a9bdbd8
cf5186d
849779f
4ca825e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright (c) 2014-2018 by The Monix Project Developers. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* 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 monix.eval | ||
package internal | ||
|
||
private[eval] object TaskStartAndForget { | ||
/** | ||
* Implementation for `Task.startAndForget`. | ||
*/ | ||
def apply[A](fa: Task[A]): Task[Unit] = | ||
Task.Async[Unit] { (ctx, cb) => | ||
implicit val sc = ctx.scheduler | ||
// It needs its own context, its own cancelable | ||
val ctx2 = Task.Context(sc, ctx.options) | ||
// Starting actual execution of our newly created task forcing new async boundary | ||
Task.unsafeStartAsync(fa, ctx2, Callback.empty) | ||
// Signal the created Task reference | ||
cb.onSuccess(()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has the potential of generating stack overflow errors under certain conditions, which is why as policy we never call Please use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: the comment above is not correct, there's no Task reference signalled |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (c) 2014-2018 by The Monix Project Developers. | ||
* See the project homepage at: https://monix.io | ||
* | ||
* 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 monix.eval | ||
|
||
import cats.laws._ | ||
import cats.laws.discipline._ | ||
|
||
import scala.util.Success | ||
|
||
object TaskStartAndForgetSuite extends BaseTestSuite { | ||
|
||
test("task.startAndForget works") { implicit sc => | ||
check1 { (i: Int) => | ||
var counter = 0 | ||
val task = Task { | ||
counter = i | ||
i | ||
} | ||
task.startAndForget.runAsync | ||
sc.tick() | ||
|
||
counter <-> i | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're using Do a simple test and test that:
val task = Task.eval { counter += 1; counter }
val main = for {
_ <- task.delayExecution(1.second).forkAndForget // first
_ <- task.delayExecution(1.second).forkAndForget // second
} yield ()
val f = main.runAsync
assertEquals(f.value, Some(Success(()))
assertEquals(counter, 0)
// Testing that both got executed in parallel, otherwise
// the total execution time would take 2 seconds
s.tick(1.second)
assertEquals(counter, 2) Well, this doesn't test that an async boundary is forced, since we are doing it anyway with |
||
} | ||
} | ||
|
||
test("task.startAndForget is stack safe") { implicit sc => | ||
var task: Task[Any] = Task(1) | ||
for (_ <- 0 until 5000) task = task.startAndForget | ||
for (_ <- 0 until 5000) task = task.flatMap(_ => Task.unit) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
|
||
val f = task.runAsync | ||
sc.tick() | ||
assertEquals(f.value, Some(Success(()))) | ||
} | ||
|
||
test("task.startAndForget <-> task.start.map(_ => ())") { implicit sc => | ||
check1 { (task: Task[Int]) => | ||
task.startAndForget <-> task.start.map(_ => ()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
task.startAndForget <-> Task.unit We don't need it. Get rid of it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can I somehow prove this equivalence? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. Would be nice but |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you refer to
fork
instead ofstart
, this comment is not needed.