Skip to content
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

Cleanup signal handling for agents and enable them earlier. #2571

Merged
merged 1 commit into from
Apr 19, 2016

Conversation

kacf
Copy link
Contributor

@kacf kacf commented Apr 12, 2016

The motivation for this is that during policy loading, certain
functions may be evaluated that open pipes, and if these pipes at any
point become disconnected, we get an EPIPE signal. This is ignored
once we get to the evaluation stage, but during loading the signal
handlers have not been enabled yet.

This was originally seen during introduction of the mapdata()
function, which opens a pipe to an external process. In the test for
this function, cat was used to output a prerendered response, but
cat was also expected to consume the data input. Depending on
timing, if the data was written to cat before it terminated,
everything would be fine, but if cat terminated before data could be
written (because it was catting a file, not from stdin), cf-promises
would get an EPIPE signal and terminate abnormally.

Upon inspection of our signal handling, it appears this can happen in
cf-agent as well, and is as such "a ticking time bomb". Therefore this
commit cleans up the signal handling a bit, consolidates it where
possible, and moves all signal handler initialization to the beginning
of each agent main().

Daemons have other signal handler requirements and were left alone for
now.

The motivation for this is that during policy loading, certain
functions may be evaluated that open pipes, and if these pipes at any
point become disconnected, we get an EPIPE signal. This is ignored
once we get to the evaluation stage, but during loading the signal
handlers have not been enabled yet.

This was originally seen during introduction of the mapdata()
function, which opens a pipe to an external process. In the test for
this function, `cat` was used to output a prerendered response, but
`cat` was also expected to consume the data input. Depending on
timing, if the data was written to `cat` before it terminated,
everything would be fine, but if `cat` terminated before data could be
written (because it was catting a file, not from stdin), cf-promises
would get an EPIPE signal and terminate abnormally.

Upon inspection of our signal handling, it appears this can happen in
cf-agent as well, and is as such "a ticking time bomb". Therefore this
commit cleans up the signal handling a bit, consolidates it where
possible, and moves all signal handler initialization to the beginning
of each agent main().

Daemons have other signal handler requirements and were left alone for
now.
@kacf kacf mentioned this pull request Apr 12, 2016
@kacf
Copy link
Contributor Author

kacf commented Apr 12, 2016

@jimis: I'd like your input on this one.

@kacf kacf mentioned this pull request Apr 12, 2016
@tzz
Copy link
Contributor

tzz commented Apr 12, 2016

Yeah, nice catch!

@jimis
Copy link
Contributor

jimis commented Apr 12, 2016

Nice catch indeed! Will look into it deeper in a bit. :-)

@jimis
Copy link
Contributor

jimis commented Apr 12, 2016

Makes sense. What I don't get is why mapdata() gets evaluated before the evaluation starts, IMO it should be clearly part of the evaluation, but this belongs to the evaluator refactoring discussion!

So +1, I can't think of any side-effects this can have.

@kacf
Copy link
Contributor Author

kacf commented Apr 15, 2016

mapdata is evaluated during pre-evaluation, since it is part of a vars promise. This is expected, and you can avoid it by the known class guard workaround.

Thanks for looking at it! I will merge it together with the PR that prompted this.

@kacf kacf self-assigned this Apr 15, 2016
@jimis
Copy link
Contributor

jimis commented Apr 15, 2016

I was under the impression that in theory only common bundles need to be evaluated in pre-eval. So if it's a "vars" promise in a non-common bundle, it should be skipped.

@kacf
Copy link
Contributor Author

kacf commented Apr 19, 2016

No, all variables are resolved in the pre-eval step, regardless of which bundle they are in.

@kacf kacf merged commit 205dc71 into cfengine:master Apr 19, 2016
@kacf kacf deleted the earlier_signal_handling branch April 19, 2016 06:19
@jimis
Copy link
Contributor

jimis commented Apr 20, 2016

No, all variables are resolved in the pre-eval step, regardless of which bundle they are in.

Why would that happen? The variables in common bundles being pre-evaluated, makes sense in order to resolve dynamic inputs. But what would the reason be for that to happen in all bundles, during pre-evaluation?

@kacf
Copy link
Contributor Author

kacf commented Apr 21, 2016

I don't know what the original motivation was, it just seems to be that way now.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants