red888
red888

Reputation: 31620

How do I read the current output with asynchronous without waiting for the process to finish?

Also opened a GitHub issue: https://github.com/pyinvoke/invoke/issues/951

It's documented, but are there any complete examples and snippets for how to use asynchronous=True?

I usually have to look through GitHub issues when trying to find full example snippets to stuff, but maybe I'm just missing this in the docs.

I'm doing this

@task
def my_cmd(ctx: Context):
    invoke_promise = ctx.run(
        "while true; do echo running forevah; sleep 2; done", warn=True, hide=False, echo=True, asynchronous=True
    )

This throws an error

print(invoke_promise)

Traceback (most recent call last):
  File "/usr/local/bin/myproject", line 8, in <module>
    sys.exit(program.run())
  File "/usr/local/lib/python3.10/site-packages/invoke/program.py", line 384, in run
    self.execute()
  File "/usr/local/lib/python3.10/site-packages/invoke/program.py", line 569, in execute
    executor.execute(*self.tasks)
  File "/usr/local/lib/python3.10/site-packages/invoke/executor.py", line 129, in execute
    result = call.task(*args, **call.kwargs)
  File "/usr/local/lib/python3.10/site-packages/invoke/tasks.py", line 127, in __call__
    result = self.body(*args, **kwargs)
  File "/workspaces/myproject/myproject/tasks/mytask.py", line 479, in my_cmd
    print(invoke_promise)
  File "/usr/local/lib/python3.10/site-packages/invoke/runners.py", line 1475, in __str__
    if self.exited is not None:
AttributeError: 'Promise' object has no attribute 'exited'

As does this

print(invoke_promise.stdout)
AttributeError: 'Promise' object has no attribute 'stdout'

This hangs forever until the process exits

print(invoke_promise.join()) 

What method is there on the returned promise object to just get the current output of the running background process that was started? I can't find anything in the docs about this.

I want to be able to:

  1. Just see the current output so far without waiting for it to finish
  2. Be able to read the output of the currently running process and choose to manually kill it if I want

Upvotes: 1

Views: 360

Answers (1)

red888
red888

Reputation: 31620

Based on this github issue I think I found a solution: https://github.com/pyinvoke/invoke/issues/689

@task
def my_cmd(ctx: Context):
    invoke_promise = ctx.run(
        "while true; do echo running forevah; sleep 2; done", warn=True, hide=False, echo=True, asynchronous=True
    )

    import time
    time.sleep(10)  # ie do a bunch of work in the foreground

    # Check the current output of backgroud process
    current_output = invoke_promise.runner.stdout

    # ... parse current output and do stuff
    # Based on current output decide if and when to kill it 
    invoke_promise.runner.kill()

Upvotes: 2

Related Questions