MS RFC 109:优化运行时替换

日期

2014年3月

作者

托马斯堡

联系

tbonfort@terriscope.fr

状态

采用

版本

MAPServer 7

修正

2015年2月

最后更新

2014/03/07

1。动机

  • 在分析WMS shootout查询时,在 运行时替换 代码,即使功能根本没有被使用。当运行时替换应用于 all mapserv请求,这部分代码中的优化对于所有mapserv操作都是有益的。

  • 对于某些特定情况,可能需要在元数据条目中应用运行时替换(例如,在MapServer和客户端之间使用代理时,修改OWS_启用_请求,以便为经过身份验证的客户端启用特定操作)。当前的实现禁止这样做,因为它会对性能造成非常明显的影响。

2。建议重写

在伪代码中,当前的算法是:(kvp代表键值对,是传递到mapserver的url中的参数之一,例如,..&map=path/to/mapfile.map&…)

foreach KVP:
  foreach outputformat:
    if KVP appears in "FILENAME" formatoption:
      if KVP validates against MAP_>WEB->VALIDATION:
        apply substitution

  foreach layer:
    foreach class:
      if KVP appears in a substitutable CLASS keyword (EXPRESSION, TEXT, TITLE):
        if KVP validates against CLASS->VALIDATION:
          apply substitution
        else if KVP validates against LAYER->VALIDATION:
          apply substitution
        else if KVP validates against MAP->WEB->VALIDATION:
          apply substitution
      if KVP appears in a substitutable LAYER keyword (DATA, CONNECTION, FILTER, TILEINDEX):
        else if KVP validates against LAYER->VALIDATION:
          apply substitution
        else if KVP validates against MAP->WEB->VALIDATION:
          apply substitution

对于一个典型的请求,其中kvps的数量相对较高(例如,所有的ows请求),并且层/类的数量也相对较高,这会导致为“if kvp出现在xxx关键字”部分进行大量的strcasestr调用。无论是否使用实际的运行时替换,都会发生这种情况。

有了这个RFC,我们将切换到这个伪代码:

foreach layer:
  foreach class:
    foreach class->validation:
      if validation_key in kvp:
        if kvp validates:
          apply class substitutions
  foreach layer->validation:
    if validation_key in kvp:
      if kvp validates:
        apply layer substitutions
        foreach class:
          apply class substitutions
foreach map->web->validation:
  if validation_key in kvp:
    if kvp validates:
      apply outputformat validations
      foreach layer:
        apply layer substitutions
        foreach class:
          apply class substitutions

这样做的好处是,如果不使用替换,则只需要很少的开销,并且在一定程度上简化了代码。这种优化成为可能,因为我们需要验证条目(从6.0开始)。

三。其他

作为这种加速的交换,我们现在允许在层->元数据和映射->Web->元数据条目上进行替换,这将对以前的方法的性能产生过大的影响。我们还可以想象向其他mapfile元素添加替换,因为此操作的成本在不使用时不会影响性能。

出于性能原因,验证应该放在“最接近”实际使用验证块的位置。在map->web->validation中进行验证是可行的,因为它将应用于整个map文件,但是它的行为将比在所需的层/类验证中复制它慢一些。

自2015/02年起更新,Thomasb、Stephanm、Danielm、Mikes和Stevew的+1:正如电子邮件列表中所讨论的,此RFC扩展为以下两个功能:

  • 允许在处理条目时发生替换(Rfc91本机过滤器需要,也可用于例如允许为栅格层动态设置重采样方法)

  • 允许从环境变量中优先读取替换值。这将允许服务器管理员根据用户ID等设置替换…由于环境查找仅在映射文件包含验证块中的相应条目时发生,因此此功能不允许泄漏全局环境,除非用户选择了与现有环境值匹配的替换键。请注意,来自environment的键将优先于在url中传递的相同键。

3.1向后不兼容

由于替换现在可以应用于元数据,因此对于这种不常见的情况,存在潜在的不兼容性:

  • 元数据块的某个条目中包含%variable%子字符串

  • and mapfile包含“variable”runsub的验证块。

在这种情况下,如果在URL中存在variable=foo,则会发生替换,而这在以前不会发生。

3.2问题跟踪ID

https://github.com/MapServer/MapServer/pull/4877

参见:

3.3投票历史

+1来自托马斯布、汤克、史蒂文、叶旺德沃塞纳、史蒂文、佩里恩、米克斯、杰夫姆和斯蒂芬。