Skip to content

Commit

Permalink
fix: address "too many open files" error when pushing large bindles
Browse files Browse the repository at this point in the history
Pushing a bindle that contains many assets using `StandaloneRead::push` can
result in a "too many open files" error on POSIX systems with a default file
descriptor limit of 1024.  This is due to the unlimited concurrency of
`future::join_all`.

The alternative is to use `futures::StreamExt::buffer_unordered` instead, which
accepts a parameter to limit maximum concurrency.

This fixes #336.

Signed-off-by: Joel Dice <joel.dice@gmail.com>
  • Loading branch information
dicej committed May 16, 2022
1 parent 9487388 commit 2b2b104
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/standalone/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::convert::TryInto;
use std::path::{Path, PathBuf};

use async_compression::tokio::{bufread::GzipDecoder, write::GzipEncoder};
use futures::{future, stream, TryStreamExt};
use tokio::fs::{read_dir, File};
use tokio::io::{AsyncRead, AsyncWriteExt};
use tokio_stream::{Stream, StreamExt};
Expand All @@ -14,6 +15,9 @@ use tracing::{debug, info, instrument, trace};
use crate::client::{tokens::TokenManager, Client, ClientError, Result};
use crate::Id;

/// Maximum number of assets to upload in parallel
const MAX_PARALLEL_UPLOADS: usize = 16;

/// The name of the invoice file
pub const INVOICE_FILE: &str = "invoice.toml";
/// The name of the parcels directory
Expand Down Expand Up @@ -152,11 +156,9 @@ impl StandaloneRead {
Ok(())
});

futures::future::join_all(parcel_futures)
futures::StreamExt::buffer_unordered(stream::iter(parcel_futures), MAX_PARALLEL_UPLOADS)
.try_for_each(future::ok)
.await
.into_iter()
.collect::<Result<Vec<_>>>()?;
Ok(())
}

/// Retrieve the invoice from the standalone bindle.
Expand Down

0 comments on commit 2b2b104

Please sign in to comment.