github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/instance_mgt/get.go (about)

     1  // Package instance_mgt computes instance info; views are in instance_info.
     2  package instance_mgt
     3  
     4  import (
     5  	"net/http"
     6  
     7  	"errors"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/pbberlin/tools/appengine/util_appengine"
    12  	"github.com/pbberlin/tools/stringspb"
    13  	"golang.org/x/net/context"
    14  	"google.golang.org/appengine"
    15  	"google.golang.org/appengine/module"
    16  
    17  	aelog "google.golang.org/appengine/log"
    18  )
    19  
    20  var ii *Instance = new(Instance) // initialization check via ii.LastUpdated.IsZero()
    21  
    22  func GetStatic() *Instance {
    23  	return ii
    24  }
    25  
    26  func Get(r *http.Request) *Instance {
    27  	c := util_appengine.SafelyExtractGaeContext(r)
    28  	return GetByContext(c)
    29  }
    30  
    31  // Todo: When c==nil we are in a non-appengine environment.
    32  // We still want to return at least ii.PureHostname
    33  func GetByContext(c context.Context) *Instance {
    34  
    35  	tstart := time.Now()
    36  
    37  	if !ii.LastUpdated.IsZero() {
    38  
    39  		age := tstart.Sub(ii.LastUpdated)
    40  
    41  		if age < 200*time.Millisecond {
    42  			aelog.Infof(c, "instance info update too recently: %v, skipping.\n", age)
    43  			return ii
    44  		}
    45  
    46  		if age < 1*time.Hour {
    47  			if len(ii.Hostname) > 2 {
    48  				return ii
    49  			}
    50  
    51  		}
    52  
    53  		aelog.Infof(c, "instance info update too old: %v, recomputing.\n", age)
    54  	}
    55  
    56  	ii.ModuleName = appengine.ModuleName(c)
    57  	ii.InstanceID = appengine.InstanceID()
    58  	ii.VersionFull = appengine.VersionID(c)
    59  
    60  	majorMinor := strings.Split(ii.VersionFull, ".")
    61  	if len(majorMinor) != 2 {
    62  		panic("we need a version string of format X.Y")
    63  	}
    64  
    65  	ii.VersionMajor = majorMinor[0]
    66  	ii.VersionMinor = majorMinor[1]
    67  
    68  	var err = errors.New("dummy creation error message")
    69  
    70  	ii.NumInstances, err = module.NumInstances(c, ii.ModuleName, ii.VersionFull)
    71  	if err != nil {
    72  		// this never works with version full
    73  		// we do not log this - but try version major
    74  		err = nil
    75  
    76  		if !util_appengine.IsLocalEnviron() {
    77  			ii.NumInstances, err = module.NumInstances(c, ii.ModuleName, ii.VersionMajor)
    78  
    79  			if err != nil {
    80  				eStr := err.Error()
    81  				eCmp1, eCmp2, eCmp3 := "API error", "INVALID_VERSION)", "Could not find the given version"
    82  				if strings.Contains(eStr, eCmp1) && strings.Contains(eStr, eCmp2) && strings.Contains(eStr, eCmp3) {
    83  					aelog.Infof(c, "get num instances works only live and without autoscale; %v", err)
    84  				} else {
    85  					aelog.Errorf(c, "get num instances error; %v", err)
    86  				}
    87  			}
    88  
    89  		}
    90  
    91  	}
    92  
    93  	// in auto scaling, google reports "zero" - which can not be true
    94  	// we assume at least 1
    95  	if ii.NumInstances == 0 {
    96  		ii.NumInstances = 1
    97  	}
    98  
    99  	// http://[0-2].1.default.libertarian-islands.appspot.com/instance-info
   100  
   101  	ii.Hostname, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "")
   102  	if err != nil {
   103  		aelog.Errorf(c, "ModuleHostname1: %v", err)
   104  	}
   105  
   106  	ii.PureHostname = appengine.DefaultVersionHostname(c)
   107  
   108  	if !appengine.IsDevAppServer() {
   109  		ii.HostnameInst0, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "0")
   110  		if err != nil && (err.Error() == autoScalingErr1 || err.Error() == autoScalingErr2) {
   111  			aelog.Infof(c, "inst 0: "+autoScalingErrMsg)
   112  			err = nil
   113  		}
   114  		if err != nil {
   115  			aelog.Errorf(c, "ModuleHostname2: %v", err)
   116  		}
   117  
   118  		ii.HostnameInst1, err = appengine.ModuleHostname(c, ii.ModuleName, ii.VersionMajor, "1")
   119  		if err != nil && (err.Error() == autoScalingErr1 || err.Error() == autoScalingErr2) {
   120  			aelog.Infof(c, "inst 1: "+autoScalingErrMsg)
   121  			err = nil
   122  		}
   123  		if err != nil {
   124  			aelog.Errorf(c, "ModuleHostname3: %v", err)
   125  		}
   126  
   127  		ii.HostnameMod02, err = appengine.ModuleHostname(c, "mod02", "", "")
   128  		if err != nil {
   129  			aelog.Infof(c, "ModuleHostname4: %v", err)
   130  		}
   131  
   132  	}
   133  
   134  	ii.LastUpdated = time.Now()
   135  
   136  	aelog.Infof(c, "collectInfo() completed, %v  - %v - %v - %v - %v, took %v",
   137  		stringspb.Ellipsoider(ii.InstanceID, 4), ii.VersionMajor, ii.ModuleName,
   138  		ii.Hostname, ii.PureHostname, time.Now().Sub(tstart))
   139  
   140  	return ii
   141  }