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

Add test case to return zero on a closed channel #8167

Closed
wants to merge 6 commits into from

Conversation

kavyasrinet
Copy link

@kavyasrinet kavyasrinet commented Feb 5, 2018

This test case covers the expected behavior of receiving in a closed channel as explained in the Axioms here : https://github.com/PaddlePaddle/Paddle/blob/2500f30ef210e8e55cccb5cc18ab525941e970f2/doc/design/csp.md

@abhinavarora
Copy link
Contributor

@kavyasrinet I am not sure why we need this. @chengduoZH has already implemented a PR where the send and receive return a boolean. If channel got closed, we get a boolean false and if the send/receive was successful we get a true. I don't think this test is needed. We have already added tests for checking the boolean. This was done to keep the implementation similar to Go Channels and was also suggested by @wangkuiyi. This is how Go implements this -> https://golang.org/ref/spec#Receive_operator. As long as we provide the boolean, the channel does not need to give any guarantees on the read value. It is the responsibility of the thread that is calling receive to see what boolean was returned. it should use the value in the pointer only if true was returned.

@kavyasrinet
Copy link
Author

kavyasrinet commented Feb 5, 2018

I agree with your comment above that closing a channel will return the boolean false, but from what it looks like this in Go's implementation and from what was also mentioned in the axioms listed by @wangkuiyi here : https://github.com/PaddlePaddle/Paddle/blob/2500f30ef210e8e55cccb5cc18ab525941e970f2/doc/design/csp.md , ideally a Close operation should not only set the boolean to be false but also return a zero value to all receivers as soon as the channel is empty. In the case that we will have values written to the channel, those values will be returned first and a value of zero thereafter.
This PR was intended to perform channel operations close to how Go does it, as is also explained here: https://dave.cheney.net/2014/03/19/channel-axiomstest

In addition to the point above, once the reviewers agree on the behavior as mentioned in the unit test, I can go ahead and change the CloseChannel implementation as well to perform the mentioned behavior.

@@ -60,6 +60,32 @@ TEST(Channel, SufficientBufferSizeDoesntBlock) {
delete ch;
}

// This test tests that CloseChannel returns a value of zero
// immediately to all receivers that are trying to receive from the channel.
TEST(Channel, ReceiverGetsZeroOnClosedChannel) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the purpose of this PR is to add a unit test to ensure that

  1. receiving from a closed buffered channel returns residual values and then zeros values, and
  2. receiving from a closed unbuffered channel doesn't block and returns zero.

then this PR looks too simple to ensure the above two invariants.

Copy link
Author

Choose a reason for hiding this comment

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

I think one of the axioms was that : A receive from a closed channel returns the residual values and then zeros.
This PR tries to validate that #1 you explained above holds since we aren't explicitly checking for the zero value anywhere else.

// immediately to all receivers that are trying to receive from the channel.
TEST(Channel, ReceiverGetsZeroOnClosedChannel) {
const size_t buffer_size = 10;
auto ch = MakeChannel<size_t>(buffer_size);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This invariant should be verified with buffered and unbuffered channels.

Copy link
Author

Choose a reason for hiding this comment

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

Sure.

Copy link
Author

Choose a reason for hiding this comment

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

On a side note, correct me if I am wrong @wangkuiyi but for an unbuffered channel, since the buffer size is zero, there would be no residual values. So trying to read from a closed channel should just return a zero value, right ?

EXPECT_EQ(ch->Send(&i), true); // sending should not block
}

CloseChannel(ch);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe receive some values before CloseChannel and checks that receivings after CloseChannel return the residual values.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for pointing that out! Will fix it in a commit.

@wangkuiyi
Copy link
Collaborator

wangkuiyi commented Feb 6, 2018

#8175 This is for your reference. @kavyasrinet

@kavyasrinet
Copy link
Author

Thank you!
I just pushed similar changes in this PR too. I will wait for the CI to finish running on #8175 and we can merge it.

Copy link
Collaborator

@wangkuiyi wangkuiyi left a comment

Choose a reason for hiding this comment

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

Please refer to my PR for details

int out;
for (size_t i = 1; i <= 12; ++i) {

for (size_t i = 6; i <= 12; ++i) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Both 6 and 12 are magical numbers.

@kavyasrinet
Copy link
Author

Thank you, will do.

@kavyasrinet
Copy link
Author

Closing this, since #8175 fixes the same issue.

@kavyasrinet kavyasrinet closed this Feb 6, 2018
@kavyasrinet kavyasrinet deleted the receive_closed branch February 8, 2018 18:40
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.

3 participants