Last active
December 26, 2023 16:27
-
-
Save klaeufer/3d6a15837bae8d7d5dd07ad9f0db9b97 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see also https://www.implicitdef.com/2015/11/19/comparing-scala-http-client-libraries.html | |
// task: use the prime checker webservice | |
// https://github.com/LoyolaChicagoCode/primenumbers-spray-scala | |
// to count the number of primes within a given range | |
/* instructions: create a build.sbt file in your project root folder containing the following lines: | |
scalaVersion := "3.3.1" | |
Compile / scalacOptions ++= Seq( | |
"-deprecation", | |
"-feature", | |
"-unchecked", | |
"-Wvalue-discard", | |
"-language:strictEquality", | |
"-Yexplicit-nulls", | |
"-Ysafe-init", | |
) | |
libraryDependencies ++= Seq( | |
"com.typesafe.play" %% "play-ahc-ws-standalone" % "2.2.4", | |
"org.slf4j" % "slf4j-simple" % "2.0.9" | |
) | |
*/ | |
// then launch sbt console and paste the rest of the code in the resulting REPL | |
// it is best to do this section by section, not all at once, following the comments | |
// *** section 1 *** | |
import scala.util.Success | |
import scala.concurrent.Future | |
import akka.actor.ActorSystem | |
import akka.stream.ActorMaterializer | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import play.api.libs.ws.ahc.StandaloneAhcWSClient | |
val system = ActorSystem("wsplay-example") | |
given ActorSystem = system | |
val wsClient = StandaloneAhcWSClient() | |
val urls = (10000000 to 10005000).map: n => | |
"https://primechecker.azurewebsites.net/api/isPrime?number=" + n | |
// *** section 2 *** | |
// Seq[Future[...]] | |
val requests = urls.map(u => wsClient.url(u).get()) | |
val results = requests.map: f => | |
f.map: r => | |
r.status == 200 | |
val resultsFailsafe = results.map: f => | |
f.recover: ex => | |
false | |
// Future[Seq[...]] | |
val f1 = Future.sequence(results) | |
val f2 = f1.map(r => r.count(identity)) | |
// how are these two different? | |
val f3 = Future.sequence(resultsFailsafe) | |
val f4 = f3.map(r => r.count(identity)) | |
// *** section 3 *** | |
// print final result | |
f2.foreach(println) | |
f4.foreach(println) | |
// *** section 4 *** | |
// meanwhile, can check repeatedly how many requests have completed | |
results.count(f => f.isCompleted) | |
resultsFailsafe.count(f => f.isCompleted) | |
// you can also (repeatedly) print the wrapped result in the foreground | |
f2.value | |
f4.value | |
// *** section 5 *** | |
// finally, exit the REPL using | |
system.terminate() | |
// and/or Ctrl-C | |
// IMPORTANT: The current web service instances are too responsive | |
// for us to observe progress by repeating line 53 manually. | |
// Instead, we can paste (in one piece) lines 42-53 followed by several repetitions of | |
// | |
// ; Thread.sleep(10) ; results.count: f => f.isCompleted | |
// | |
// to see progress in this form: | |
// | |
// val res75: Int = 105 | |
// val res77: Int = 109 | |
// ... | |
// | |
// If that's not enough, try redoing the whole experiment for a wider numeric range, | |
// e.g., 10 or 100 times as wide. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment