In order to prevent concurrent access to some resources, the renderJS methods can be protected by a mutex.
A protected method is executed only when the previous call is resolved/rejected.
One mutex can also be uses to protect the different methods.
To use a mutex, pass an optional "mutex" parameter to the declareMethod like:
.declareMethod("methodName", function () {...}, {mutex: "mutex_name"})
Here is a full example:
Create one child gadget
HTML
<html>
<head>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="howto_mutex_child.js"></script>
</head>
<body>
</body>
</html>
JS
(function (rJS, RSVP, window) {
"use strict";
function resetCounter() {
this.counter = 0;
}
function increaseCounterAndWaitAndReturn() {
var gadget = this;
gadget.counter += 1;
return new RSVP.Queue(RSVP.delay(50))
.push(function () {
return gadget.counter;
});
}
rJS(window)
.ready(resetCounter)
.declareMethod("executeNotProtectedMethod", increaseCounterAndWaitAndReturn)
.declareMethod("executeFirstNonConcurrentMethod", increaseCounterAndWaitAndReturn, {mutex: "first_mutex"})
.declareMethod("executeSecondNonConcurrentMethod", increaseCounterAndWaitAndReturn, {mutex: "first_mutex"})
.declareMethod("resetCounter", resetCounter);
}(rJS, RSVP, window));
Create the parent gadget
HTML
<html>
<head>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="howto_mutex_parent.js"></script>
</head>
<body>
<pre></pre>
</body>
</html>
JS
(function (rJS, RSVP, window) {
"use strict";
function log(gadget, text, expected_value, value) {
gadget.element.querySelector("pre").textContent += text + " - expected: " + expected_value + " got: " + value + "\n";
}
rJS(window)
.declareService(function () {
var parent_gadget = this,
child_gadget;
return parent_gadget.declareGadget("howto_mutex_child.html", {scope: "child_scope"})
.push(function (result) {
child_gadget = result;
// If not protected with a mutex, method are executed concurrently
return RSVP.all([
child_gadget.executeNotProtectedMethod(),
child_gadget.executeNotProtectedMethod()
]);
})
.push(function (result_list) {
log(parent_gadget, "First executeNotProtectedMethod", 2, result_list[0]);
log(parent_gadget, "Second executeNotProtectedMethod", 2, result_list[1]);
// One method is protected by a mutex
return RSVP.all([
child_gadget.resetCounter(),
child_gadget.executeFirstNonConcurrentMethod(),
child_gadget.executeFirstNonConcurrentMethod()
]);
})
.push(function (result_list) {
log(parent_gadget, "First executeFirstNonConcurrentMethod", 1, result_list[1]);
log(parent_gadget, "Second executeFirstNonConcurrentMethod", 2, result_list[2]);
// Two different methods can use the same mutex
return RSVP.all([
child_gadget.resetCounter(),
child_gadget.executeFirstNonConcurrentMethod(),
child_gadget.executeSecondNonConcurrentMethod()
]);
})
.push(function (result_list) {
log(parent_gadget, "First executeFirstNonConcurrentMethod", 1, result_list[1]);
log(parent_gadget, "Second executeSecondNonConcurrentMethod", 2, result_list[2]);
});
});
}(rJS, RSVP, window));