New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Worker process doesn't let parallel API package stage updates to complete when terminated #9267
Worker process doesn't let parallel API package stage updates to complete when terminated #9267
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be possible to solve this within ApiListener
? Adding this to Process
feels somewhat random for me. Possible options:
- Wait for pending actions in
ApiListener::Stop()
. You'd have to be careful that you actually reload with a new configuration that's consistent with all the requests answered. - Fail concurrent requests for modification altogether, i.e. just return some kind of "conflicting operation already in progress, please try again later" error. Clients then would have to handle this, but they have to handle failures already anyways since the API is gone during the reload, but the error would look a bit different.
You want me to forbid concurrent stage updates that are completely independent from each other? |
Tom and I also do. (Icinga/icingaweb2-module-director#2412) |
e909865
to
62e0c34
Compare
Before: After: Package cmdb: curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/config/stages/cmdb' -d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { check_command = \"dummy\" }" }, "pretty": true }'
HTTP/1.1 200 OK
Server: Icinga/v2.13.0-209-g62e0c349b
Content-Type: application/json
Content-Length: 221
{
"results": [
{
"code": 200,
"package": "cmdb",
"stage": "9a218b57-8b04-4f66-80ff-3c9c8763fe24",
"status": "Created stage. Reload triggered."
}
]
} Package icinga: curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/config/stage
s/icinga' -d '{ "files": { "conf.d/test.conf": "object Host \"test-host\" { check_command = \"dummy\" }" }, "pretty": true }'
HTTP/1.1 409 Conflict
Server: Icinga/v2.13.0-209-g62e0c349b
Content-Type: application/json
Content-Length: 142
{
"error": 409,
"status": "Conflicting request, there is already an ongoing package update in progress. Please try it again later."
} |
1e5cc5e
to
cecfca5
Compare
cecfca5
to
0c5c0ab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to the inline comments, please also make sure to test #9267 (comment) (second paragraph).
0c5c0ab
to
cb85adc
Compare
cb85adc
to
c82b397
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where you add that new Defer
parameter, lines are getting quite long, so I'd say it's time to add some line breaks.
c82b397
to
129b1dd
Compare
129b1dd
to
c67bd66
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yhabteab Is this intentionally still in draft state? I don't have anything more code-wise so far. I'll still do some testing but preferably after you say you don't plan any other changes to the code.
lib/remote/configstageshandler.cpp
Outdated
} catch (const std::exception& ex) { | ||
return HttpUtility::SendJsonError(response, params, 500, | ||
"Stage creation failed.", | ||
DiagnosticInformation(ex)); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just caught my eye and fixed it right away. Is this a reason for a change request?
lib/remote/configstageshandler.cpp
Outdated
@@ -212,4 +221,3 @@ void ConfigStagesHandler::HandleDelete( | |||
response.result(http::status::ok); | |||
HttpUtility::SendJsonBody(response, params, result); | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same 👆
Sorry, forgot to press the ready! |
Let's hear a second opinion on my requested changes... |
lib/base/defer.hpp
Outdated
m_Func(); | ||
} catch (...) { | ||
// https://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor | ||
if (m_Func != nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw. wondering whether != nullptr
is actually necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't really make a difference, both does pretty much the same:
…alidation success and process is going to be reloaded
To prevent Icinga2 from being restarted while one or more requests are still in progress and end up as corrupted stages without status file and startup logs.
c67bd66
to
6193a91
Compare
@yhabteab Backport this PR. |
…s-do-not-finish-while-reload Worker process doesn't let parallel API package stage updates to complete when terminated
When the second request isn't finished processing till the new worker process is started and its configs are validated, the old worker is terminated immediately after the new worker becomes ready. When the worker process is terminated, all the worker threads of the
Process
class that are responsible for processing such requests are also destroyed. Thus, the second API request remains incomplete and produces a package stage withoutstartup
logs andstatus
file.Changes:
Concurrent package updates are strictly prohibited.
To Reproduce
curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/config/packages/cmdb?pretty=1'
curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/config/packages/test?pretty=1'
fixes #7898