Skip to content
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

Use Result in several places and solve double deletion problem #260

Merged
merged 2 commits into from
Sep 12, 2017

Conversation

torkleyy
Copy link
Member

@torkleyy torkleyy commented Sep 10, 2017

Not meant to be merged as is

Fixes #94

@torkleyy torkleyy force-pushed the deltw branch 3 times, most recently from cb6c193 to 97ff65e Compare September 11, 2017 09:17
@torkleyy
Copy link
Member Author

Okay, I think this is ready for review now.

Copy link
Contributor

@csherratt csherratt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looks ok.

src/error.rs Outdated
#[derive(Debug)]
pub struct WrongGeneration {
/// The action that failed because of the wrong generation.
pub action: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be an enum or a &'static string?

WrongGeneration(WrongGeneration),

#[doc(hidden)]
__NonExhaustive,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of breakage would occur without this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a client matches against all the variants and we add one, it would cause an error about non-exhaustive matching. By having this additional variant which should never be used, the user is forced to match against _. This is a very common pattern (even the standard library uses it, see https://doc.rust-lang.org/src/core/sync/atomic.rs.html#220) and there's an RFC about creating an attribute #[non_exhaustive] for just this case.

Copy link
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable. I have 2 concerns:

  1. some clients may be better at tracking the entity lifetimes, so we should provide an unsafe way to delete those without extra checks
  2. better have an enum for the action, like @csherratt noted

@torkleyy
Copy link
Member Author

@kvark A deletion without checks wouldn't really be unsafe, the semantics are just not clearly defined (whether it panics or it's silently ignored). Benchmarking both versions, I cannot see any difference in performance (it may be the case that other checks are eliminated, idk). So if the difference is smaller than 1 ns/iter, would it still make sense to add a second variant?

* Move BoxedErr out of common module
* Add unified Error type
* Add WrongGeneration error
@kvark
Copy link
Member

kvark commented Sep 12, 2017

A deletion without checks wouldn't really be unsafe, the semantics are just not clearly defined (whether it panics or it's silently ignored)

Even better then - let's have a safe version that ignores the errors. For ergonomics and this undetectable bit of performance ;)

@torkleyy
Copy link
Member Author

So should the _unchecked version not do the check or just silently ignore a deletion of a dead entity?

@torkleyy
Copy link
Member Author

torkleyy commented Sep 12, 2017

I'm assuming the latter right now, but it's not clear to me. I added these Results because before the behavior was pretty much undefined.

Here's the previous behavior (without checks):

  • Both kill and kill_atomic don't check the generation of the entity. Thus, an entity with an old id could be used to delete an entity with a newer id.
  • kill would cause a panic in debug mode if the entity has been deleted by kill or a merged kill_atomic
  • kill_atomic would cause a panic in debug mode if the entity has been deleted by kill or a merged kill_atomic
  • a second kill_atomic would be silently ignored if called twice on the same entity, but in the same frame

Given this confusing behavior, I thought that a clear check would be better. So I'm not sure if it makes sense to offer a version without a check at all (as opposed to checking and ignoring).

@kvark
Copy link
Member

kvark commented Sep 12, 2017

Ok, that's convincing enough. Thank you!
bors r+

bors bot added a commit that referenced this pull request Sep 12, 2017
260: Use Result in several places and solve double deletion problem r=kvark a=torkleyy

Not meant to be merged as is

Fixes #94
@bors
Copy link
Contributor

bors bot commented Sep 12, 2017

Build succeeded

@bors bors bot merged commit f12a9f9 into amethyst:master Sep 12, 2017
@torkleyy torkleyy deleted the deltw branch September 12, 2017 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants