Узаемадзеянне з Akka акцёра па-за акцёраў

Я хачу, каб ўзаемадзейнічаць з акцёрамі Akka з уласнага патоку. У цяперашні час, я раблю так:

val res = Await.result(aref ? GroupReceive(fromRank), timeout.duration).asInstanceOf[T]

But I am unsure how this actually interacts with my thread? I wish for the receive to be asynchronous, i.e. I want to hang up the thread while receiving to allow for some other work to be done. I just recently read about Akka inbox system. inbox akka api

Я думаю, што я памятаю, што Await стварае новы акцёр кожны раз. Якія адрозненні паміж AWAIT + спытаць і паштовую скрыню, а кто-то можа даць мне прыклад таго, як стварыць паштовую скрыню і выкарыстоўваць яго для зносін з акцёрамі з «звонку»?

EDIT Just to clarify, I don't want the same thread to continue working, I want it to stop hogging a cpu-core and leave other threads to work until it receives something, then wake up again.

10
У Акко вы павінны лепш выкарыстоўваць МАПТО [Type] замест asInstanceOf
дададзена аўтар 4lex1v, крыніца
@senia яна вяртае новы ActorRef з механізмам ActorSelection, але не новы акцёр
дададзена аўтар 4lex1v, крыніца
@senia прабачце ніколі не выкарыстоўваў AKKA DSL, але, як я магу зразумець з гэты радок не стварае новага акцёра, але вяртае будучыню з спасылкай акцёра
дададзена аўтар 4lex1v, крыніца
@senia прабачце ніколі не выкарыстоўваў AKKA DSL, але, як я магу зразумець з гэты радок не стварае новага акцёра, але вяртае будучыню з спасылкай акцёра
дададзена аўтар 4lex1v, крыніца
Так, вы можаце прачытаць аб выкарыстанні AKKA і ф'ючэрсаў тут
дададзена аўтар 4lex1v, крыніца
Так, вы можаце прачытаць аб выкарыстанні AKKA і ф'ючэрсаў тут
дададзена аўтар 4lex1v, крыніца
У Акко вы павінны лепш выкарыстоўваць МАПТО [Type] замест asInstanceOf
дададзена аўтар 4lex1v, крыніца
Таксама Await не можа ствараць новыя акцёр, гэта адзіная мэта складаецца ў тым, каб блакаваць выкананне да таго часу ў чаканні выніку. Адзіны спосаб стварыць акцёра праз system.actorOf (...)
дададзена аўтар 4lex1v, крыніца
Таксама Await не можа ствараць новыя акцёр, гэта адзіная мэта складаецца ў тым, каб блакаваць выкананне да таго часу ў чаканні выніку. Адзіны спосаб стварыць акцёра праз system.actorOf (...)
дададзена аўтар 4lex1v, крыніца
<�Код> asInstanceOf згенеруе выключэнне, калі ён выходзіць з ладу. <�Код> МАПТО вяртае які адмовіў будучыню.
дададзена аўтар drexin, крыніца
<�Код> asInstanceOf згенеруе выключэнне, калі ён выходзіць з ладу. <�Код> МАПТО вяртае які адмовіў будучыню.
дададзена аўтар drexin, крыніца
Небяспечная справа, што asInstanceOf сапраўды можа дамагчыся поспеху і не пазней, калі канкрэтны метад.
дададзена аўтар drexin, крыніца
Небяспечная справа, што asInstanceOf сапраўды можа дамагчыся поспеху і не пазней, калі канкрэтны метад.
дададзена аўтар drexin, крыніца
@AlexIv: system.actorOf (...) гэта не адзіны спосаб стварэння акцёра. <�Код> задаць або стварае новага акцёра, ActorDSL.inbox стварае новы акцёр.
дададзена аўтар senia, крыніца
@AlexIv: system.actorOf (...) гэта не адзіны спосаб стварэння акцёра. <�Код> задаць або стварае новага акцёра, ActorDSL.inbox стварае новы акцёр.
дададзена аўтар senia, крыніца
Існуе прыклад у дакументацыі </а>.
дададзена аўтар senia, крыніца
Існуе прыклад у дакументацыі </а>.
дададзена аўтар senia, крыніца
У чым карысць? :)
дададзена аўтар Felix, крыніца
У чым карысць? :)
дададзена аўтар Felix, крыніца
Ці ёсць боры ніткі хоць?
дададзена аўтар Felix, крыніца
Ці ёсць боры ніткі хоць?
дададзена аўтар Felix, крыніца

6 адказы

