简体   繁体   English

在 Python 中,如何等到 java 编译完成 PlantUML 图?

[英]How to wait until java compilation of PlantUML diagrams is completed, in Python?

Context语境

I've written a Python code that:我写了一个 Python 代码:

  1. First generates PlantUML .uml files.首先生成 PlantUML .uml文件。
  2. Then runs a Java command to locally compile those .uml files into .png diagrams.然后运行 Java 命令在本地将这些.uml文件编译成.png图表。
  3. Exports those diagrams into a /images directory for latex compilation.将这些图表导出到/images目录以进行 latex 编译。
  4. Then compiles a latex document that integrates those generated PlantUML diagrams.然后编译一个 Z25F7E525B5C0641E1EB1FB3BDEBEB15B5Z 文档,该文档集成了那些生成的 PlantUML 图。

Code代码

The Python that compiles the .uml files into .png files is:.uml文件编译成.png文件的Python是:

def compile_gantt(relative_plant_uml_java_filepath,relative_src_filepath,src_to_gantt_path):
    os.environ["PLANTUML_LIMIT_SIZE"] = "8192"
    run_bash_command(
        f"java -jar {relative_plant_uml_java_filepath} -verbose {relative_src_filepath}{src_to_gantt_path}"
    )

def run_bash_command(bashCommand):
    # Verbose call.
    subprocess.Popen(bashCommand, shell=True)
    # Silent call.
    #subprocess.Popen(bashCommand, shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

And I have written a method that waits until all .png files are created:我编写了一个方法,等待所有.png文件创建完成:

def await_and_verify_compilation_results(self, dir, expected_diagram_filenames,compilation_timout):
        pause_per_iteration=4 #seconds
        
        count=0 # seconds
        while count<compilation_timout:
            all_found=True
            for diagram_filename in expected_diagram_filenames:
                if not os.path.isfile(f"{dir}/{diagram_filename}"):
                    all_found=False
                    print(f"Did not yet find:{dir}/{diagram_filename}")
            print(f"Awaiting compilation of Gantt charts: count={count}/{compilation_timout}.")
            
            # Break while condition.
            if all_found:
                count=compilation_timout+pause_per_iteration
            
            # Continue waiting.
            count=count+pause_per_iteration
            time.sleep(pause_per_iteration)
        
        if not all_found:
            raise Exception("Did not find all gantt diagrams in time!")
        time.sleep(30) # allow extra buffer for all images to be finalised.

Issue问题

The Python code proceeds before the images are completely generated by the Java process. Python 代码在 Java 进程完全生成图像之前继续运行。

This means the images are created but it takes a while before they are actually filled with data.这意味着图像已创建,但需要一段时间才能真正填充数据。 Even when they are filled with data it takes a while before they are completed.即使它们充满了数据,也需要一段时间才能完成。 For example some_diagram.png may increase in file size from 0 kb, to 800 bytes to 1.2 kb over the timespan of a few seconds.例如some_diagram.png文件大小可能会在几秒钟的时间跨度内从 0 kb 增加到 800 字节到 1.2 kb。 So my "await_and_verify_compilation_results` does not wait until the generation of the pictures is completed.所以我的“await_and_verify_compilation_results`不会等到图片的生成完成。

Question问题

How can I make the Python code wait until the Java process/PlantUML generation of the .png files is completed?如何使 Python 代码等到 Java 过程/PlantUML 生成.png文件完成?

Considerations注意事项

Since the .png files are generated automatically, I do not know what their final file size would be.由于.png文件是自动生成的,我不知道它们的最终文件大小。 I can set a manual pause of x seconds after each png to ensure they are completed on my device, but I would not want others with a faster device to have to wait on my buffer.我可以在每个png之后设置手动暂停x秒,以确保它们在我的设备上完成,但我不希望其他设备更快的人不得不在我的缓冲区上等待。 Additionally such a hardcoded loiter may be unreliable, and inefficient compilation-timewise.此外,这种硬编码的 loiter 可能是不可靠的,并且在编译时间方面效率低下。 So I think the most simple solution would be to modify the python function that calls the Java function.所以我认为最简单的解决方案是修改调用 Java ZC1C425268E687A94F14Z python function I have not yet found out how to make that wait, nor have I found how I can make the Java function signal that is is completed.我还没有找到如何让那个等待,我也没有找到如何让 Java function 信号完成。 (The PlantUML .jar file is downloaded automatically and I would prefer not to tamper with their file). (PlantUML .jar文件是自动下载的,我不想篡改他们的文件)。

As Gonzalo Odiard already suggested in the comments, the solution could be found by using subprocess.call instead of subprocess.Popen .正如 Gonzalo Odiard 在评论中已经建议的那样,可以通过使用subprocess.call而不是subprocess.Popen找到解决方案。 So a solution looked like:所以一个解决方案看起来像:

def run_bash_command(bashCommand):
    # Verbose call.
    subprocess.call(bashCommand, shell=True)
    # Silent call.
    # subprocess.call(bashCommand, shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

It was verified on Ubuntu 21.04 Using Python 3.6.已使用 Python 3.6 在 Ubuntu 21.04 上进行了验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM