github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/google.golang.org/appengine/internal/net.go (about)

     1  // Copyright 2014 Google Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package internal
     6  
     7  // This file implements a network dialer that limits the number of concurrent connections.
     8  // It is only used for API calls.
     9  
    10  import (
    11  	"log"
    12  	"net"
    13  	"runtime"
    14  	"sync"
    15  	"time"
    16  )
    17  
    18  var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable.
    19  
    20  func limitRelease() {
    21  	// non-blocking
    22  	select {
    23  	case <-limitSem:
    24  	default:
    25  		// This should not normally happen.
    26  		log.Print("appengine: unbalanced limitSem release!")
    27  	}
    28  }
    29  
    30  func limitDial(network, addr string) (net.Conn, error) {
    31  	limitSem <- 1
    32  
    33  	// Dial with a timeout in case the API host is MIA.
    34  	// The connection should normally be very fast.
    35  	conn, err := net.DialTimeout(network, addr, 500*time.Millisecond)
    36  	if err != nil {
    37  		limitRelease()
    38  		return nil, err
    39  	}
    40  	lc := &limitConn{Conn: conn}
    41  	runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required
    42  	return lc, nil
    43  }
    44  
    45  type limitConn struct {
    46  	close sync.Once
    47  	net.Conn
    48  }
    49  
    50  func (lc *limitConn) Close() error {
    51  	defer lc.close.Do(func() {
    52  		limitRelease()
    53  		runtime.SetFinalizer(lc, nil)
    54  	})
    55  	return lc.Conn.Close()
    56  }