Як напісана ў будучай дакументацыі Акки, у не выкарыстоўваючы чаканне блакуе бягучы паток да таго часу, чакаючы вынік.

прыклад

import scala.concurrent.Await
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._

implicit val timeout = Timeout(5 seconds)
val future = actor ? msg//enabled by the “ask” import
val result = Await.result(future, timeout.duration).asInstanceOf[String]

<�моцны> Гэта прымусіць бягучы паток, каб блакаваць і чакаць акцёра на «поўнае» будучыню з яго адказам. </Р>

Выкарыстанне З Акцёраў

8
дададзена
Няма неабходнасці блакаваць. Як ужо згадвалася ў дакументацыі, вы можаце імпартаваць scala.concurrent.Future і akka.pattern.ask, а затым VAL будучыню: будучыня [String] = спытаць (акцёр, сбщ) .mapTo [String]
дададзена аўтар matanster, крыніца
@senia ўсё яшчэ не згодныя з вамі, папытаеце вярнуць будучыню з ActorRef праз ActorSelection, але гэта не стварае новы акцёр
дададзена аўтар 4lex1v, крыніца
@Felix На жаль ніколі не выкарыстоўваў AKKA DSL, але, як я магу ўбачыць галоўнае выкарыстанне паштовага скрыні з'яўляецца тое, што просіць не 1) можа атрымліваць некалькі адказаў і 2) глядзець жыццёвы цыкл іншых акцёраў. The Уваходныя
дададзена аўтар 4lex1v, крыніца
@AlexIv: Вы правільныя.
дададзена аўтар senia, крыніца
@Alexlv, калі вы карыстаецеся спытаць па-за акцёра, часовы акцёр ствараецца пад капотам. Гэта адбываецца таму, што для таго, каб адказаць вам патрэбен акцёр реф адправіць назад праз! аператар. Акцёр нядоўгі і спыняецца пасля таго, як будзе атрыманы адказ або ўзнікае тайм-аўт.
дададзена аўтар cmbaxter, крыніца
Вы можаце ўдакладніць розніцу паміж гэтым і выкарыстаннем паштовай скрыні?
дададзена аўтар Felix, крыніца
як я мог бы выкарыстаць гэта з BroadcastRouter, які павінен адказаць некалькі раз для кожнага будучага? Дзякуй.
дададзена аўтар Trylks, крыніца

Як напісана ў будучай дакументацыі Акки, у не выкарыстоўваючы чаканне блакуе бягучы паток да таго часу, чакаючы вынік.

прыклад

import scala.concurrent.Await
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._

implicit val timeout = Timeout(5 seconds)
val future = actor ? msg//enabled by the “ask” import
val result = Await.result(future, timeout.duration).asInstanceOf[String]

<�моцны> Гэта прымусіць бягучы паток, каб блакаваць і чакаць акцёра на «поўнае» будучыню з яго адказам. </Р>

Выкарыстанне З Акцёраў

8
дададзена
Няма неабходнасці блакаваць. Як ужо згадвалася ў дакументацыі, вы можаце імпартаваць scala.concurrent.Future і akka.pattern.ask, а затым VAL будучыню: будучыня [String] = спытаць (акцёр, сбщ) .mapTo [String]
дададзена аўтар matanster, крыніца
@senia ўсё яшчэ не згодныя з вамі, папытаеце вярнуць будучыню з ActorRef праз ActorSelection, але гэта не стварае новы акцёр
дададзена аўтар 4lex1v, крыніца
@Felix На жаль ніколі не выкарыстоўваў AKKA DSL, але, як я магу ўбачыць галоўнае выкарыстанне паштовага скрыні з'яўляецца тое, што просіць не 1) можа атрымліваць некалькі адказаў і 2) глядзець жыццёвы цыкл іншых акцёраў. The Уваходныя
дададзена аўтар 4lex1v, крыніца
@AlexIv: Вы правільныя.
дададзена аўтар senia, крыніца
@Alexlv, калі вы карыстаецеся спытаць па-за акцёра, часовы акцёр ствараецца пад капотам. Гэта адбываецца таму, што для таго, каб адказаць вам патрэбен акцёр реф адправіць назад праз! аператар. Акцёр нядоўгі і спыняецца пасля таго, як будзе атрыманы адказ або ўзнікае тайм-аўт.
дададзена аўтар cmbaxter, крыніца
Вы можаце ўдакладніць розніцу паміж гэтым і выкарыстаннем паштовай скрыні?
дададзена аўтар Felix, крыніца
як я мог бы выкарыстаць гэта з BroadcastRouter, які павінен адказаць некалькі раз для кожнага будучага? Дзякуй.
дададзена аўтар Trylks, крыніца

