四、Rational ClearQuest Hooks—性能注意事项
特别需要注意的是在schema中使用hook代码——特别是如果你的hook在Perl中执行,而不在VBScript。你通常可以选择是否使用Perl或VBScript在Rational ClearQuest hooks中,这是有限制的,不过这可能迫使你使用这个或另一个。例如,如果你的环境需要支持用户本地的Unix客户端的Rational ClearQuest,那么你必须撰写你的hooks在Perl中,因为VBScript脚本不支持Unix环境。 无论你选择什么(VB,Perl,译者注)作为的脚本语言,都需要记住,当用户登录时,不管是通过Windows或Unix平台的客户端还是通过Web访问,所有在Shema中定义的Hook代码都会加载到CQ客户端(或CQ Web服务端),很多Hook 代码会引起登录需要更多的时间和更多的内存消耗。
同时,当每次执行“Action”或者一个Base Action Hook被执行时,所有的记录脚本(当前的记录类型)和所有全局脚本都会传给编译器和进行编译。无论这些执行的Hook是否使用这些记录脚本或全局脚本,他们都会传给编译器。这个情况和性能有很大的关系,特别是如果你的Schema里包含较多重要的记录脚本或者全局脚本时。为了使传给编译器的代码数量最小,考虑使用Perl模块或者VBSrcipt Com对象——他们能够在执行时按需加载,从而达到压缩全局脚本的目的。
五、使用Perl的附加性能影响
如果你计划提供用户通过CQWeb访问您的Rational ClearQuest,重要的是要记录CQWeb单线程perl代码的执行情况。这将限制在Rational ClearQuest hooks中使用Perl作为一种脚本语言执行CQWeb的可扩展性。除非您的部署还包括——或很可能包括——本地的Unix/L inux客户端,建议使用VBScript而不是用perl部署CQWeb,特别是如果您执行需要大量hook 代码。
六、附加schema设计指南
其余的本节提到的其他一些资源,这些资源提供了在您的schema中使用某些Rational ClearQuest架构产生性能影响的详细资料。在性能和功能之间你必须作出取舍,以及你最好作为一个schema设计师理解这些权衡,就越有可能部署一个成功的Rational ClearQuest应用程序。
1. 避免使用“ AdminSession ”从schema repository获得的数据。
用户信息存储在用户数据库,因此没有必要在schema repository存放的数据,如用户的全名,等等,如果你必须从schema repository中重新找到数据,把它存储在会话变量以便重用。(看下列使用会话变量事例)
2. 在字段属性上避免使用Recalculate Choice List。
这样做会产生这样的结果,当一条记录在编辑时,当任何一个字段的值改变时都会读取数据库一个来回,并且运行hook脚本。替代的解决方案是,在“父亲”字段的“VALUE_CHANGED”hook里用“InvalidateFieldChoiceList” and “SetFieldChoiceList” methods方法来更新其子字段的内容。
3. 静态或者动态的Choice Lists的条目应该小于100个。
这是因为客户端的内存限制,如果你需要100个以上的Choices,用REFERENCE_LIST来实现。
4. 限制在一个表单上REFERENCE 或REFERENCE_LIST字段的数量。
在显示时这些关联的记录时,Rathional ClearQuest需要执行一个“加入”所有被这个表单关联的记录类型。Multi_Table的加入是耗时的操作,当一个表单上REFERENCE 或者REFERENCE_LIST的数量增加时,时间的消耗会急剧增加。首要的规则是在一个表单上不要有超过10个这样的字段。
5. 避免使用FIELD_VALIDATION hook。
当执行一个Action时,任何域值的改变都会导致Field validation hooks执行一次。(它同时也增加了在登录时加载到内存的代码数量),替代的解决方法是,在ACTION_VALIDATION hook里检查每一个域值的合法性,这样只有用户点“Apply”进行提交修改时才执行一次。
6. 尽量执行hook代码减少数据库查询中。
只要有可能,应该把最常用的查询值记录到一个Session 变量里。当在这个Session期间,每次Hook执行时只需要去读取这个Sesssion变量的值而不是重新去执行查询。这样做只是对那些比较静态的数据来说,如用户信息,EntityType 数据或者其他。如果你用一个Session变量存储一个查询的返回数据如“当前用户的所有打开的bug”,你可能会以为这个Session变量持续地使用导致原来的数据过期的风险。请看下面使用Session变量来避免一个查询的例子:
7. 避免在查询中返回MULTILINE_TEXT字段。
没有multiline text字段,CQ会一次从数据库中批量选择250行。因此,一个返回N条记录的查询只需要N/250次客户端到数据库之间的逻辑往返查询。如果有multiline text字段,CQ会取一条记录的所有非multiline text字段为一行,然后取multiline text字段为一行。然后CQ用同样的方式再取下一条记录。因此,一个返回N行包含M个multiline text字段记录的查询需要(1+M)*N次逻辑往返查询。注意:关于这个问题的一个补丁包计划在V2003.06.00解决,在安装这个补丁包之前建议不要使用返回multiline text字段的查询。
8. 谨慎的使用电子邮件规则。
每一个邮件规则都包括一个过滤,每一个过滤和一个查询相联系。每一次邮件规则运行的时候,关联的查询也会执行。每一个Action的时候,邮件规则开始加载并开始运行。作为邮件规则的一个替代选择,可以使用Notification Hooks(在那里需要写代码来实现发送邮件),这样就可以在相应Action的时候才触发这个Hook。试着最小化和合并邮件规则以减少查询代码执行的数量。这意味着要给一个更广泛的用户范围发一封未定义的邮件。不过从性能上考虑是值得的。
9. 想去某个字段的值的时候不要取出完整的记录。
从CQ中取出一个完整的记录是很费时的操作。如果你只需要从一个记录或者记录集合里取一个或者两个字段的值,使用一个只查出这些字段的值作为结果的查询比取出整个记录或者循环查找记录集合取得想要的字段更有效率。 同样的,你可以取的一个记录里关联字段的值而不需要完整地取出整个记录。如:假设当前的Entity有一个字段叫“Project”,这个字段REFERENCE到其他包含一个字段叫“name”的记录类型,用如下的代码,你可以得到关联的字段:
my $projname = $entity->GetFieldValue("Project.Name")->GetValue();
这样取值会比下面的代码更有效率:
my $project = $entity->GetFieldValue(“Project”)->GetValue();
my $projname = $project->GetFieldValue(“Name”)->GetValue();