【问题标题】:Controlling Java and Lotusscript agents控制 Java 和 Lotusscript 代理
【发布时间】:2011-11-11 20:54:33
【问题描述】:

我创建了 2 个代理,一个由 Java 制成,另一个由 Lotusscript 制成。 java 代理每 5 分钟运行一次,而 lotusscript 代理每 15 分钟运行一次。因此,它们将同时运行。发生这种情况时,java 代理必须暂停/等待,直到 lotusscript 代理完成。我尝试使用 Profile DOcuments 和 Environment Variables 来模拟锁定,但无济于事。有没有一种方法可以模拟这两个不同代理之间的锁定?请帮忙。非常感谢!

编辑:我忘了说这 2 个代理驻留在两个不同的数据库中,让事情变得更加复杂:(

【问题讨论】:

    标签: java lotus-notes lotus-domino lotusscript agents


    【解决方案1】:

    在数据库中启用文档锁定可能会起作用。如果您可以在数据库本身中启用文档锁定,您可以让代理锁定特定文档并检查文档在运行代码之前/期间是否被锁定。

    如果在该数据库中启用文档锁定不是一个选项,您可以考虑创建一个单独的数据库来存储文档。

    为什么这些代理不能同时运行?也许可以在允许代理同时运行的同时实现相同的结果。试图以这种方式控制代理通常会导致其他问题。如果数据库有副本,解决方案可能会中断。

    【讨论】:

    • java 代理从 web 服务数据创建文档,然后删除重复项,而 lotusscript 代理从 java 代理所在的数据库中提取文档。如您所见,如果 Java 代理发现拉取文档尚未完成,则应暂停,否则也会拉取重复的文档。
    • 重复文件是由 Java 代理创建但尚未由 Lotus Script 代理提取的文档?
    • 是的。然后,java 代理必须删除文档的旧副本(即“重复”),以便在每次 lotusscript 代理拉取文档时都会拉取最新的副本。
    • 是否启用文档锁定选项?您可以锁定文档并进行更新,而不是删除。
    • 没有。旧文件不能只是被锁定。数据库每 5 分钟从 Web 服务数据创建文档,因此数据增长迅速。
    【解决方案2】:

    这是我发现的一种近乎万无一失的方法,可用于控制独立代理的执行顺序。我使用真实的笔记文档作为伪锁定文档。

    我之前这样做的方法是保留一个代表“锁”的 Notes 文档。不要使用数据库配置文件,因为它容易出现复制/保存冲突问题,并且您无法在视图中查看它。

    “锁定”文档上可以有一个标志,告诉 java 代理现在是否允许运行。 Java 代理只是在其中包含类似于此的代码

    Session s = NotesFactory.createSession();
    Database db = s.getDatabase("This Server", "This database");
    View vw = db.getView("(lockView)");
    Document docControl = vw.getFirstDocument();
    String sRunStatus = docControl.getItemValueString("runStatus");
    boolean bContinue = false;
    if (sRunStatus =="Go"){
        bContinue = true;
    }
    if(bContinue){
        //do agent code here....
    
        // reset the status to "wait". The lotusscript agent should then set it to "Go"
        // the other agent will execute on "wait" and then update the status to "Go" on 
        // completion to prevent simulatenous execution. Can also use different state names
        // instead of go/wait, like run0, run1, run2 etc
        docControl.replaceItemValue("runStatus", "wait");
        docControl.save(true);
    }
    

    请注意,您使用代理在控制文档的“runStatus”字段中设置“Go”/“wait”值。您只需要 1 个文档,因此您只需将第一个文档移出视图即可。

    在 LotusScript 代理中添加等效逻辑应该更简单。我能找到的唯一缺点是 java 代理可能不会执行代码,因为控制文档尚未设置为“go”并且“IF”测试在没有运行逻辑的情况下失败,所以它不是这样的暂停,而是防止Java 代理与 lotusscript 代理的执行顺序不一致。但如果 LotusScript 代理已释放它,它将在下一个计划实例上触发。

    您还可以通过使用“RunAgent1”、“RunAgent2”等特定值来扩展这个想法来管理一组代理,甚至链接多个代理,另一个好处是您还可以捕获执行开始时间、错误以及,或任何你需要的东西......

    【讨论】:

    • 如果您不将它与 Notes/Domino 的文档锁定功能一起使用,您将不会满意。如果两个代理“同时”运行,读取“runStatus”,查看“Go”并在更新文档(可能创建冲突文档)后都运行,会发生什么?正如 Jasper 已经指出的那样,如果您像这样引入信号量,则需要文档锁定。
    • 不可能。如果您更仔细地阅读我编写的逻辑,您会发现为每个代理运行使用特定状态,只会允许该特定代理运行。我没有说两个代理都像你暗示的那样在“Go”上执行。因此,如果“agentA”在“Go”上执行,而“agentB”在“Wait”上执行,那么即使两者同时执行,也只有 1 个 agent 将实际执行所需的业务逻辑。我已经更新了答案,以更明确地说明您提出的观点。如果您在此基础上修改您的反对票,我将不胜感激。
    • 这真的是等待吗?看起来更像是取消,下次试试。我会尝试使用 Thread.sleep() 让它等待 x 秒,然后再试一次。
    • 我修改了下面的代码(实际上在你回答之前我确实使用配置文件实现了类似的东西)。我没有使用简单的 continue 事件,而是执行了一个无限循环,等待锁定文档中的值更改。我知道在Java中,数据是按值传递的,因此我所做的就是在while的条件下一次又一次地获取文档,以确保新文档被传递。但是,当 2 个代理同时运行时,锁定文档中的更改仍然没有出现。
    • @Jairo,你不应该有一个无限循环,这将阻塞代理管理器上的一个队列,如果你只有一个队列,你将阻止代理执行,直到达到代理的超时限制。这也会使服务器达到服务器上代理的最大 CPU 限制。我相信默认设置为 70%。所以不要做无限循环。如果频率很关键,您可以从 LS 代理启动 java 代理。它也有一些风险,但比无限循环要好得多。还有其他方法,但这会开始重新编码您的代理。
    【解决方案3】:

    为什么不编写第三个代理(可能在一个额外的数据库中),它每五分钟定期运行一次,从而启动其他两个代理:

    1. Lo​​tus 脚本代理每次
    2. Java 代理每三次运行一次

    ...那么您也可以控制运行顺序,无需任何复杂的锁定机制。

    【讨论】:

    • 其实这个答案真的很好!如果我能完成这项工作,我会检查一下!谢谢。
    • 我见过这种方式,在比较简单的情况下还可以,小规模也可以。但是我已经看到这种方法使服务器崩溃。它的主要风险是当代理调用其他代理时,它不再受服务器对代理的设置的控制。服务器具有限制设置以阻止代理消耗 100% cpu。从其他代理调用的代理可以做他们喜欢做的事情。此外,您将无法在 Notes 日志中指出什么称为子代理。所以它有风险。
    • 您还可以考虑让 5 分钟代理每 3 次调用一次 Java 代理(或者可能通过检查时钟和 NotesAgent.LastRun)。
    【解决方案4】:

    您说它是两个数据库,但实际上阻止代理同时运行的最简单方法是将它们放在同一个数据库中。我会经常创建一个仅包含代理和代理生成的日志文档的特殊数据库。代理可以打开任何数据库,因此它们在哪里并不重要。

    我曾经领导过一个项目,在该项目中,我们结合了 giulio 和 spookycoder 的想法,为代理构建了自己的控制机制。只安排了一个“主”代理,它读取控制文档来决定接下来应该运行哪个代理。假设我们有代理 A、B 和 C。主机运行 A,它会立即更新控制文档以说“我正在运行”,然后在执行过程中使用其进度信息更新字段,最后在完成时更新用“B”更新控制文档,下次主运行时,它会查看控制文档。如果进度信息显示 A 已经完成,那么 master 会看到该轮到 B 运行了。当然,A 可能会意识到 B 没有工作要做,所以它可能会写成“C”,在这种情况下,master 将运行 C。如果进度信息显示,master 也可以选择重新运行 A它没有完成这项工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多