0

I have an Akka server who is asking the mallet file (some output) from an actor. However in mallet actor code, several steps are done. In which files are taken, modified, new files are created and saved in resource directory couple of times.

I need to run the actor sequentially so I am using map in calling future. However the job is getting NullPointerException as there is no file for next future. And as soon as I am stopping the server. all the files are getting generated in resources directory.

I need the files in resources directory as soon as individual future is completed. Please suggest

Below is the code of my server

lazy val routes: Route = apiRoutes
Configuration.parser.parse(args,Configuration.ConfigurationOptions()) match {
    case Some(config) =>
      val serverBinding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, config.interface, config.port)
      serverBinding.onComplete {
        case Success(bound) =>
          println(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/")
        case Failure(e) =>
          log.error("Server could not start: ", e)
          system.terminate()
      }
    case None =>
      system.terminate()
  }
  Await.result(system.whenTerminated, Duration.Inf)
}

Below is the code of receive function.

            def receive: Receive = {
        case GetMalletOutput(malletFile) => createMalletResult(malletFile).pipeTo(sender())
    }


          def createMalletResult(malletFile: String): Future[MalletModel] = {

            //sample malletResult
            val topics = Array(Topic("1", "2").toJson)
            var mM: Future[MalletModel] = Future{MalletModel("contentID", topics)}


            //first Future to save file in resource
            def saveFile(malletFile: String): Future[String] = Future {

                val res = MalletResult(malletFile)
                val converted = res.Score.parseJson.convertTo[MalletRepo]
                val fileName = converted.ContentId
                val fileTemp = new File("src/main/resources/new_corpus/" + fileName)

                val output = new BufferedWriter(new FileWriter("src/main/resources/new_corpus/" + fileName))
                output.write(converted.ContentText)
                //output.close()
                malletFile
              }

//Second Future to used the resource file and create new one
            def t2v(malletFile: String): Future[String] = Future{
              val tmpDir = "src/main/resources/"

              logger.debug(tmpDir.toString)

              logger.debug("t2v Started")
              Text2Vectors.main(("--input " + tmpDir + "new_corpus/ --keep-sequence --remove-stopwords " + "--output " + tmpDir + "new_corpus.mallet --use-pipe-from " + tmpDir + "corpus.mallet").split(" "))
              logger.debug("text2Vector Completed")
              malletFile
            }
        //another future to take file from resource and save in the new file back in resource
            def infer(malletFile: String): Future[String] = Future {
              val tmpDir = "src/main/resources/"
              val tmpDirNew = "src/main/resources/inferResult/"
              logger.debug("infer started")
              InferTopics.main(("--input " + tmpDir + "new_corpus.mallet --inferencer " + tmpDir + "inferencer " + "--output-doc-topics " + tmpDirNew + "doc-topics-new.txt --num-iterations 1000").split(" "))
              logger.debug("infer Completed")
              malletFile
            }

//final future to return the requested output using the saved future
            def response(malletFile: String): Future[MalletModel] = Future{
              logger.debug("response Started")

              val lines = Source.fromResource("src/main/resources/inferResult/doc-topics-new.txt")
                .getLines
                .toList
                .drop(1) match {
                case Nil => List.empty
                case x :: xs => x.split(" ").drop(2).mkString(" ") :: xs
              }

              logger.debug("response On")
              val result = MalletResult(malletFile)
              val convert = result.Score.parseJson.convertTo[MalletRepo]
              val contentID = convert.ContentId

              val inFile = lines.mkString(" ")


              val a = inFile.split(" ").zipWithIndex.collect { case (v, i) if (i % 2 == 0) =>
                (v, i)
              }.map(_._1)
              val b = inFile.split(" ").zipWithIndex.collect { case (v, i) if (i % 2 != 0) =>
                (v, i)
              }.map(_._1)
              val paired = a.zip(b) // [(s,t),(s,t)]

              val topics = paired.map(x => Topic(x._2, x._1).toJson)

              logger.debug("validating")
              logger.debug("mallet results...")
              logger.debug("response Done")
              MalletModel(contentID, topics)

            }

//calling one future after another to run future sequntially
            val result: Future[MalletModel] =
              saveFile(malletFile).flatMap(malletFile =>
                          t2v(malletFile).flatMap(mf =>
                            infer(mf).flatMap(mf =>
                            response(mf))))

            result
            }

          }
danD
  • 666
  • 1
  • 7
  • 29

1 Answers1

0

It seems I have got the answer myself. The problem was I was trying to write the file in resource directory and reading the file back. to resolve the issue I wrote the file in tmpDir and read it back with bufferreader instead of source. and bam it worked.

danD
  • 666
  • 1
  • 7
  • 29