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

server.Serve returns error after GracefulStop #1017

Closed
jsha opened this issue Dec 8, 2016 · 4 comments
Closed

server.Serve returns error after GracefulStop #1017

jsha opened this issue Dec 8, 2016 · 4 comments

Comments

@jsha
Copy link
Contributor

jsha commented Dec 8, 2016

Steps to reproduce:

  1. Set up a gRPC server listening in a goroutine.
  2. At some later time, call server.GracefulStop()

Expected result:

server.Serve() returns nil error

Actual result:

server.Serve() returns accept tcp [::]:50051: use of closed network connection

// testServer is used to implement InterceptorTest
type testServer struct{}

// Chill implements InterceptorTest.Chill
func (s *testServer) Chill(ctx context.Context, in *Time) (*Time, error) {
	start := time.Now()
	time.Sleep(time.Duration(*in.Time) * time.Nanosecond)
	spent := int64(time.Since(start) / time.Nanosecond)
	return &Time{Time: &spent}, nil
}

func TestGracefulStopNoError(t *testing.T) {
	const port = ":50051"

	lis, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	RegisterInterceptorTestServer(s, &testServer{})
	go func() {
		start := time.Now()
		if err := s.Serve(lis); err != nil {
			t.Fatalf("s.Serve: %v after %s", err, time.Since(start))
		}
	}()

	// Set up a connection to the server.
	conn, err := grpc.Dial("localhost"+port, grpc.WithInsecure())
	if err != nil {
		t.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := NewInterceptorTestClient(conn)
	var second int64 = time.Second.Nanoseconds()
	spent, err := c.Chill(context.Background(), &Time{Time: &second})
	if err != nil {
		t.Fatal("Calling Chill: %s", err)
	}
	t.Logf("Successfully chilled for %s", time.Duration(*spent.Time)*time.Nanosecond)

	s.GracefulStop()
}
syntax = "proto2";

option go_package = "grpc";

service InterceptorTest {
  // Sleep for the given amount of time, and return the amount of time slept.
  rpc Chill(Time) returns (Time) {}
}

message Time {
  optional int64 time = 1; // In nanoseconds
}

Output:

            interceptors_test.go:115: s.Serve: accept tcp [::]:50051: use of closed network connection after 1.001130858s
@menghanl
Copy link
Contributor

menghanl commented Dec 8, 2016

Serve() returns the fatal error returned by lis.Accept.
And lis.Accept returns use of closed network connection error when it's closed.

@menghanl menghanl closed this as completed Dec 8, 2016
@jsha
Copy link
Contributor Author

jsha commented Dec 8, 2016

@menghanl: So, assuming that I log all errors returned from Serve(), how do I accomplish a clean shutdown that does not log any errors?

Also, is there any situation in which Serve() will return without an error? If not, that should be documented.

@menghanl
Copy link
Contributor

menghanl commented Dec 8, 2016

Serve() always returns non-nil error. I will create a PR to document that.

One way to get a clean log is to filter errors with use of closed network connection, because error net.errClosing is not exported.

@menghanl
Copy link
Contributor

menghanl commented Dec 8, 2016

#1018 created

@lock lock bot locked as resolved and limited conversation to collaborators Sep 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants