【问题标题】:How do I prevent multiple discordrb bot activations being processed out of sequence?如何防止多个 discordrb bot 激活被乱序处理?
【发布时间】:2020-07-26 05:29:09
【问题描述】:

我有一个 Ruby Discord (discordrb) 机器人,用于管理 D&D 角色。我注意到当多个玩家同时提交相同的命令时,他们各自收到的结果并不独立。一个玩家的请求(为他们的角色分配武器)最终被分配给同时提交相同请求的其他角色。我希望每个请求都按顺序单独执行。如何防止交叉请求?

bot.message(contains:"$Wset") do |event|
    inputStr = event.content; # this should contain "$Wset#" where # is a single digit
    check_user_or_nick(event);  pIndex = nil;  #fetch the value of @user & set pIndex
    (0..(@player.length-1)).each do |y|  #find the @player pIndex within the array using 5 char of @user
        if (@player[y][0].index(@user.slice(0,5)) == 0) then pIndex = y;  end; #finds player Index Value (integer or nil)
    end;
    weaponInt = Integer(inputStr.slice(5,1)) rescue false; #will detect integer or non integer input
    if (pIndex != nil) && (weaponInt != false)  then; 
       if weaponInt < 6 then;
           @player[pIndex][1]=weaponInt;
           say = @player[pIndex][0].to_s + " weapon damage has be set to " + @weapon[(@player[pIndex][1])].to_s;
          else;
              say = "Sorry, $Wset requires this format: $Wset?  where ? is a single number ( 0 to 5 )";         
          end;
    else
       say = "Sorry, $Wset requires this format: $Wset?  where ? is a single number ( 0 to 5 )"; 
    end;
    event.respond say;
end;

【问题讨论】:

  • 顺便说一句,这里有很多不习惯的东西,例如then; 可以简单地删除,因为它没有任何效果(更广泛地说,分号是 not在 Ruby 中需要)。不过,那是另一天的讨论 - 我会推荐你​​到rubocop's style guide

标签: ruby discord


【解决方案1】:

为避免此类多线程代码中的竞争条件,您要查找的主要内容是副作用

bot.message(contains:"$Wset") do |event| 块视为小程序线程。这里的所有内容都应该自包含 - 应该无法影响任何其他线程。

最初浏览您的代码,我正在搜索的是任何共享变量。如果它们同时被多个线程读取/写入,则会产生竞争条件。

在这种情况下,有 2 个明显的违规者 - @player@user。这些应该被重构为局部变量而不是实例变量。在块中定义它们,这样它们就不会影响任何其他范围,例如:

# Note, for this to work, you will have to change
# the method definition to return [player, user]

player, user = check_user_or_nick(event)

有时,线程产生副作用是不可避免的(假设您想计算线程运行的次数)。为了防止在这些情况下出现竞争条件,Mutex 通常是解决方案,但如果代码在多台机器上运行,有时也可以使用distributed lock。但是,从您显示的代码来看,您似乎不需要这些东西。

【讨论】:

  • 太棒了!我在代码主体中引入了 check_user_or_nick(event) 的功能,因为它决定了唯一用户。问题已解决。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 2015-12-17
  • 2015-12-02
  • 2020-10-08
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多