J'ai un problème avec ma compréhension de la bibliothèque d'acteur standard dans Scala. Dans le code ci-dessous j'ai créé un simple swing, qui devrait essentiellement tester s'il est capable de se connecter à un serveur PostgreSQL. Cependant, cela ne va pas si loin, j'utilise Actors puisque l'interface utilisateur se bloquerait en faisant le travail nécessaire pour se connecter à la base de données. Lorsque er j'utiliser cette ligne (ce qui signifie que j'utilise des acteurs au lieu d'un seul fil)Scala Les acteurs suspendent inattendu lors de la connexion à une base de données
PostgresCheck ! new GetInfo()
Swing ne sera jamais mis à jour. Cependant, si je commente la ligne et utilise les trois lignes suivantes. (ce qui signifie que les acteurs ne seront pas utilisés)
val result = PostgresCheck.checkPostgreSQL
if (result == "OK") pgText.background = GREEN else pgText.background = RED
pgText.text = result
Le Swing se fige mais après environ 25 secondes, le swing sera mis à jour.
import dbc.Database
import dbc.vendor.PostgreSQL
import java.awt.Dimension
import java.net.URI
import java.sql.Connection
import swing.event._
import swing._
import actors.Actor
import java.awt.Color._
import scala.actors.Actor._
case class Info(reply: String)
case class GetInfo()
object Example extends SimpleSwingApplication {
val pgButton = new Button("Check PostgreSQL")
val pgText = new TextArea("Not Checked Yet")
val pgPanel = new GridPanel(1, 2)
pgPanel.contents += pgButton
pgPanel.contents += pgText
def top = new MainFrame {
title = "StateChecker"
contents = pgPanel
}
listenTo(pgButton)
reactions += {
case e: ButtonClicked if (e.source.eq(pgButton)) => {
PostgresCheck ! new GetInfo()
//val result = PostgresCheck.checkPostgreSQL
//if (result == "OK") pgText.background = GREEN else pgText.background = RED
//pgText.text = result
}
}
val guiActor = new Actor {
def act() = {
loop {
react {
case e: String => {
val result = e
if (result == "OK") pgText.background = GREEN else pgText.background = RED
pgText.text = result
}
case e => println(e.toString)
}
}
}
}
guiActor.start
}
object PostgresCheck extends Actor {
def checkPostgreSQL() = {
try {
val db = new Database(myPgSQL)
val con: Connection = myPgSQL.getConnection // Freezes while doing this method
val statement = con.createStatement
if (statement.getResultSet.getMetaData.getColumnCount == 1) "OK"
else statement.getWarnings.toString
}
catch {
case e => e.toString
}
}
def act() = {
loop {
react {
case e: GetInfo => {
sender ! new Info(checkPostgreSQL)
}
}
}
}
start()
}
object myPgSQL extends PostgreSQL {
val uri = new URI("jdbc:postgresql://whatever.com")
val user = "1234"
val pass = "1234"
}
Pouvez-vous sauvegarder une trace de pile lorsque votre application se bloque? Sur les fenêtres, CTRL-BREAK dans la fenêtre de la console, sur Unix, 'kill -QUIT pid', où pid est l'ID du processus. – retronym
Sous les paramètres de configuration standard, CTRL- \ génère un signal QUIT sous Unix et Linux. –
Etes-vous sûr que l'initialisation de PostgresCheck est déjà exécutée? (C'est-à-dire si vous mettez un 'println (" Running ")' après le 'start()', le voyez-vous?) Est-ce que vous le faites dans la déclaration de réaction de guiActor? –