Skip to content

Commit bdca4a2

Browse files
committed
initial implementation of #177
1 parent 173ee82 commit bdca4a2

10 files changed

+106
-4
lines changed

NAMESPACE

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ S3method(get_server_count_selected,simmer)
4444
S3method(get_sources,simmer)
4545
S3method(get_sources,wrap)
4646
S3method(get_trajectory,simmer)
47+
S3method(handle_unfinished,trajectory)
4748
S3method(join,trajectory)
4849
S3method(leave,trajectory)
4950
S3method(length,trajectory)
@@ -116,6 +117,7 @@ export(get_server_count)
116117
export(get_server_count_selected)
117118
export(get_sources)
118119
export(get_trajectory)
120+
export(handle_unfinished)
119121
export(join)
120122
export(leave)
121123
export(log_)

R/RcppExports.R

+4
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ Leave__new <- function(prob) {
165165
.Call(`_simmer_Leave__new`, prob)
166166
}
167167

168+
HandleUnfinished__new <- function(trj) {
169+
.Call(`_simmer_HandleUnfinished__new`, trj)
170+
}
171+
168172
Leave__new_func <- function(prob) {
169173
.Call(`_simmer_Leave__new_func`, prob)
170174
}

R/trajectory-activities.R

+17
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,23 @@ leave <- function(.trj, prob) UseMethod("leave")
359359
#' @export
360360
leave.trajectory <- function(.trj, prob) .trj$leave(prob)
361361

362+
#' Handle Unfinished Arrivals
363+
#'
364+
#' Activity for setting a drop-out trajectory for unfinished arrivals, i.e.,
365+
#' those dropped from a resource (due to preemption or resource shrinkage) or
366+
#' those that \code{\link{leave}} a trajectory.
367+
#'
368+
#' @inheritParams seize
369+
#' @param handler trajectory object to handle unfinished arrivals. A \code{NULL}
370+
#' value will unset the drop-out trajectory.
371+
#'
372+
#' @return Returns the trajectory object.
373+
#' @export
374+
handle_unfinished <- function(.trj, handler) UseMethod("handle_unfinished")
375+
376+
#' @export
377+
handle_unfinished.trajectory <- function(.trj, handler) .trj$handle_unfinished(handler)
378+
362379
#' Renege on some Condition
363380
#'
364381
#' Activities for setting or unsetting a timer or a signal after which the arrival will abandon.

R/trajectory-class.R

+6
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ Trajectory <- R6Class("trajectory",
292292
)
293293
},
294294

295+
handle_unfinished = function(handler) {
296+
check_args(handler=c("trajectory", "NULL"))
297+
traj <- as.list(c(handler[]))
298+
private$add_activity(HandleUnfinished__new(traj))
299+
},
300+
295301
renege_in = function(t, out=NULL) {
296302
check_args(t=c("number", "function"), out=c("trajectory", "NULL"))
297303
traj <- as.list(c(out[]))

inst/include/simmer/activity/leave.h

+25
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,31 @@ namespace simmer {
4848
T prob;
4949
};
5050

51+
/**
52+
* Set a path to handle unfinished arrivals (from 'leave' or resources)
53+
*/
54+
class HandleUnfinished : public Fork {
55+
public:
56+
CLONEABLE(HandleUnfinished)
57+
58+
HandleUnfinished(const VEC<REnv>& trj)
59+
: Fork("HandleUnfinished", VEC<bool>(trj.size(), false), trj) {}
60+
61+
void print(unsigned int indent = 0, bool verbose = false, bool brief = false) {
62+
Activity::print(indent, verbose, brief);
63+
internal::print(brief, false);
64+
Fork::print(indent, verbose, brief);
65+
}
66+
67+
double run(Arrival* arrival) {
68+
Activity* next = NULL;
69+
if (heads.size())
70+
next = heads[0];
71+
arrival->set_dropout(next);
72+
return 0;
73+
}
74+
};
75+
5176
} // namespace simmer
5277

5378
#endif

