如何在重新启动时恢复Java命令行工具的执行

huangapple go评论65阅读模式
英文:

How to resume Java command line tool execution upon restart

问题

我正在开发一个类似以下方式工作的Java命令行工具:

  1. 下载一个文件(其中包含一些键/值对的数据)。
  2. 处理整个文件并将键/值对存储在内存中的TreeMap中(以键排序)。
  3. 遍历TreeMap并将每个键/值Map条目传递给外部库。基本上,它的任务是按'键'对键/值条目进行排序,然后将它们传递给外部方法。

以下是CLI工具中的伪代码:

List<VersionPair> pairs = getVersionPairsFromJSON(input); 

TreeMap<Long, String> orderedEntries = new TreeMap<>();

for (VersionPair pair : pairs) {
    orderedEntries.put(pair.getKey(), pair.getVersionContent());
}

for (Map.Entry<Long, String> entry : orderedEntries) {
    externalMethod.sendVersion(entry.getKey(), entry.getValue())
        .whenComplete((metadata, error) -> {
            if (error != null) {
                System.err.println("Failed to send Version with key: " + entry.getKey() + ", with content: " + entry.getKey());
            }
        });
}

// POJO for VersionPair
public class VersionPair {
    Long key;
    String versionContent;
    ...
    // constructor, getters and setters
}
public CompletableFuture<Metadata> externalMethod(Long key, String versionContent);

在这里,对externalMethod的调用顺序应严格基于JSON文件中的键的排序顺序(由于我的应用程序的性质)。例如:

externalMethod.sendVersion(1, "version1Content");
externalMethod.sendVersion(2, "version2Content");
externalMethod.sendVersion(3, "version3Content");

我想知道是否可能在某种情况下从工具中断的地方恢复执行,例如因为某种原因终止了执行(比如,用户按下Ctrl+C)。假设文件内容保持不变。

我的用例还要求对于给定的键/值对,外部库方法不能被调用多次。因此,在为一些键/值对调用外部库后,如果程序停止,我需要从程序停止的地方继续,而不是从头开始。

是否可以通过Java命令行工具实现此行为?如果不能,我想知道还有哪些其他选项可以实现这一点?

提前感谢您的回答!

英文:

I am working on a Java command line tool that works like below:

  1. Downloads a file (which contains some key/value pairs of data)
  2. Processes the entire file and stores key/value pairs in an in-memory TreeMap (to sort by key).
  3. Iterates through the TreeMap and passes each key/value Map entry to an external library. So, basically its job is to sort the key/value entries by 'key' and then pass them to an external method.
Sample file content (key-value pairs in JSON):
[{   
      &quot;key&quot; : 2
      &quot;value&quot; : &quot;version2Content&quot;
 },
 {   
      &quot;key&quot; : 1
      &quot;value&quot; : &quot;version1Content&quot;
 }, 
 {   
      &quot;key&quot; : 3
      &quot;value&quot; : &quot;version3Content&quot;
 }]

Psuedo code in the CLI tool:

List&lt;VersionPair&gt; pairs = getVersionPairsFromJSON(input); 

TreeMap&lt;Long, String&gt; orderedEntries = new TreeMap&lt;&gt;();

for (VersionPair pair : pairs) {
    orderedEntries.put(pair.getKey(), pair.getVersionContent());
}

for (Map.Entry&lt;Long, String&gt; entry : orderedEntries) {
    externalMethod.sendVersion(entry.getKey(), entry.getValue())
        .whenComplete((metadata, error) -&gt; {
            if (error != null) {
                System.err.println(&quot;Failed to send Version with key: &quot; + entry.getKey() + &quot;, with content: &quot; + entry.getKey());
            }
        });
}

// POJO for VersionPair
public class VersionPair {
    Long key;
    String versionContent;
    ...
    // constructor, getters and setters
}
public CompletableFuture&lt;Metadata&gt; externalMethod(Long key, String versionContent);

In here, the order of calls to externalMethod should strictly be based on the sorted order of keys in the JSON file (due to the nature of my application). Eg:

externalMethod.sendVersion(1, &quot;version1Content&quot;);
externalMethod.sendVersion(2, &quot;version2Content&quot;);
externalMethod.sendVersion(3, &quot;version3Content&quot;);

I would like to know if its possible to resume execution of this tool from where it left off, in case the execution is terminated for some reason. (Say, a user hit Ctrl+C). Assume that the file content remains unchanged.

My use-case also requires that the external library method cannot be called more than once, for a given key/value pair. So in case the program is stopped after calling the external library for some key/value pairs, I need to resume from where the program stopped, instead of starting all over again.

Is it possible to achieve this behavior with Java Command line tools ? If not, may I know what other options do we have that can achieve this ?

Thanks in advance!

答案1

得分: 1

我猜想您的使用情况是希望构建一个命令行应用程序,供最终用户将数据提交到外部系统中。

为了实现“恢复”过程,这需要“持久性”存储来记住其“停止”的时间点。

因此,您可能需要包括一个“基于文件”的数据库,比如 H2、HSQL 等,或者使用一个简单的文本文件,来记住已经处理过的记录。

假设您的命令行是这样的:java -jar app.jar data1.json,那么在您的程序中可以立即创建一个 data1-inprogress.dat 文件。然后将您成功处理的每条记录都写入您的 externalMethod。

因此,如果应用程序被中断,用户重新运行相同的命令,您的程序可以确定无论 data1.json 是否有 data1-inprogress.dat,以指示尚未完成。然后,您可以开始编写所有条件语句,将 data1.json 和 dat1-inprogress.dat 之间的情况进行对比,以确保您的程序不会重新处理旧数据。

英文:

My guess your use case is you want to build a command line application for end user to submit data into external system.

In order to achieve "resume" process, this requires "persistence" storage to remember the point in time where its "stop".

Therefore, you may need to include a "file-based" database, such as H2, HSQL etc. or using a simple text file, to remember which records has been processed.

Let say your command line is like this: java -jar app.jar data1.json, then in your program may create a data1-inprogress.dat file immediately. Then write down each record that you have successfully process your externalMethod.

So if the application is interrupted, and user rerun the same command, your program can determine whatever data1.json has data1-inprogress.dat to indicate is not finished. then you can start writing all the condition statement between data1.json and dat1-inprogress.dat to make sure your program does not reprocess the old data.

huangapple
  • 本文由 发表于 2020年8月27日 13:04:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63609516.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定