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) } }
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") } }