inst/include/simmer/process/arrival.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ namespace simmer {
6565
Arrival(Simulator* sim, const std::string& name, int mon, Order order,
6666
Activity* first_activity, int priority = 0)
6767
: Process(sim, name, mon, priority), order(order), paused(false),
68-
clones(new int(0)), activity(first_activity), timer(NULL), batch(NULL)
69-
{ init(); }
68+
clones(new int(0)), activity(first_activity), timer(NULL),
69+
dropout(NULL), batch(NULL) { init(); }
7070

7171
Arrival(const Arrival& o)
7272
: Process(o), order(o.order), paused(o.paused), clones(o.clones),
73-
activity(NULL), attributes(o.attributes), timer(NULL), batch(NULL)
74-
{ init(); }
73+
activity(NULL), attributes(o.attributes), timer(NULL),
74+
dropout(NULL), batch(NULL) { init(); }
7575

7676
~Arrival() { reset(); }
7777

@@ -186,6 +186,8 @@ namespace simmer {
186186
batch = NULL;
187187
}
188188

189+
void set_dropout(Activity* next) { dropout = next; }
190+
189191
void set_renege(double timeout, Activity* next) {
190192
cancel_renege();
191193
timer = new Task(sim, "Renege-Timer",
@@ -222,6 +224,7 @@ namespace simmer {
222224
SelMap selected; /**< selected resource */
223225
Task* timer; /**< timer that triggers reneging */
224226
std::string signal; /**< signal that triggers reneging */
227+
Activity* dropout; /**< drop-out trajectory */
225228
Batched* batch; /**< batch that contains this arrival */
226229
ResMSet resources; /**< resources that contain this arrival */
227230

inst/include/simmer/process/arrival_impl.h

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
namespace simmer {
2727

2828
inline void Arrival::terminate(bool finished) {
29+
if (!finished && dropout) {
30+
activity = dropout;
31+
sim->schedule(0, this, priority);
32+
return;
33+
}
34+
2935
foreach_ (ResMSet::value_type& itr, resources) {
3036
Rcpp::warning("'%s': leaving without releasing '%s'", name, itr->name);
3137
itr->erase(this, true);

man/handle_unfinished.Rd

+22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RcppExports.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,17 @@ BEGIN_RCPP
526526
return rcpp_result_gen;
527527
END_RCPP
528528
}
529+
// HandleUnfinished__new
530+
SEXP HandleUnfinished__new(const std::vector<Environment>& trj);
531+
RcppExport SEXP _simmer_HandleUnfinished__new(SEXP trjSEXP) {
532+
BEGIN_RCPP
533+
Rcpp::RObject rcpp_result_gen;
534+
Rcpp::RNGScope rcpp_rngScope_gen;
535+
Rcpp::traits::input_parameter< const std::vector<Environment>& >::type trj(trjSEXP);
536+
rcpp_result_gen = Rcpp::wrap(HandleUnfinished__new(trj));
537+
return rcpp_result_gen;
538+
END_RCPP
539+
}
529540
// Leave__new_func
530541
SEXP Leave__new_func(const Function& prob);
531542
RcppExport SEXP _simmer_Leave__new_func(SEXP probSEXP) {
@@ -1335,6 +1346,7 @@ static const R_CallMethodDef CallEntries[] = {
13351346
{"_simmer_Rollback__new", (DL_FUNC) &_simmer_Rollback__new, 2},
13361347
{"_simmer_Rollback__new_func", (DL_FUNC) &_simmer_Rollback__new_func, 2},
13371348
{"_simmer_Leave__new", (DL_FUNC) &_simmer_Leave__new, 1},
1349+
{"_simmer_HandleUnfinished__new", (DL_FUNC) &_simmer_HandleUnfinished__new, 1},
13381350
{"_simmer_Leave__new_func", (DL_FUNC) &_simmer_Leave__new_func, 1},
13391351
{"_simmer_Clone__new", (DL_FUNC) &_simmer_Clone__new, 2},
13401352
{"_simmer_Clone__new_func", (DL_FUNC) &_simmer_Clone__new_func, 2},

src/activity.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ SEXP Leave__new(double prob) {
255255
return XPtr<Leave<double> >(new Leave<double>(prob));
256256
}
257257

258+
//[[Rcpp::export]]
259+
SEXP HandleUnfinished__new(const std::vector<Environment>& trj) {
260+
return XPtr<HandleUnfinished>(new HandleUnfinished(trj));
261+
}
262+
258263
//[[Rcpp::export]]
259264
SEXP Leave__new_func(const Function& prob) {
260265
return XPtr<Leave<Function> >(new Leave<Function>(prob));

0 commit comments

Comments
 (0)