Чтение потока файлов, одновременно записываемого другим потоком - PullRequest
1 голос
/ 28 сентября 2019

У меня есть Postgres BlobInputStream, который связан с транзакцией базы данных, и мне нужно передать его клиенту, который запрашивает его через HTTP-запрос.

Чтобы избежать медленных клиентов из-за потери транзакций базы данных,Я хочу сбросить поток на диск и одновременно позволить клиенту читать с диска: таким образом, транзакция завершится, когда поток будет записан на диск, даже если клиент все еще читает из файла.

Очевидно, я не хочу, чтобы клиент ожидал сброса всего потока на диск перед началом чтения.

На данный момент это мой код:

public void transferStreamToChannel(InputStream stream, SinkChannel channel) {
    try {
        // Create a temporary file to buffer to stream transfer, so that slow readers won't
        // starve the transaction.
        var tmp = Files.createTempFile(StreamTransferInitiator.class.getSimpleName(),
                Thread.currentThread().getName());
        var tos = Files.newOutputStream(tmp);

        var executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try (var fis = Files.newInputStream(tmp, StandardOpenOption.DELETE_ON_CLOSE)) {
                var out = Channels.newOutputStream(channel);
                fis.transferTo(out);
            } catch (IOException e) {
                this.getLogger().error("Error writing to disk", e);
            }
        });

        stream.transferTo(tos);
    } catch (IOException e) {
        this.getLogger().error("Error reading stream", e);
    } finally {
        try {
            stream.close();
            channel.close();
        } catch (IOException e) {
            this.getLogger().error("Error closing stream", e);
        }
    }
}

Проблема с этимчто исполнитель найдет пустой файл и закроется до того, как поток базы данных будет полностью очищен.

Как мне соединить две операции, чтобы при передаче клиенту было известно о большем количестве данных, которые еще предстоит записатьна диск?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...