并行响应多个传入的Slack-Bot请求

时间:2018-06-28 06:27:23

标签: python multithreading python-multiprocessing slack

作为该领域的新手,我一直在尝试使用线程解决GIL限制,以便为我的自定义Slack机器人(用python编写)处理多个传入的RTM事件

用例: 一个Slack Bot,它将被添加到几个通道,必须同时服务多个请求(机器人命令)

面临的挑战 由于python中的Threading遵循GIL的概念,因此传入的bot请求实际上不是 并行执行的。

解决方案进行了调查: 作为替代方案,我正在研究multiprocessing.pool,它将使我产生许多可以互斥的方式满足每个请求的工作程序。

问题:由于我在同时循环中无限地轮询传入的事件,因此我需要找到一种方法来生成进程响应每个传入请求,而不会阻塞另一个请求的处理(可以在相同时间从另一个渠道发布)而不会耗尽所有可用内存。< / p>

代码

slack_client = SlackClient(<bot_token>)
if slack_client.rtm_connect(auto_reconnect=True):
     while True:
         incoming_events = slack_client.rtm_read()
         command = parse_bot_mention(incoming_events) #this method returns the command issued to the bot in specific
         if command:
             handle_command_thread = Thread(target=handle_bot_command, args=(command))
             handle_command_thread.start()
         time.sleep(1) #RTM read delay of 1 sec

当我将此漫游器订阅到单个频道,并且有多个命令发布时,这种方法可以正常工作。问题是当存在多个参与者/通道的多通道时,响应时间会很长。

是否可以采用任何方法/编程范例来解决此问题?

1 个答案:

答案 0 :(得分:0)

似乎您在处理并发性时遇到了Python的弱点之一。杜德,那真是痛苦!我将把您的一些想法限制在您的问题范围内,但不要在我犯下我的最大 StackOverflow宠物烦恼之前...通过告诉您完全尝试其他方法来回答您的问题...

烦人的答案:您正在描述的用例似乎需要一个使并发成为一等公民的工具,这就是为什么我建议您考虑使用Golang的原因。来自非常沉重的Python背景,我发现拿起Golang并不是很困难。 Golang使用“例程”轻松处理类似您遇到的问题。它还具有许多您应该签出的其他非常好的功能(例如键入..哦,是的!)。如果您习惯了Python Dev的工作,乍一看有点奇怪,但是在您掌握了概念之后,这相当简单!

不烦人的答案:好的,如果您阅读以上内容,我会很感激,让我在您的问题范围内提出一些想法。

  1. 一种选择是使用您提到的MultiProcessing库。您最好的选择可能是实例化一组工作人员。当程序通过while循环工作并注册已给出命令时,它将把该命令传递给开放工作者以完成工作。

因此,您将创建一个函数,将类似

的内容插入while循环中
Def Dispatch_worker_boi(self, command):
    use multiprocessing function to pitch to a worker (see Pool.apply_async)
  1. 想到的唯一另一个想法是AsyncIO软件包。如果您的机器人在等待侦听命令响应,它可能会派上用场。不过,老实说,我对该程序包的经验要少得多。值得一看!

最后的注释: Chiragjn列出的另一种方法是使用某种类型的排队服务,例如芹菜。这将使您能够坚持使用Python,并且比纯Python方法具有更多的可伸缩性。不过,老实说,如果您要处理的规模很大,Golang将为您提供良好的服务。

希望这对您有所帮助,请随时提供反馈!