context.destroy() does not trigger destroylistener appropriately
warmuuh opened this issue · comments
developing a plugin, i was unittesting my destroy listener using this code:
wire(spec, {require:require}).then(function(ctx){
//get a bean
ctx.destroy().then(function(){
//assert something on the bean
});
}, console.error);
it seems that the destroy listener are not called appropriately. (though in my normal code, they ARE called somewhen...)
Hey @warmuuh, I may not understand the case you're talking about. I added a unit test for the case I thought you meant, and it passes, so I think I need some help in understanding your situation. Could you provide (preferably) a runnable example, or at least more detail in the case above? For example, could you show the contents of the spec
and an assertion you expect would pass, but instead fails?
Thanks!
Also, I just remembered this test, which verifies that the component lifecycle listeners, including component destroy listeners, are invoked at the appropriate times.
Component lifecycle listeners are notified for each component's lifecycle transitions, and context lifecycle listeners are notified for for the overall context's lifecycle transitions. AFAICT, both seem to be working correctly.
Hmmm, the wire plugin format changed in 0.10. I wonder if that is causing issues, since you're working on a plugin.
In wire < 0.10, a plugin looked like this:
{
wire$plugin: function(options, ready, destroyed) {
// return plugin instance
}
}
And in 0.10 the new format is preferred (we try to support the old format, but it's possible there is a bug):
function(options) {
// return plugin instance
}
So, instead of being an object with a wire$plugin
property, plugins are now just a function that accepts options.
Also noticed that the ready
and destroyed
promises are no longer passed in. While they were simple to use, they introduced some potential problems and race conditions between plugins. Those promises have been replaced by a new context event listener system, which provides more events, and fixes all the problems with the potential race conditions.
Here's a quick example of a plugin that uses context event listeners:
function(options) {
return {
context: {
initialize: function(resolver, wire) {
// the context is being initialized, but no wiring has occurred yet.
},
ready: function(resolver, wire) {
// the context is ready
}
shutdown: function(resolver, wire) {
// the context is **entering** the destroy phase. It has not
// yet been destroyed, but is about to be!
},
destroy: function(resolver, wire) {
// the context has been destroyed
}
}
// More plugin stuff here
};
}
So, for example, if you had previously been relying on the destroyed
promise, like this:
{
wire$plugin: function(options, ready, destroyed) {
destroyed.then(function() {
// Do cleanup
});
}
}
You can refactor it to:
function(options) {
return {
context: {
destroy: function(resolver, wire) {
// Do cleanup, and then
resolver.resolve();
// Or, if you need to cleanup asynchronously:
doAsynchronousCleanup().then(resolver.resolve, resolver.reject);
}
}
};
}
Let me know if that helps. If not, please provide more detail if you can. Thanks!
well, i was using the shutdown listener instead of the destroy listener. it does not seem to work as expected anymore, or does it? :D
code:
//testplugin.js
module.exports = function() {
return {'shutdown':function(r){
console.log("test");
r.resolve();
}
}
}
and the wiring:
var spec = {
bean: "test",
$plugins: [{module:'./testplugin'}]
};
wire(spec, {require:require}).then(function(ctx){
var bean = ctx.bean;
ctx.destroy().then(function(){
test.done();
});
}, console.error);
with 'destroy', it works, the test output is visible
Thanks, @warmuuh, I'll dig into it.
After a quick look back at the code an unit tests for 0.9.0 - 0.9.4, I don't see a version in that range that supported a per-component event named shutdown
. Were you using 0.9.x or something earlier, like 0.8.x?
Would it work for you to use the destroy event? or perhaps destroy:before
if you want to do something just before a component is destroyed. Let me know if one of those will work for you.
@warmuuh Just wondering what the status of this is. If this is still an issue, please have a look at the questions in my last comment. Thanks!
i am sorry, but i hadn't any time lately to verify the issue. but it looks like i made a mistake and it works with the destroy listener. probably i just mixed something up. sorry for the confusion :D
No problem at all. Glad it's working for you!