我应该在演员中包装封锁代码与未来吗?
我有一个关于阻止演员中呼叫处理的问题。我有一个阻止方法调用blokingProcess()
我想在演员中称其为。我是否应该
- 将此
blokingprocess()
future 用专用dispatcher/executionContext
将代码>。 或 - 我应该创建
主管父母
,我将使用专用dispatcher
制作儿童演员
。该儿童演员将处理阻止呼叫blokingProcess()
,而没有任何未来
包装器。
注意,我还可以通过将用
专用dispatcher/executionContext
与No Actor中的Future
一起呼叫blokingprocess()
。我的程序一次会产生如此多的阻止电话。我不需要回复。
我知道这是非常愚蠢的问题。但是寻找专家的建议。
I have a question regarding of blocking call handling within an actor. I have a blocking method call blokingProcess()
I want to call it within an actor. Should I have to
- Wrap this
blokingProcess()
byFuture
with a dedicateddispatcher/ExecutionContext
in an actor then usingpipeTo self
. Or - I should create a
supervisor parent actor
under which I will producechild actor
with dedicateddispatcher
. That child actor will handle the blocking callblokingProcess()
without anyFuture
wrapper .
Note I can also call blokingProcess()
by wrapping with Future
with dedicated dispatcher/ExecutionContext
with in no actor. My programme will generate so many blocking calls at a time . I don't need response back.
I know this is very silly question. But looking for experts' suggestions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,您不想在
Actorsystem
的主要调度器池的线程上执行长期的螺纹阻挡工作。这是因为它是同一池处理所有您应用程序中的事件(除非专门针对另一个池) - 因此,如果该池被阻塞的线程饱和,则您的应用程序将死亡。我建议的模式是设置a for IO结合的阻塞工作。然后,您可以通过单个演员之一以两种方式之一:
或以亲子方式使用,在这里,IO结合的调度员用于孩子所做的所有工作:
让孩子在其上进行阻止动作主线程将是IO结合调度员池的线程。
第二种方法的优点是,它使恢复/监督像其他任何演员一样起作用;换句话说,如果您的阻塞操作会引发未被发现的例外,它将起泡监督堆栈,直到处理为止。这可能是您想要的,也可能不是您想要的。
无论哪种情况,最好添加围绕阻止代码的登录,这将使您可以检查操作发生的线程名称。 (警告!akka的默认记录日志默认值线程池上的所有事件;您必须明确要求从MDC中添加日志事件的
sourcethread
添加到日志输出中。)注意。设计了所有Akka自己的IO原语(例如HTTP客户端,Kafka消费者等)(通常是通过流API)设计的,以不阻止调度程序线程。因此,除非您非常非常确保他们正在引起线池饥饿(而不仅仅是它的受害者),否则您不应将其移至其他调度员。
You generally don't want to perform long-running thread-blocking work on threads of your
ActorSystem
's main dispatcher pool. This is because it is that same pool that handles all the events in your application (unless specifically directed to another pool) -- so if that pool gets saturated with blocked threads, your application will deadlock.The pattern I recommend is to set up a separate dispatcher for IO-bound blocking work. Then you can use in one of two ways, either in a single actor:
or in a parent-child fashion, where the IO-bound dispatcher is used for all work done by the child:
and have the child run the blocking action on its main thread, which will be a thread from the IO-bound dispatcher's pool.
The advantage to the second approach is it makes recovery/supervision work like it does for any other actor; in other words, if your blocking operation throws an uncaught exception, it will bubble up the supervision stack until handled. This may or may not be what you want.
In either case, it's always good to add some logging around the blocking code which will allow you to inspect the thread name that the action is occurring on. (Warning! Akka's default logging logs all events on the default thread pool; you have to explicitly request that the log event's
sourceThread
from MDC is added to the log output.)Note that all of Akka's own IO primitives (e.g. HTTP client, Kafka consumer, etc.) are designed (usually by means of the Streams APIs) to not block dispatcher threads. So you should not move these to other dispatchers unless you are very, very sure that it is they that are causing thread-pool starvation (and not merely being the victim of it).
我的答案是
Future
中,并使用阻止
如果将
blockingprocess
放入阻止
block中,则调度程序可以为该Future
使用专用线程,并避免僵局的风险。对我来说,使用单独的调度员或儿童演员感觉就像是过度杀伤。
这确实取决于所使用的特定调度程序,因此请参见在这里有关更多详细信息。
My answer is
Future
and useblocking
If you put
blockingProcess
inside ablocking
block then the dispatcher can use a dedicated thread for thatFuture
and avoid the risk of deadlock.Using separate dispatchers or child actors feels like overkill to me.
This does depend on the particular dispatcher being used, so see here for more details.