2016-08-02 30 views
0

Ich habe eine Funktion in meinem Controller, die Benutzereingaben entgegennimmt und dann mithilfe einer Endlosschleife eine Datenbank abfragt und das von der Datenbank zurückgegebene Objekt an eine Webseite sendet. Das alles funktioniert gut, außer dass ich Nebenläufigkeit einführen musste, um sowohl diese Logik auszuführen als auch die Webseite zu rendern.Ändern des Status bei Verwendung von Scala Concurrency

def getSearchResult = Action { request => 
    val search = request.queryString.get("searchInput").head.head 

    val databaseSupport = new InteractWithDatabase(comm, db) 

    val put = Future { 
     while (true) { 
     val data = databaseSupport.getFromDatabase(search) 
     if (data.nonEmpty) { 
      if (data.head.vendorId.equals(search)) { 
      comm.communicator ! data.head 
      } 
     } 
     } 
    } 
    Ok(views.html.singleElement.render) 
    } 

Das Problem entsteht, wenn ich dies wieder anrufen will, aber mit einem anderen Eingang:

Der Code ist gegeben durch. Da der erste Thread in einer Endlosschleife ist, hört er immer auf zu laufen und läuft noch, auch wenn ich den zweiten Thread starte. Daher werden beide Objekte gleichzeitig in zwei separaten Threads an die Webseite gesendet.

Wie kann ich den ersten Thread stoppen, nachdem ich diese Funktion erneut aufgerufen habe? Oder gibt es eine bessere Umsetzung dieser ganzen Idee, so dass ich es ohne Multithreading machen könnte?

Hinweis: Ich versuchte, die Gleichzeitigkeit von dieser Funktion zu entfernen (wie Multithreading das Ding gibt mir all diese Probleme gewesen ist) und, anstatt sie an den Web-Buchse selbst bewegen, aber dies stellte Probleme wie die Web-Buchse angeschlossen ist zu einem Router, und alles verbindet sich über den Router mit dem Web-Socket.

+0

Haben Sie 'if (nomore) break' versucht? – Dima

Antwort

0

Versuchen Sie AsyncAction, wo Sie ein Future [Ergebnis] als Ergebnis zurückgeben. Machen Sie einen Datenbankaufruf neben diesem Ergebnis. Z. B. (Pseudo-Code),

def getSearchResult = AsyncAction { request => 
val search = request.queryString.get("searchInput").head.head 

val databaseSupport = new InteractWithDatabase(comm, db) 

Future { 
    val data = databaseSupport.getFromDatabase(search) 
    if (data.nonEmpty) { 
    if (data.head.vendorId.equals(search)) { 
     comm.communicator ! data.head // A 
    } 
    } 
    Ok(views.html.singleElement.render) 
} 

}

Besser, wenn databaseSupport.getFromDatabase(search) eine Future gibt, aber das ist eine Geschichte für einen anderen Tag. Der schwierige Teil besteht darin, herauszufinden, wie man mit Actor bei "A" umgeht. Denken Sie daran, am Ausgang muss Future[Result] Ergebnistyp zurückgegeben werden.