Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@klaeufer
Last active December 26, 2023 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klaeufer/3d6a15837bae8d7d5dd07ad9f0db9b97 to your computer and use it in GitHub Desktop.
Save klaeufer/3d6a15837bae8d7d5dd07ad9f0db9b97 to your computer and use it in GitHub Desktop.
// 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