-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Support Twitter futures #833
Changes from 20 commits
4ed1287
44d6b14
b137c02
a9aa71b
595d48b
ad3c1a7
c98e2ff
58d4a36
4a6a025
d754b82
ff1b505
695aa0d
4ec01ef
0bb7c03
2703c56
9ec75e7
f5fc7bc
a7ee13a
dbc12ee
99e6514
729a293
709453f
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 |
---|---|---|
|
@@ -36,7 +36,7 @@ jobs: | |
- &scaladoc | ||
stage: microsite | ||
name: "Generate Scaladoc" | ||
script: sbt ++$TRAVIS_SCALA_VERSION coreJVM/doc coreJS/doc interopCatsJVM/doc interopCatsJS/doc interopFutureJVM/doc interopFutureJS/doc interopScalaz7xJVM/doc interopScalaz7xJS/doc interopMonixJVM/doc interopMonixJS/doc interopJavaJVM/doc interopReactiveStreamsJVM/doc | ||
script: sbt ++$TRAVIS_SCALA_VERSION coreJVM/doc coreJS/doc interopCatsJVM/doc interopCatsJS/doc interopFutureJVM/doc interopScalaz7xJVM/doc interopScalaz7xJS/doc interopMonixJVM/doc interopMonixJS/doc interopJavaJVM/doc interopReactiveStreamsJVM/doc interopTwitterJVM/doc | ||
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. is 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. It was on purpose, as I think there isn't (wasn't?) such interop atm. I can reintroduce it though. |
||
- µsite | ||
stage: microsite | ||
name: "Generate microsite" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,13 +42,14 @@ lazy val root = project | |
interopCatsJVM, | ||
interopCatsJS, | ||
interopFutureJVM, | ||
// interopMonixJVM, | ||
// interopMonixJS, | ||
interopMonixJVM, | ||
interopMonixJS, | ||
interopScalaz7xJVM, | ||
interopScalaz7xJS, | ||
interopJavaJVM, | ||
interopReactiveStreamsJVM, | ||
// benchmarks, | ||
interopTwitterJVM, | ||
benchmarks, | ||
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. What was the reason to have 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. No idea. It was commented out for a long time now. As far as I can see it's commented out together with Monix during "death of TF" PR :). 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 remember it :D , I wondered why it was already commented before |
||
testkitJVM, | ||
docs | ||
) | ||
|
@@ -225,6 +226,16 @@ lazy val interopReactiveStreams = crossProject(JVMPlatform) | |
|
||
lazy val interopReactiveStreamsJVM = interopReactiveStreams.jvm.dependsOn(interopSharedJVM) | ||
|
||
lazy val interopTwitter = crossProject(JSPlatform, JVMPlatform) | ||
.in(file("interop-twitter")) | ||
.settings(stdSettings("zio-interop-twitter")) | ||
.settings( | ||
libraryDependencies += "com.twitter" %% "util-core" % "19.4.0" | ||
) | ||
.dependsOn(core % "test->test;compile->compile") | ||
|
||
lazy val interopTwitterJVM = interopTwitter.jvm.dependsOn(interopSharedJVM) | ||
|
||
lazy val testkit = crossProject(JVMPlatform) | ||
.in(file("testkit")) | ||
.settings(stdSettings("zio-testkit")) | ||
|
@@ -281,5 +292,14 @@ lazy val docs = project.module | |
"org.jsoup" % "jsoup" % "1.11.3" % "provided" | ||
) | ||
) | ||
.dependsOn(coreJVM, interopCatsJVM, interopFutureJVM, interopScalaz7xJVM, interopJavaJVM, interopReactiveStreamsJVM) | ||
.dependsOn( | ||
coreJVM, | ||
interopCatsJVM, | ||
interopFutureJVM, | ||
interopMonixJVM, | ||
interopScalaz7xJVM, | ||
interopJavaJVM, | ||
interopReactiveStreamsJVM, | ||
interopTwitterJVM | ||
) | ||
.enablePlugins(MdocPlugin, DocusaurusPlugin) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
id: interop_twitter | ||
mijicd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
title: "Twitter" | ||
--- | ||
|
||
`interop-twitter` module provides capability to convert Twitter `Future` into ZIO `Task`. | ||
|
||
### Example | ||
|
||
```scala | ||
import com.twitter.util.Future | ||
import scalaz.zio.{ App, Task } | ||
import scalaz.zio.console._ | ||
import scalaz.zio.interop.twitter._ | ||
|
||
object Example extends App { | ||
def run(args: List[String]) = { | ||
val program = | ||
for { | ||
_ <- putStrLn("Hello! What is your name?") | ||
name <- getStrLn | ||
greeting <- Task.fromTwitterFuture(greet(name)) | ||
_ <- putStrLn(greeting) | ||
} yield () | ||
|
||
program.fold(_ => 1, _ => 0) | ||
} | ||
|
||
private def greet(name: String): Future[String] = Future.value(s"Hello, $name!") | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright 2017-2019 John A. De Goes and the ZIO Contributors | ||
* | ||
* 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 scalaz.zio.interop | ||
|
||
import com.twitter.util.{ Future, FutureCancelledException, Return, Throw } | ||
import scalaz.zio.{ Task, UIO } | ||
|
||
package object twitter { | ||
implicit class TaskObjOps(private val obj: Task.type) extends AnyVal { | ||
final def fromTwitterFuture[A](future: => Future[A]): Task[A] = | ||
Task.effectAsyncInterrupt { cb => | ||
future.respond { | ||
case Return(a) => cb(Task.succeed(a)) | ||
case Throw(e) => cb(Task.fail(e)) | ||
} | ||
|
||
Left(UIO(future.raise(new FutureCancelledException))) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package scalaz.zio.interop | ||
|
||
import java.util.concurrent.atomic.AtomicInteger | ||
|
||
import com.twitter.util.{ Duration => TwitterDuration, Future, JavaTimer } | ||
import org.specs2.concurrent.ExecutionEnv | ||
import scalaz.zio.{ FiberFailure, Task, TestRuntime } | ||
import scalaz.zio.Exit.Cause.Fail | ||
import scalaz.zio.duration.Duration | ||
import scalaz.zio.interop.twitter._ | ||
|
||
import scala.concurrent.duration._ | ||
|
||
class TwitterSpec(implicit ee: ExecutionEnv) extends TestRuntime { | ||
def is = | ||
"Twitter spec".title ^ s2""" | ||
`Task.fromTwitterFuture` must | ||
return failing `Task` if future failed. $propagateFailures | ||
return successful `Task` if future succeeded. $propagateResults | ||
ensure future is interrupted together with task. $propagateInterrupts | ||
""" | ||
|
||
private def propagateFailures = { | ||
val error = new Exception | ||
val future = Future.exception[Int](error) | ||
val task = Task.fromTwitterFuture(future) | ||
|
||
unsafeRun(task) must throwAn(FiberFailure(Fail(error))) | ||
} | ||
|
||
private def propagateResults = { | ||
val value = 10 | ||
val future = Future.value(value) | ||
val task = Task.fromTwitterFuture(future) | ||
|
||
unsafeRun(task) ==== value | ||
} | ||
|
||
private def propagateInterrupts = { | ||
implicit val timer = new JavaTimer(true) | ||
|
||
val futureTimeout = TwitterDuration.fromSeconds(3) | ||
val taskTimeout = Duration.fromScala(1.second) | ||
val value = new AtomicInteger(0) | ||
|
||
lazy val future = Future.sleep(futureTimeout).map(_ => value.incrementAndGet()) | ||
|
||
val task = Task.fromTwitterFuture(future).timeout(taskTimeout) | ||
|
||
unsafeRun(task) must beNone | ||
|
||
SECONDS.sleep(5) | ||
|
||
value.get() ==== 0 | ||
} | ||
} |
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.
Is this necessary? It's added by metals, isn't it? If possible I'd move that out of the way.
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.
Unfortunately, it is. All hell breaks loose if you remove it :).
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.
Sad 😞