OPA HTTP 自引用 PUT 请求超时

OPA HTTP self referential PUT request times out

我在 main 包中有两个策略调用同一个实例(本地 运行ning OPA 服务器),如下所示:

package main

get[response] {
    response := http.send({
        "method" : "GET",
        "url": "http://localhost:8181/v1/data/example"
    })
}

put[response] {
    response := http.send({
        "method" : "PUT",
        "url": "http://localhost:8181/v1/data/example",
        "body": { "example": true }
    })
}

我 运行 我的 OPA 服务器是这样的:

opa run -w -s main.rego --log-level debug --log-format text

当我卷曲 get 策略时,我收到 200 响应:

$ curl -X POST localhost:8181/v0/data/main/get
[{"body":{},"raw_body":"{}","status":"200 OK","status_code":200}]

但是,当我卷曲放置策略时,它会在 5 秒后超时:

$ curl -X POST localhost:8181/v0/data/main/put
{
  "code": "internal_error",
  "message": "error(s) occurred while evaluating query",
  "errors": [
    {
      "code": "eval_builtin_error",
      "message": "http.send: Put http://localhost:8181/v1/data/example: net/http: request canceled (Client.Timeout exceeded while awaiting headers)",
      "location": {
        "file": "main.rego",
        "row": 11,
        "col": 14
      }
    }
  ]
}

有谁知道为什么 PUT 而不是针对 OPA 实例的 GET 请求?

同时,类似的 curl 工作正常:

curl -X PUT -d "{}" http://localhost:8181/v1/data/example

我知道这是一个 strange/bad 'use case' 但我出于好奇想问这个问题是为了更好地了解 rego http 功能中发生了什么。

OPA 目前支持多并发读事务(如策略查询)和并发写事务(如更新数据)。但是,当写入事务提交时,OPA 会等待读者完成。

由于您是从策略查询内部执行写操作,因此写操作的提交会被阻止。这就是为什么您会看到带有 put 规则的超时。您没有看到 get 规则的超时,因为没有写入事务(因此没有任何阻塞。)

这是OPA的实现细节。理论上 OPA 可以支持多个并发的读取器和写入器,在这种情况下,您可以从策略查询内部修改数据。这不是一个高优先级的功能。

也就是说,我们建议这样做。