-
Notifications
You must be signed in to change notification settings - Fork 82
Improve resiliency of entities when destroyed #897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve resiliency of entities when destroyed #897
Conversation
entity.js - added _destroy(), isDestroyed() - added cache to hold obsolete _handles to avoid premature GC entity.d.ts - added isDestroyed() node.js - added guard statements to execute() to filter out destroyed entities action/client.js - added _destory() and isDestroyed() - refactored destroy() flow action/server.js - added _destory() and isDestroyed() - refactored destroy() flows main.ts - added tests for isDestroyed() to entity subclasses test-destruction.js - added entity.destory() test cases
entity.js - added static gcHandles() node.js - revised execute() to use for-of loops for each entity type. This simplifies the looping of each group of entities through the use of loop interruption (e.g., use continue statement) to detect a destroyed entity before processing. Additionally it the for-of loop reduces the number of isDestroyed() calls Lastly, added a call to Entity.gcHandles() prior to exiting the method.
f3840e2 to
9af468f
Compare
|
@minggangw my latest commit 9af468f to address your suggestion may have overwritten f3840e2 |
Sorry for missing this comment, the change looks good to me, thanks! |
minggangw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for fixing the crashing issue
|
Hi @wayneparrott I have approved this PR, please go ahead to merge it after resolving the conflict, thanks! |
* improve entity destroy() resiliency #896 entity.js - added _destroy(), isDestroyed() - added cache to hold obsolete _handles to avoid premature GC entity.d.ts - added isDestroyed() node.js - added guard statements to execute() to filter out destroyed entities action/client.js - added _destory() and isDestroyed() - refactored destroy() flow action/server.js - added _destory() and isDestroyed() - refactored destroy() flows main.ts - added tests for isDestroyed() to entity subclasses test-destruction.js - added entity.destory() test cases * improve destroyed entity handling to avoid segfault entity.js - added static gcHandles() node.js - revised execute() to use for-of loops for each entity type. This simplifies the looping of each group of entities through the use of loop interruption (e.g., use continue statement) to detect a destroyed entity before processing. Additionally it the for-of loop reduces the number of isDestroyed() calls Lastly, added a call to Entity.gcHandles() prior to exiting the method.
Issue #896 identifies an race condition where multiple subscriptions listen to a common topic and one subscription, from it's callback destroys another subscription (an entity). This revealed an issue where i/o activity can exists on an entity's _handle after the entity has been destroyed. The result is an invalid entity pointer or worse a SEGFAULT. To address this I've added destroy state semantics to the Entity class.
full disclosure:
One quirky behavior I've attempted to resolve is that setting
Entity._handle = null, results in the _handle being quickly GC'ed. This causes the SEGFAULT when the handle is still referenced by ShadowNode.Execute(). I believe after calling _handle.release(), the handle must not be GC'ed until after the current Node.execute() completes. I was not sure how to pull this off in C with Nan API so I implemented a hack by using a cache to hold_handle's after theirrelease(). The cache will flush when its size exceeds a const (100 atm). I'm definitely open to revising this hack with the suggestion of others.entity.js
entity.d.ts
node.js
action/client.js
action/server.js
main.ts
test-destruction.js
Fix #896