func TestLimitedConnListenerAccept(t *testing.T) {
	if _, err := runtime.FDUsage(); err != nil {
		t.Skip("skip test due to unsupported runtime.FDUsage")
	}

	ln, err := net.Listen("tcp", ":0")
	if err != nil {
		t.Fatal(err)
	}
	fdNum, err := runtime.FDUsage()
	if err != nil {
		t.Fatal(err)
	}
	srv := &httptest.Server{
		Listener: &LimitedConnListener{
			Listener:       ln,
			RuntimeFDLimit: fdNum + 100,
		},
		Config: &http.Server{},
	}
	srv.Start()
	defer srv.Close()

	resp, err := http.Get(srv.URL)
	defer resp.Body.Close()
	if err != nil {
		t.Fatalf("Get error = %v, want nil", err)
	}
}
Example #2
0
func monitorFileDescriptor(done <-chan struct{}) {
	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()
	for {
		used, err := runtime.FDUsage()
		if err != nil {
			plog.Errorf("cannot monitor file descriptor usage (%v)", err)
			return
		}
		fileDescriptorUsed.Set(float64(used))
		limit, err := runtime.FDLimit()
		if err != nil {
			plog.Errorf("cannot monitor file descriptor usage (%v)", err)
			return
		}
		if used >= limit/5*4 {
			plog.Warningf("80%% of the file descriptor limit is used [used = %d, limit = %d]", used, limit)
		}
		select {
		case <-ticker.C:
		case <-done:
			return
		}
	}
}
func (l *LimitedConnListener) Accept() (net.Conn, error) {
	conn, err := l.Listener.Accept()
	if err != nil {
		return nil, err
	}

	n, err := runtime.FDUsage()
	// Check whether fd number in use exceeds the set limit.
	if err == nil && n >= l.RuntimeFDLimit {
		conn.Close()
		plog.Errorf("accept error: closing connection, exceed file descriptor usage limitation (fd limit=%d)", l.RuntimeFDLimit)
		return nil, &acceptError{error: errors.New("exceed file descriptor usage limitation"), temporary: true}
	}
	return conn, nil
}
func TestLimitedConnListenerLimit(t *testing.T) {
	if _, err := runtime.FDUsage(); err != nil {
		t.Skip("skip test due to unsupported runtime.FDUsage")
	}

	ln, err := net.Listen("tcp", ":0")
	if err != nil {
		t.Fatal(err)
	}
	srv := &httptest.Server{
		Listener: &LimitedConnListener{
			Listener:       ln,
			RuntimeFDLimit: 0,
		},
		Config: &http.Server{},
	}
	srv.Start()
	defer srv.Close()

	_, err = http.Get(srv.URL)
	if err == nil {
		t.Fatalf("unexpected nil Get error")
	}
}