<�Код> Await.receive з'яўляецца часткай паралелізм API Scala і не мае нічога агульнага з акцёрамі. Яго мэта складаецца ў тым блоку бягучы паток да таго часу, забяспечанае будучыня не завершыцца, ці таймаўт памірае, і ўсё гэта заканчваецца выключэннем тайм-аўту.

Задаць аператар сапраўды стварыць часовы акцёр з адзінай мэтай чакае адказу ад акцёра, на які паказвае Арэфы зменнай і завяршаючы будучыню вы атрымалі, калі вы называецца папрасіць аператара з атрыманым адказам.

Такім чынам, ваш код па сутнасці блакуе ўвесь струмень. Як было паказана, калі вы хочаце, каб вызваліць бягучы паток і працягваць рабіць іншую працу, якую вы можаце прымацаваць функцыю зваротнага выкліку ў будучыні.

implicit val ctx: ExecutionContext = //provide execution context here
implicit val timeout: Timeout =//provide timeout here
aref ? GroupReceive(fromRank)) onSuccess { res =>
   //do something with res here, asynchronously
}
// some other code which runs without being blocked...

Прыведзены вышэй код можна перапісаць з акцёрам DSL вы згадалі вышэй:

import akka.actor.ActorDSL._
implicit val actorSystem: ActorSystem =//provide an actor system here or any actor ref factory

actor(new Act {
  aref ! GroupReceive(fromRank)
  context.setReceiveTimeout(timeout) //optional
  become {
    case ReceiveTimeout => {
      //handle the timeout
      context.stop(self)
    }
    case res => {
      //do your thing with res, asynchronously
      context.stop(self)
    }
  }
}

//some other code which won't wait for the above operations

Апошняя версія таксама стварае новы часовы акцёр, які пасылае GroupReceive паведамленне і чакае адказу, пасля чаго ён забівае сябе.

Сутнасць заключаецца ў тым, што для таго, каб атрымаць паведамленне ад акцёра вы павінны быць акцёрам самастойна. Акцёры не могуць проста адправіць паведамленне на нешта іншае, акрамя ActorRef .

Так як вы карыстаецеся шаблон спытаць, які стварае часовы акцёр за кулісамі і кіруе самім жыццёвым цыклам гэтага часовага акцёра, агаляючы вам проста прыемна простае будучыню, каб працаваць, ці вы можаце стварыць часовы акцёр самастойна, але тады вы павінны кіраваць яго жыццёвы цыкл (г.зн. памятаеце, каб забіць яго, як толькі ён зрабіў сваю працу)

Выберыце той варыянт, які падыходзіць вам лепш за ўсё.

4
дададзена
Што тычыцца DSL, напрыклад, частка вашага адказу: хоць гэта працуе для больш высокіх запытаў часу чакання для вельмі хуткага запыту/адказу можа не спрацаваць, таму што стаць займае некаторы час, каб штурхнуць ў DSL-дзеянні павінны быць ініцыялізаваны гэтак жа, як у гэтым пытанні, каб заўсёды працаваць .: stackoverflow.com/questions/17851849/& hellip; .
дададзена аўтар radekg, крыніца

<�Код> Await.receive з'яўляецца часткай паралелізм API Scala і не мае нічога агульнага з акцёрамі. Яго мэта складаецца ў тым блоку бягучы паток да таго часу, забяспечанае будучыня не завершыцца, ці таймаўт памірае, і ўсё гэта заканчваецца выключэннем тайм-аўту.

Задаць аператар сапраўды стварыць часовы акцёр з адзінай мэтай чакае адказу ад акцёра, на які паказвае Арэфы зменнай і завяршаючы будучыню вы атрымалі, калі вы называецца папрасіць аператара з атрыманым адказам.

Такім чынам, ваш код па сутнасці блакуе ўвесь струмень. Як было паказана, калі вы хочаце, каб вызваліць бягучы паток і працягваць рабіць іншую працу, якую вы можаце прымацаваць функцыю зваротнага выкліку ў будучыні.

implicit val ctx: ExecutionContext = //provide execution context here
implicit val timeout: Timeout =//provide timeout here
aref ? GroupReceive(fromRank)) onSuccess { res =>
   //do something with res here, asynchronously
}
// some other code which runs without being blocked...

Прыведзены вышэй код можна перапісаць з акцёрам DSL вы згадалі вышэй:

import akka.actor.ActorDSL._
implicit val actorSystem: ActorSystem =//provide an actor system here or any actor ref factory

