Process the same input file concurrently Let's say we have a text file that contains 2 different types of lines. For the sake of example, one group starts with "i:" (for Integer) and the other group starts with "s:" (for String), something like the following file: s:New york s:Apple i:387548 s:Amsterdam i:4556 i:39874 s:Orange i:56787 s:Banana i:4657567 s:Turkey i:45679456 s:Iran i:4356456 i:23423 i:456 s:Ukraine i:453645 i:5456 We want to process these input lines separately but concurrently. And the process can be anything, for this example, we just print them to the console. But what matters is that we open the file only for READ so 2 different processes (or routines) can read the file at the same time. The Cats Effect answer to open files (or in general any resources) in a safe and efficient way, is Resource class. So we need a function to take the path to the file and give us a Resource of some type that allows us to read the file line by line. One o...
In this super short post, I am showing you how to write a very naive HTTP client (GET) to return the content of the response as a plain String.
The whole point here is not to use a proper Scala library and wrap the side effect (an HTTP request is a side effect) in an IO object.
object HttpService {
def getRequest(uri: String): IO[String] = {
try {
IO {
val url = new URL(uri)
val con = url.openConnection.asInstanceOf[HttpURLConnection]
con.setRequestMethod("GET")
val streamReader = getTheStreamReader(con)
val bufferedReader = new BufferedReader(streamReader)
def loop(reader: BufferedReader, stringBuilder: StringBuilder): StringBuilder = {
val line = reader.readLine()
line match
case null => stringBuilder
case line => loop(reader, stringBuilder.append(line))
}
loop(bufferedReader, new StringBuilder()).toString()
}
} catch {
case t: Throwable => IO.raiseError(t)
}
}
private def getTheStreamReader(con: HttpURLConnection): InputStreamReader =
con.getResponseCode match
case status if status > 299 && con.getErrorStream != null => new InputStreamReader(con.getErrorStream)
case _ => new InputStreamReader(con.getInputStream)
}This is good for the sake of learning but we can simplify it as
def getRequest(uri: String): IO[String] = IO(scala.io.Source.fromURL(uri).mkString)
Comments
Post a Comment