I have two policies in a main
package which call the same instance (the locally running OPA server) like this:
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 }
})
}
I run my OPA server like this:
opa run -w -s main.rego --log-level debug --log-format text
When I curl the get
policy I get a 200 response:
$ curl -X POST localhost:8181/v0/data/main/get
[{"body":{},"raw_body":"{}","status":"200 OK","status_code":200}]
However, when I curl the put policy it times out after 5 seconds:
$ 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
}
}
]
}
Does anyone know why this might be happening for PUT
and not GET
requests against the OPA instance?
Meanwhile a comparable curl works fine:
curl -X PUT -d "{}" http://localhost:8181/v1/data/example
I'm aware this is a strange/bad 'use case' but I'm asking out of curiosity in an attempt to better understand what's going on in the rego http functionality.
OPA currently supports multiple concurrent read transactions (e.g., policy queries) and one concurrent write transaction (e.g., updating data). However, when the write transaction commits, OPA waits until readers have finished.
Since you are executing a write operation from inside a policy query, the commit for the write operation blocks. This is why you see the timeout w/ the put
rule. You do not see a timeout with the get
rule because there are no write transactions (so nothing blocks.)
This is an implementation detail of OPA. In theory OPA could support multiple concurrent readers and writers and in that case you could modify data from inside a policy query. It's just not a high-priority feature.
That said, we do not recommend doing this.