2014-04-03 3 views
8

Чтение документа Scala Мне трудно понять разницу между спросом и рассказом.Разница между спросом и рассказом в Акке?

http://doc.akka.io/docs/akka/snapshot/scala/actors.html состояния:

! означает «огонь и забыть», например. отправьте сообщение асинхронно, а немедленно верните. Также известен как сказать.

? отправляет сообщение асинхронно и возвращает Будущее, представляющее возможный ответ . Также известен как ask.

Если актер, которого я использую, запускает веб-запрос, в чем разница между запросом и сообщением? В обоих случаях запрос будет генерироваться асинхронно и должен ждать ответа, другими словами, как «сказать» немедленно вернуться, если актер вызывает веб-службу и ожидает ответа?

ответ

10

Похоже, вы уже знаете основную разницу между ask и tell, но не понимаете, как использовать tell для привлечения других участников при обработке HTTP-запросов.

Для того, чтобы это сделать смысл использовать tell в ваших HTTP обработчики запросов, вы должны использовать сервер HTTP, который не требует, чтобы обработчики запросов возвращают свои ответы. Spray - такой HTTP-сервер.

В спрей обработчик запроса не возвращает свой ответ; ему задан объект RequestContext, и ответ на запрос включает вызов некоторого метода на нем. Вы можете просто отправить этот RequestContext другому актеру, который затем может ответить на запрос:

path("foo") { 
    rc => rc complete "foo" // respond here 
} ~ 
path("bar") { 
    rc => barActor ! DoBar(rc) // send it to bar; NO RESPONSE HERE 
} 

Затем актер ссылается barActor мог сказать

case DoBar(rc) => 
    rc complete "bar" // respond here, in another actor 

Тот факт, что Spray пакеты контекстного запроса в объект, который может быть передан и выполнен с любого актера, отлично подходит для модели актера. Если, с другой стороны, ваша веб-инфраструктура требует, чтобы вызываемый обработчик возвращал ответ, тогда, если вы хотите привлечь другого актера, ваш единственный выбор - использовать ask.

Typesafe объявила, что Play скоро будет использовать спрей снизу. Надеюсь, это означает, что Play затем разрешит отправлять запросы другим субъектам для обработки.

+0

, я понимаю, что Tomcat также обрабатывает запросы асинхронно, и все современные веб-серверы обрабатывают запросы асинхронно, это они не сделали, очень просто для запросов просто стоять в очереди и вызывать медленное время отклика сервера? –

+0

Если вы имеете в виду, что они позволяют вам обрабатывать запросы «асинхронно друг от друга», тогда обязательно - многое сделайте. Я имею в виду, является ли HTTP-сервер вызовом обработчика как метода, который требуется для возврата ответа в качестве результата. В этом случае отдельный субъект не может справиться с ответом; обработчик должен будет вызвать актера, используя ask, получая будущее для результата. Когда результат достигнет, исходный обработчик снова запустится, чтобы обработать ответ. – AmigoNico

+0

Я попытался сделать это более ясным в ответе. – AmigoNico

12

Разница между ask и tell с точки зрения отправителя сообщения (что необязательно является актером). ask отправит сообщение и вернет будущее, которое может быть ожидано до тех пор, пока не будет получен тайм-аут или ответ, tell отправит сообщение и сразу же вернется.

В случае ask актер, который получает сообщение, должен ответить отправителю, когда операция завершена.

+0

Если сообщение немедленно возвращается из процесса, который, например, возвращает 30 секунд, то что он возвращает? Или используется разница, где не следует ожидать, что возвращаемое значение будет запрашиваться, когда ожидаемое значение ожидается в какой-то момент времени? –

+1

Да, точно.Оба сразу возвращаются - говорят, что возвращает 'Unit', то есть ничего не значит, поэтому ожидаемое значение возврата не ожидается. 'ask' возвращает' Future [Any] ', который может быть' await'ed или передан другому субъекту, или 'map'ped для обратного вызова для выполнения. 'ask' намного сложнее и реализуется через неявное преобразование в' akka.pattern.AskableActorRef' –

Смежные вопросы