Во-первых, весь код находится в https://github.com/JJ/spray-test. Я использую глобальный объект (я не знаю, является ли это правильным поведением Scala) для совместного использования состояния в приложении Spray. put
добавляет к карте, get
получает значения из карты, таким образом:
path( Segment ) { quien =>
get {
println( Apuestas) // also Thread.wait(100)
val esta_apuesta = Apuestas.get( quien )
complete( esta_apuesta )
}
}
(пожалуйста, проверьте весь файл по адресу https://github.com/JJ/spray-test/blob/master/src/main/scala/info/CC_MII/MyService.scala)
Существенными частями тестового кода являются
"Crea apuestas correctamente" in {
Put( "/0/2/Alguien") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Alguien")
}
Put( "/3/0/Menda") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Menda")
}
}
"GET recupera apuesta correctamente" in {
Get("/Alguien") ~> myRoute ~> check {
response.entity should not be equalTo(None)
responseAs[String] must contain("Alguien")
}
}
Проблема в первом куске кода. Если я закомментирую оператор println
, он не сработает и не сработает. Это сообщение об ошибке: [error] 'There was an internal server error.' doesn't contain 'Alguien' (MyServiceSpec.scala:49)
Очевидно, это указывает на то, что часть "получить" еще не сработала, или она находится в другом потоке, или я действительно не понимаю, в чем дело.
Вероятно, это как-то связано с синхронизацией и чем-то подобным, и мне, вероятно, следует объявить Apuestas каким-то другим способом, но я совершенно новичок в этом, и я был бы очень рад просветлению.
Я также включил это как проблему в репозиторий с меткой hacktoberbest
на тот случай, если кто-то заинтересован в продвижении одного PR в этой области. https://github.com/JJ/spray-test/issues
Обновление: похоже, это связано с этим вопросом: Непреднамеренное изменение локальной переменной актера Scala, то есть акторы не должны совместно использовать состояние, но программа должна обеспечить его соблюдение. Дело в том, что они действительно разделяют состояние, но только если мы печатаем. Может быть, введение задержки в потоке будет иметь тот же эффект? Я знаю, что все это плохая манера, наихудшая практика и все такое прочее, но, как сказано выше, я был бы счастлив узнать, как это сделать.
2-е обновление: я пытался синхронизировать методы таким образом:
def add( apuesta: Apuesta ): Apuesta = synchronized {
{
this.apuestas += ( apuesta.quien -> apuesta )
}
apuesta
}
До сих пор нет кости. Мне все еще нужно либо распечатать весь объект Apuesta, либо подождать в потоке, что вызывает больше проблем. Что делает println, чего нельзя сделать с помощью синхронизации?
Обновление 3: после некоторого тестирования println "синхронизирует" только часть времени. Все еще терпит неудачу случайно. Это как-то связано со временем, но не могу понять, как.