gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

net.go (1230B)


      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, 10*time.Second)
     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 }