actor(new Act {
  aref ! GroupReceive(fromRank)
  context.setReceiveTimeout(timeout) //optional
  become {
    case ReceiveTimeout => {
      //handle the timeout
      context.stop(self)
    }
    case res => {
      //do your thing with res, asynchronously
      context.stop(self)
    }
  }
}

//some other code which won't wait for the above operations

Апошняя версія таксама стварае новы часовы акцёр, які пасылае GroupReceive паведамленне і чакае адказу, пасля чаго ён забівае сябе.

Сутнасць заключаецца ў тым, што для таго, каб атрымаць паведамленне ад акцёра вы павінны быць акцёрам самастойна. Акцёры не могуць проста адправіць паведамленне на нешта іншае, акрамя ActorRef .

Так як вы карыстаецеся шаблон спытаць, які стварае часовы акцёр за кулісамі і кіруе самім жыццёвым цыклам гэтага часовага акцёра, агаляючы вам проста прыемна простае будучыню, каб працаваць, ці вы можаце стварыць часовы акцёр самастойна, але тады вы павінны кіраваць яго жыццёвы цыкл (г.зн. памятаеце, каб забіць яго, як толькі ён зрабіў сваю працу)

Выберыце той варыянт, які падыходзіць вам лепш за ўсё.

4
дададзена
Што тычыцца DSL, напрыклад, частка вашага адказу: хоць гэта працуе для больш высокіх запытаў часу чакання для вельмі хуткага запыту/адказу можа не спрацаваць, таму што стаць займае некаторы час, каб штурхнуць ў DSL-дзеянні павінны быць ініцыялізаваны гэтак жа, як у гэтым пытанні, каб заўсёды працаваць .: stackoverflow.com/questions/17851849/& hellip; .
дададзена аўтар radekg, крыніца

Калі вы не хочаце, каб заблакаваць на выклікалай баку, то не выкарыстоўвайце ЧАКАЮЦЬ, выкарыстоўвайце неблокирующем зваротныя выклікі замест як OnSuccess, OnFailure і OnComplete. Калі вы зробіце гэта, будучая задача ставіцца ў любую ExecutionContext знаходзіцца ў вобласці бачнасці падчас спытаць (?). Калі адказ атрыманы, гэты зваротны выклік выклікаецца асінхронна праз выкананьне ExecutionContext. Такім чынам, вы пазбегнуць блокаў зараз усе разам у патоку, які робіць запыт на акцёр, а затым зваротны выклік апрацоўваецца ў пуле патокаў, прывязаны да выканання ExecutionContext.

Акрамя таго, я лічу, што паштовая скрыня матэрыял вы згадваеце арыентаваны на тэстуючы акцёр матэрыялу ў Рэпля (прынамсі, гэта тое, што дакументы на ActorDsl) станах. Палка з падыходам вы павінны выкарыстоўваць спытаць звонку акцёра. Хай Akka стварыць недаўгавечны акцёр, які неабходны для сувязі пад капотам для не-акцёра акцёра званкоў. Тады проста пераключыцца на ня блакавальны зваротны выклік, як я прапанаваў вышэй. Я лічу, што гэта тое, што вы шукаеце.

0
дададзена

Калі вы не хочаце, каб заблакаваць на выклікалай баку, то не выкарыстоўвайце ЧАКАЮЦЬ, выкарыстоўвайце неблокирующем зваротныя выклікі замест як OnSuccess, OnFailure і OnComplete. Калі вы зробіце гэта, будучая задача ставіцца ў любую ExecutionContext знаходзіцца ў вобласці бачнасці падчас спытаць (?). Калі адказ атрыманы, гэты зваротны выклік выклікаецца асінхронна праз выкананьне ExecutionContext. Такім чынам, вы пазбегнуць блокаў зараз усе разам у патоку, які робіць запыт на акцёр, а затым зваротны выклік апрацоўваецца ў пуле патокаў, прывязаны да выканання ExecutionContext.

Акрамя таго, я лічу, што паштовая скрыня матэрыял вы згадваеце арыентаваны на тэстуючы акцёр матэрыялу ў Рэпля (прынамсі, гэта тое, што дакументы на ActorDsl) станах. Палка з падыходам вы павінны выкарыстоўваць спытаць звонку акцёра. Хай Akka стварыць недаўгавечны акцёр, які неабходны для сувязі пад капотам для не-акцёра акцёра званкоў. Тады проста пераключыцца на ня блакавальны зваротны выклік, як я прапанаваў вышэй. Я лічу, што гэта тое, што вы шукаеце.

0
дададзена