% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/future_promise.R
\name{WorkQueue}
\alias{WorkQueue}
\title{Future promise work queue}
\description{
Future promise work queue

Future promise work queue
}
\details{
#' \ifelse{html}{\out{<a href='https://www.tidyverse.org/lifecycle/#experimental'><img src='figures/lifecycle-experimental.svg' alt='Experimental lifecycle'></a>}}{\strong{Experimental}}

An \pkg{R6} class to help with scheduling work to be completed. \code{WorkQueue} will only execute work if the \code{can_proceed()} returns \code{TRUE}. For the use case of \code{future}, \code{can_proceed()} defaults to \code{future::nbrOfFreeWorkers() > 0} which will not allow for work to be executed if a \pkg{future} worker is not available.

\code{WorkQueue} will constantly try to start new work once prior work item finishes.  However, if \code{can_proceed()} returns \code{FALSE} (no future workers are available) and there is more work to be done, then work is attempted later a random amount of time later using exponential backoff.  The exponential backoff will cap out at 10 seconds to prevent unnecessarily large wait times.

Each time \code{WorkQueue} tries to start more work, it will repeat until \code{can_proceed()} returns \code{FALSE} or there is no more work in the \code{queue}.
}
\section{Global event loop}{


The global loop is used by default as the internal \code{WorkQueue} "delayed check" uses a single delay check for the whole queue, rather than having each item in the queue attempt to process.
This behavior might change in the future, but we are not exactly sure how at this point.

If a private \code{later} loop wants to become synchronous by running until all jobs are completed but is waiting on a \code{future_promise()}, the private loop will not complete unless the global loop is allowed to move forward.

However, it is possible to use a private loop inside a user-defined \code{WorkQueue} may work which can be provided directly to \code{future_promise(queue=custom_queue)}. Having a concrete example (or need) will help us understand the problem better. If you have an example, please reach out .
}

\seealso{
\code{\link[=future_promise_queue]{future_promise_queue()}} which returns a \code{WorkQueue} which is cached per R session.
}
\keyword{internal}
\section{Methods}{
\subsection{Public methods}{
\itemize{
\item \href{#method-new}{\code{WorkQueue$new()}}
\item \href{#method-schedule_work}{\code{WorkQueue$schedule_work()}}
\item \href{#method-clone}{\code{WorkQueue$clone()}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-new"></a>}}
\if{latex}{\out{\hypertarget{method-new}{}}}
\subsection{Method \code{new()}}{
Create a new \code{WorkQueue}
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{WorkQueue$new(
  can_proceed = future_worker_is_free,
  queue = fastmap::fastqueue(),
  loop = later::global_loop()
)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{can_proceed}}{Function that should return a logical value. If \code{TRUE} is returned, then the next scheduled work will be executed. By default, this function checks if \code{\link[future:nbrOfWorkers]{future::nbrOfFreeWorkers()} > 0}}

\item{\code{queue}}{Queue object to use to store the scheduled work. By default, this is a "First In, First Out" queue using \code{\link[fastmap:fastqueue]{fastmap::fastqueue()}}. If using your own queue, it should have the methods \verb{$add(x)}, \verb{$remove()}, \verb{$size()}.}

\item{\code{loop}}{\pkg{later} loop to use for calculating the next delayed check. Defaults to \code{\link[later:create_loop]{later::global_loop()}}.
Schedule work}
}
\if{html}{\out{</div>}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-schedule_work"></a>}}
\if{latex}{\out{\hypertarget{method-schedule_work}{}}}
\subsection{Method \code{schedule_work()}}{
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{WorkQueue$schedule_work(fn)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{fn}}{function to execute when \code{can_proceed()} returns \code{TRUE}.}
}
\if{html}{\out{</div>}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-clone"></a>}}
\if{latex}{\out{\hypertarget{method-clone}{}}}
\subsection{Method \code{clone()}}{
The objects of this class are cloneable with this method.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{WorkQueue$clone(deep = FALSE)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{deep}}{Whether to make a deep clone.}
}
\if{html}{\out{</div>}}
}
}
}
