Nothing
get_start_time()
returns the running arrival's start time (#304).set_source()
to avoid leaking arrivals from the old source (#322).tag
argument (as part of #287).amount
argument is deprecated
in favor of the more generic name target
. The former will still work, but
raises a warning (#287 addressing #197).numeric_version
.schedule
objects (#272).get_batch_size()
getter allows a batch to retrieve its size (#263).get_activity_time()
and get_activity_time_selected()
getters allow an
arrival to retrieve the amount of activity time spent in resources (#186).simmer
and monitor
objects in
function environments for generators too (#279).wait=FALSE
, i.e., arrivals don't need to
trigger the same synchronize()
activity to be in sync (#275).when_activated()
(#250).simmer
and wrap
environments (#241).deactivate()
, which now unschedules future arrivals (#249).trap()
, synchronize()
and rollback()
. These are
stateful activities that require storing information about passing arrivals to
manage clones or redirections. These activities were not properly cleaning
their storage when arrivals were rejected at some point in the trajectory. As
a result, certain simulations with these activities involved may show random
improper behaviour depending on how memory reuse happens. This patch unifies
storage management for stateful activities, adds a new interface to register
these activities and another interface for arrivals to notify their
termination, so that the stored information is properly cleaned up (#231).select()
(#233).timeout()
activity. This makes
possible to set a null timeout so that the next event is processed in the last
place if several more events happen at the same time (#229).Queueing Systems
vignette with a section about custom service
policies (as part of #229).out
and keep_seized
parameters to leave()
with the same behaviour as
in renege_in()
and renege_if()
. Code and documentation of these functions
are now integrated under help(renege)
(#208, #217).from
, to
and from_to
accept dynamic parameters
for arguments start_time
, stop_time
and every
(#219).add_generator()
and add_resource()
respectively if a vector
of names is provided (#221).get_mon_*()
dispatch for named lists (#210).from
, to
and from_to
to preserve the
environment of the supplied functions (as part of #219).keep_seized
resources after reneging (#204 addressing #200).from
and from_to
+ documentation update (75a9569).handle_unfinished()
activity sets a drop-out trajectory for unfinished
arrivals, i.e., those dropped from a resource (due to preemption, resource
shrinkage or a rejected seize
) or those that leave
a trajectory (#178
addressing #177).release_all()
and release_selected_all()
activities automatically
retrieve the amount of resources seized and release it (#180 addressing #25).get_seized()
and get_seized_selected()
getters allow an arrival to
retrieve the amount of resources seized (#180 addressing #179).stop_if()
activity sets a conditional breakpoint (#181 addressing #100).Queueing Systems
vignette with a section about state-dependent
service rates.get_selected()
retrieves names of selected resources via the
select()
activity (#172 addressing #171).Simulator
interface for adding processes and resources (#162).
The responsibility of building the objects has been moved to the caller.add_global()
method to attach global attributes to a simulation
environment (#174 addressing #158).get_global()
to work outside trajectories (#170 addressing #165).rollback()
with an infinite amount (#173).reset()
to avoid overwriting the simulation environment (#175).get_sources()
and get_resources()
retrieve a character vector of
source/resource names defined in a simulation environment.get_trajectory()
retrieves a trajectory to which a given source is
attached.shortest-queue-available
,
round-robin-available
, random-available
(#156). These are the same as the
existing non-available
ones, but they exclude unavailable resources
(capacity set to zero). Thus, if all resources are unavailable, an error is
raised.-DRCPP_PROTECTED_EVAL
(Rcpp >= 0.12.17.4) as
-DRCPP_USE_UNWIND_PROTECT
(6d27671).-DBOOST_NO_AUTO_PTR
(70328b6).log_
print (7c2e3b1).when_activated()
convenience function to easily generate arrivals on
demand from trajectories (#161 closing #160).schedule
printing (9c66285).set_attribute(global=TRUE)
, get_attribute(global=TRUE)
and
timeout_from_attribute(global=TRUE)
(#164), the *_global
versions should
be used instead.simmer
license has been changed to GPL >= 2.inst/include
(#147 closing #145). Therefore, from now on it is possible to
extend the C++ API from another package by listing simmer
under the
LinkingTo
field in the DESCRIPTION file.monitor
constructor enables the development of new monitoring
backends in other packages (179f656, as part of #147).log_
activity has a new argument
level
which determines whether the message is printed depending on a global
log_level
defined in the simmer
constructor (#152).set_attribute
and set_global
gain a new argument to automatically
initialise new attributes (#157). Useful to update counters and indexes in a
single line, without initialisation boilerplate.-DRCPP_PROTECTED_EVAL
(Rcpp >= 0.12.17.3), which provides fast
evaluation of R expressions by leveraging the new stack unwinding protection
API (R >= 3.5.0).ostream
method (2b2f43e).rlang
and purrr
(#154).add_dataframe
enables the attachment of precomputed data,
in the form of a data frame, to a trajectory. It can be used instead of (or
along with) add_generator
. The most notable advantage over the latter is
that add_dataframe
is able to automatically set attributes and
prioritisation values per arrival based on columns of the provided data frame
(#140 closing #123).set_source
activity deprecates set_distribution()
. It works both for
generators and data sources (275a09c, as part of #140).simmer()
constructor gains a new argument mon
to provide different types of monitors.
By default, monitoring is performed in-memory, as usual. Additionally,
monitoring can be offloaded to disk through monitor_delim
and monitor_csv
,
which produce flat delimited files. But more importantly, the C++ interface
has been refactorised to enable the development of new monitoring backends
(#146 closing #119).until=Inf
for the run
method (3e6aae9, as part of #140).branch
and clone
now accept lists of trajectories, in the same way as
join
, so that there is no need to use do.call
(#142).continue
(present in seize
and branch
) is recycled if only
one value is provided but several sub-trajectories are defined (#143).timeout_from_attribute()
activity makes it easier to set a timeout based
on an attribute (#129).set_attribute()
, set_prioritization()
, set_capacity()
and
set_queue_size()
get a new argument mod
which, if set to "+"
or "*"
,
modifies the corresponding value instead of substituting it. This makes it
easier to increment, decrement or scale one of these values (#130).*_selected()
versions for the already available resource getters:
get_capacity()
, get_queue seize()
, get_server_count()
and
get_queue_count()
(#134).trap()
after a send()
(#135).create_trajectory()
and onestep()
(#117).get_mon_resources()
's data
argument. It was there for historical
reasons and probably nobody was using it (851d34b).set_attribute()
(and set_global()
by extension) can set multiple
attributes at once by providing vectors of keys
and values
(or functions
returning such keys
and/or values
). get_attribute()
(and get_global()
by extension) can retrieve multiple keys
(#122).stepn()
method deprecates onestep()
(e452975).ostream
after formatting (9ff11f8).set_capacity()
(#125).progress
callback in run()
(#103).get_name()
retrieves the arrival name.get_attribute()
retrieves an attribute by name. The old method of
retrieving them by providing a function with one argument is deprecated in
favour of get_attribute()
, and will be removed in version 3.7.x.get_prioritization()
retrieves the three prioritization values
(priority
, preemptible
, restart
) of the active arrival.set_global()
and get_global()
,
equivalent to set_attribute(global=TRUE)
and get_attribute(global=TRUE)
respectively.Rcpp::DataFrame
instead of Rcpp::List
(#104).make_resetable()
(c596f73).trap()
's handler cloning and associated test (#91).select()
's policy
also when resources
is a function (#92).rollback()
's default behaviour to times=Inf
, i.e., infinite loop (#95).timeout()
returns a missing value (#96 and #97).[<-
and [[<-
(#88).rep()
S3 method for trajectories (7fa515e).simmer.plot
package (on CRAN) already covers these features among others.Suggests
are not installed (e40e5b6).every
parameter to the from_to()
convenience function (9d68887).[
and [[
, for trajectories (1847898). Think
about trajectories as lists of activities and these operators will do (almost)
everything you expect. As a side effect, the generics head()
and tail()
automatically work with trajectories also as expected.length()
method to obtain the number of first-level activities in a
trajectory (f86375a). Useful in combination with the subsetting operators.create_trajectory()
has been deprecated in favor of trajectory()
(76c1317).plot_resource_usage()
, plot_resource_utilization()
,
plot_evolution_arrival_times()
and plot_attributes()
have been deprecated
and will be removed in the next release in order to minimise dependencies
(5b43f2b). We plan to release a new package on CRAN covering these features
and new ones.get_head()
,
get_tail()
, print_activity()
, get_next_activity()
, get_prev_activity()
(f86375a). These methods were only useful for development purposes and nobody
should be using them. And it was never a good idea to directly expose external
pointers.renege_if()
activity triggers reneging upon reception of a signal
broadcasted with send()
(#84).trap()
(bb2aa46).set_attribute()
(#82).set_queue_size()
with queue_size_strict=TRUE
: arrivals were
not being dropped (#83).set_capacity()
with a preemptive resource when the old value was
Inf
: arrivals were not being preempted (63beb2c).trap()
printed information.set_capacity()
and set_queue_size()
become activities (#77). Just like
seize()
and release()
, they have the associated set_capacity_selected()
and set_queue_size_selected()
for a joint use together with select()
.activate()
and deactivate()
activities allow an arrival to start or
stop a generator, respectively, from inside a trajectory (#80).set_trajectory()
and set_distribution()
activities allow an arrival
to install a new trajectory or distribution, respectively, in a generator
from inside a trajectory (#80).send()
, trap()
, untrap()
and wait()
can be used to send signals, wait
for signals, trap them and launch asynchronous handlers.log_()
activity simply prints messages for debugging purposes (eaa4554).seize()
and seize_selected()
(1c8c3bb).get_mon_arrivals(ongoing = TRUE)
(#73).as<>()
calls (ec4e51a).run(until)
runs the simulation exactly until until
, instead of until
the first event scheduled at a time >= until
(e7264f6).priority
, preemptible
, restart
) has been moved from
seize()
to add_generator()
(#69). This leads to a more natural
interpretation of prioritization values as attributes of arrivals from the
same generator, rather than attributes of a seize()
. Still, prioritization
values can be redefined dynamically from inside a trajectory with the new
activity set_prioritization()
.post.seize
and reject
sub-trajectories in seize()
and
seize_selected()
(#49). This feature allows us to fine-tune what happens to
an arrival if it cannot seize a resource: instead of getting dropped, it may
execute a given sub-trajectory.clone()
and synchronize()
activities (#71). clone()
implements the
workflow pattern in which an entity is processed in multiple parallel threads.
The user can define a different sub-trajectory for each clone. With
synchronize()
, multiple parallel clones converge and are synchronized: only
one continues (the first or the last to arrive), and the others are removed.batch()
and separate()
activities (#45). They can be used to implement
a rollercoaster process: batch()
collects a number of arrivals before they
can continue processing as a block, and separate()
splits a previousl
established batch.renege_in()
and renege_abort()
activities (#58). They can be used to
set or unset a timer after which the arrival will abandon.branch()
's option
returns 0
, the arrival skips the branch()
and continues to the next activity instead of throwing an index out of range
error (#70).every()
(#65) and branch()
's
deprecated argument merge
(#57).join()
activity to concatenate trajectories (#50).queue_size_strict
to add_resource()
to guarantee the queue
size limit with preemption (#59).select()
, seize_selected()
and release_selected()
activities (#52).leave()
activity (#63).end_time - start_time
. All
versions 3.2.x are affected by this bug.preemptible
in the documentation of seize()
and
force preemptible
to be equal or greater than priority
(#53).branch()
's merge
parameter name to continue
. The old name is
deprecated (#57).match.arg()
in multiple-choice arguments (#55).branch()
backwards linking and count (#56).release()
in two steps to deal properly with capacity changes at
the same point in time (#64).every()
is deprecated due to #65.capacity
and queue_size
can change over time following a user-defined
scheduling, which can be generated with the new function schedule()
.?peek
.plot_resource_usage()
(8da9b97).merge=TRUE
(#46).until=Inf
is allowed now (f47baa9).t=3, queue=2
meant that, until t=3
, the queue had
2 customers, and at t=3
the system changed (because of a new arrival or
a new departure). The idea was to keep the values and time vectors aligned
(see #28). But from this moment on, the resources are monitored after
changing the status of the system. This is more consistent with what a user
would expect, and more consistent with the behaviour of other related R
functions (e.g., see stepfun()
, from the stats
package). Wrapping up and
from now on, t=3, queue=2
means that some event happened at t=3
whose
immediate and subsequent result was a queue with 2 customers.preemptive=TRUE
. Arrivals in the server can be preempted on
a preempt_order="fifo"
or preempt_order="lifo"
basis. Each seize()
has
three basic properties:priority
: already present in previous versions.preemptible
: another seize()
with a priority
value greater than this
may preempt the present seize()
.restart
: whether the current task (a timeout()
activity, for instance)
should be restarted if the arrival is preempted.show_activity()
and show_trajectory()
.every()
, to()
and from_to()
convenience functions (8e524cd).plot_resource_usage()
(6b034a7).testthat
(#41).branch()
activity now provides attributes to its option
function, as
the other activities (#42).plot_*()
functions (#44).get_mon_arrivals()
returned the start/activity/end times
per arrival for the whole trajectory. This behaviour remains, but additionally,
get_mon_arrivals(per_resource = TRUE)
returns these times per resource, so
that it is possible to retrieve queueing/system times per resource.get_mon_*()
functions accept a single simulation environment as well as a
list of environments representing several replications (5ee2725). A new column
(replication
) in the resulting data frame indicates the corresponding
replication number.set_attribute()
activity (#16).rollback()
activity (#17 and #22).self
visibly, instead of invisibly (#35).at()
and from()
convenience functions (29cccd2 and 7cfdd90).add_skip_event()
function to implement a more flexible and user-friendly
branching method.n
arrivals beforehand,
this release leverages the concept of generator of arrivals, which is faster
and more flexible. At the same time, the concept of trajectory as a chain of
activities is implemented entirely in C++ internally. Our tests show that
simmer is even faster than SimPy when it comes to simulate queueing networks.Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.