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

problem with run async=true & returncodes ..... #55

Closed
Maziar123 opened this issue Dec 29, 2021 · 19 comments
Closed

problem with run async=true & returncodes ..... #55

Maziar123 opened this issue Dec 29, 2021 · 19 comments

Comments

@Maziar123
Copy link

Hi

below code always return [0, 0, None] and command never finish :
seems have problem with sleep ...

cmd = 'echo "Hello " && sleep 2  && echo "Finish " '
p = run(cmd, async_=True)
@vsajip
Copy link
Owner

vsajip commented Dec 31, 2021

You haven't specified any information about OS, etc. This script works for me, on Ubuntu 64-bit (Linux Mint):

import sarge

cmd = 'echo "Hello " && sleep 2  && echo "Finish " '
p = sarge.run(cmd, async_=True)
p.wait()  # wait for pipeline to finish
print(p.returncodes)

Running it prints:

Hello 
Finish 
[0, 0, 0]

So I plan to close this unless you can come up with more information and/or a small example demonstrating a problem.

@vsajip vsajip added the invalid This doesn't seem right label Dec 31, 2021
@Maziar123
Copy link
Author

Maziar123 commented Jan 1, 2022

Hi
Yes with p.wait work but when

import sarge

cmd = 'echo "Hello " && sleep 2  && echo "Finish " '
p = sarge.run(cmd, async_=True)


for i in range(1, 20):
    sleep(0.5)
    print('CMD:', p.commands, sep='')
    print('Count:', len(p.returncodes), ' ret:', p.returncodes, sep='')

I use it in async flow, then wait not suitable

Archlinux (lastest)
python 3.9
sarge .17

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

I use it in async flow, then wait not suitable

Then you can use p.poll_all() or p.poll_last() to see if the pipeline has terminated, Example:

import sarge
import time

cmd = 'echo "Hello " && sleep 2  && echo "Finish " '
p = sarge.run(cmd, async_=True)

for i in range(1, 20):
    time.sleep(0.5)
    rcs = p.poll_all()
    if i == 1:
        print('cmd:', p.commands, sep='')
    print('%d: return codes: %s' % (i, rcs), sep='')
    if None not in rcs:
        break

prints

Hello 
cmd:[Command('echo Hello '), Command('sleep 2'), Command('echo Finish ')]
1: return codes: [0, 0, None]
Finish 
2: return codes: [0, 0, 0]

@Maziar123
Copy link
Author

Thx ...

But you think behavior of returncodes is True ??

and with async_=True the "returncodes" in this sample without wait return none for infinite ??

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

Yes, because the returncode is initially None and set to the actual return code when you poll or wait. That's just how subprocess works - see the Python docs for subprocess.Popen. As you can see from my example, the returncodes doesn't return None forever - the loop terminates.

@vsajip vsajip closed this as completed Jan 1, 2022
@Maziar123
Copy link
Author

Maziar123 commented Jan 1, 2022

the returncodes doesn't return None forever - the loop terminates.

then loop terminate with wrong "returncodes" ??

from API :
returncodes : A list of the return codes of all sub-processes which were actually run.

I think one of it is wrong : (one)API comment is wrong OR (TWO)returncodes behavior
and i think number TWO is wrong

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

What exactly do you think is wrong? None is a placeholder for an actual return code.

@Maziar123
Copy link
Author

Maziar123 commented Jan 1, 2022

in First example in async mode run it :
After 20 second returncodes remain [0, 0, None]

the command i think return with [0, 0, 0] after 2 second
without p.wait returncodes remain [0, 0, None] !!

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

What happens if you use p.poll_all() or p.poll_last() as I suggested?

See this part of the documentation for subprocess, relating to the returncode attribute of subprocess.Popen objects.

@Maziar123
Copy link
Author

Maziar123 commented Jan 1, 2022

as your comment :

Popen.returncode

The child return code, set by poll() and wait() (and indirectly by communicate()). A None value indicates that the process hasn’t terminated  yet.

focus in :

A None value indicates that the process hasn’t terminated yet

then sarge returncodes in async mode return wrong value because operation successfully finish ! seems your returncodes must fixed in async mode specially when have && and sleep

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

It can also indicate that you haven't checked the status of the process - even if just using subprocess, returncode won't be set unless you call poll() or wait().

I just realised that the documentation for poll_all() and poll_wait() was missing. I have now updated the documentation to include them, as well as the documentation for returncodes. See here.

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

If you are using async_ you can still call poll_all(), as it doesn't block.

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

Two things need to happen for a returncode to be set:

  1. The subprocess finishes
  2. You call poll() or wait() on the corresponding subprocess.Popen object to get its returncode. These are called by Pipeline.poll_all() and Pipeline.wait() methods.

@Maziar123
Copy link
Author

Maziar123 commented Jan 1, 2022

why returncodes internally not call poll_all specially in async mode ?

this do latest return state ...

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

why returncodes internally not call poll_all specially in async mode ?

Generally in this kind of code you don't assume too much about what the caller wants, but provide mechanisms for them to do it. I could change it to call poll_all() internally, but then there's no way of decoupling the two things in your code, which might sometimes be desirable.

@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

I have no strong objection to changing it to poll the individual subprocesses, though.

@vsajip vsajip removed the invalid This doesn't seem right label Jan 1, 2022
@vsajip
Copy link
Owner

vsajip commented Jan 1, 2022

Well, I did it the way I did it because I wanted to let the users of the library decide when they want to do certain stuff. Your feedback is that you think it is too inconvenient to call poll_all(), and that the polling should be done automatically when you access returncodes. Having thought about it while we've been discussing the issue, I see that you have a reasonable point, so I will make the change to poll each subprocess for every access of returncodes.

@Maziar123
Copy link
Author

clear code in better always :-)

@vsajip
Copy link
Owner

vsajip commented Jan 2, 2022

Thanks for helping to make sarge better 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants