Amrith Kumar added the comment:

I see three comments, one from r.david.murray, one from haypo and one from 
pitrou. I'll try and address all three.

r.david.murray:

The code in question is in 
https://github.com/openstack/oslo-incubator/blob/master/openstack/common/processutils.py#L177-L189

note that we're catching EAGAIN and EINTR.

I have not been able to isolate this down to a simple repro without the rest of 
this paraphernalia but I'm trying.

So, we are 'catching' EAGAIN or EINTR here and we're trying to handle it to the 
best of our ability. However, if the underlying layer is not setup to handle a 
retry, our best efforts will be fruitless.

That is what is happening here. 

The reason for this code (ignoring the retry of 20) was put in place exactly 
because a call to communicate() received an EAGAIN.

The issue therefore is that in order for the higher level to properly handle 
this, communicate() should be setup to handle a second call, which it currently 
is not. 

haypo and pitrou: that may be true; I'm not competent to comment on that.

But, as pointed out in earlier comment (and modulo this may be eventlet 
specific), just catching more exceptions isn't the answer.

if the descriptor is closed, the thing that communicate/_communicate() call 
should be able to handle that situation. And this bug illustrates that at least 
eventlet doesn't handle that.

However, I submit to you that this is NOT an eventlet issue. Here's why.

The failure here is that a flush call is being attempted on a closed 
descriptor. I believe that the implementation of flush (in eventlet) is 
legitimately throwing an exception indicating that the state machine was 
violated (cannot flush on closed descriptor). 

The close() was invoked by subprocess.py after it finished doing what it 
thought it had to do with stdin on the first invocation. therefore I believe it 
must be the responsibility of subprocess.py to make sure that when invoked 
again, it doesn't step on itself.

Either that, or subprocess.py's communicate() implementation should indicate 
that it can only be called once, capture all exceptions that would point a user 
to retry (such as EAGAIN and EINTR) and mask them and return some EFATAL.

----------
components: +IO -Library (Lib)

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22114>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to