Skip to content

Commit 40e8743

Browse files
committed
Catch the TimeoutException in the search command.
Undeterministically generates a harmless error message from Akka in the console (akka/akka-http#497). Future work: disable this message.
1 parent 655272a commit 40e8743

File tree

3 files changed

+40
-30
lines changed

3 files changed

+40
-30
lines changed

src/main/scala/de/upb/cs/swt/delphi/cli/Config.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ case class Config(server: String = sys.env.getOrElse("DELPHI_SERVER", "https://d
3333
query : String = "",
3434
limit : Option[Int] = None,
3535
id : String = "",
36+
timeout : Int = 10,
3637
args: List[String] = List(),
3738
opts: List[String] = List()) {
3839

src/main/scala/de/upb/cs/swt/delphi/cli/DelphiCLI.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,19 @@ object DelphiCLI extends App {
5353
.text("Retrieve a project's description, specified by ID.")
5454
.children(
5555
arg[String]("id").action((x, c) => c.copy(id = x)).text("The ID of the project to retrieve"),
56+
opt[String]("csv").action((x, c) => c.copy(csv = x)).text("Path to the output .csv file (overwrites existing file)"),
5657
opt[Unit]('f', "file").action((_, c) => c.copy(opts = List("file"))).text("Use to load the ID from file, " +
57-
"with the filepath given in place of the ID"),
58-
opt[String]("csv").action((x, c) => c.copy(csv = x)).text("Path to the output .csv file (overwrites existing file)")
58+
"with the filepath given in place of the ID")
5959
)
6060

6161
cmd("search").action((s, c) => c.copy(mode = "search"))
6262
.text("Search artifact using a query.")
6363
.children(
6464
arg[String]("query").action((x,c) => c.copy(query = x)).text("The query to be used."),
65+
opt[String]("csv").action((x, c) => c.copy(csv = x)).text("Path to the output .csv file (overwrites existing file)"),
6566
opt[Int]("limit").action((x, c) => c.copy(limit = Some(x))).text("The maximal number of results returned."),
6667
opt[Unit](name="list").action((_, c) => c.copy(list = true)).text("Output results as list (raw option overrides this)"),
67-
opt[String]("csv").action((x, c) => c.copy(csv = x)).text("Path to the output .csv file (overwrites existing file)")
68+
opt[Int]("timeout").action((x, c) => c.copy(timeout = x)).text("Timeout in seconds.")
6869
)
6970
}
7071
}

src/main/scala/de/upb/cs/swt/delphi/cli/commands/SearchCommand.scala

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package de.upb.cs.swt.delphi.cli.commands
1818

19+
import java.util.concurrent.TimeoutException
1920
import java.util.concurrent.TimeUnit
2021

2122
import akka.actor.ActorSystem
@@ -29,7 +30,6 @@ import akka.util.ByteString
2930
import de.upb.cs.swt.delphi.cli.Config
3031
import de.upb.cs.swt.delphi.cli.artifacts.SearchResult
3132
import de.upb.cs.swt.delphi.cli.artifacts.SearchResultJson._
32-
import de.upb.cs.swt.delphi.cli.commands.RetrieveCommand.information
3333
import spray.json.DefaultJsonProtocol
3434

3535
import scala.concurrent.duration._
@@ -59,40 +59,48 @@ object SearchCommand extends Command with SprayJsonSupport with DefaultJsonProto
5959
Http().singleRequest(HttpRequest(uri = searchUri, method = HttpMethods.POST, entity = entity))
6060
}
6161

62-
val response = Await.result(responseFuture, 10 seconds)
63-
val resultFuture: Future[String] = response match {
64-
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
65-
entity.dataBytes.runFold(ByteString(""))(_ ++ _).map { body =>
66-
body.utf8String
62+
try {
63+
val response = Await.result(responseFuture, Duration(config.timeout + " seconds"))
64+
val resultFuture: Future[String] = response match {
65+
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
66+
entity.dataBytes.runFold(ByteString(""))(_ ++ _).map { body =>
67+
body.utf8String
68+
}
69+
case resp@HttpResponse(code, _, _, _) => {
70+
error(config)("Request failed, response code: " + code)
71+
resp.discardEntityBytes()
72+
Future("")
6773
}
68-
case resp@HttpResponse(code, _, _, _) => {
69-
error(config)("Request failed, response code: " + code)
70-
resp.discardEntityBytes()
71-
Future("")
7274
}
73-
}
74-
75-
val result = Await.result(resultFuture, Duration.Inf)
7675

77-
val took = (System.nanoTime() - start).nanos.toUnit(TimeUnit.SECONDS)
76+
val result = Await.result(resultFuture, Duration.Inf)
7877

79-
if (config.raw || result.equals("")) {
80-
reportResult(config)(result)
81-
}
78+
val took = (System.nanoTime() - start).nanos.toUnit(TimeUnit.SECONDS)
8279

83-
if(!(config.raw || result.equals("")) || !config.csv.equals("")) {
84-
val unmarshalledFuture = Unmarshal(result).to[List[SearchResult]]
80+
if (config.raw || result.equals("")) {
81+
reportResult(config)(result)
82+
}
8583

86-
val processFuture = unmarshalledFuture.transform {
87-
case Success(unmarshalled) => {
88-
processResults(config, unmarshalled, took)
89-
Success(unmarshalled)
90-
}
91-
case Failure(e) => {
92-
error(config)(result)
93-
Failure(e)
84+
if(!(config.raw || result.equals("")) || !config.csv.equals("")) {
85+
val unmarshalledFuture = Unmarshal(result).to[List[SearchResult]]
86+
87+
val processFuture = unmarshalledFuture.transform {
88+
case Success(unmarshalled) => {
89+
processResults(config, unmarshalled, took)
90+
Success(unmarshalled)
91+
}
92+
case Failure(e) => {
93+
error(config)(result)
94+
Failure(e)
95+
}
9496
}
9597
}
98+
} catch {
99+
case e : TimeoutException => {
100+
error(config)("The query timed out after " + (System.nanoTime() - start).nanos.toUnit(TimeUnit.SECONDS) +
101+
" seconds. To set a longer timeout, use the --timeout option.")
102+
Failure(e)
103+
}
96104
}
97105
}
98106

0 commit comments

Comments
 (0)