Import changes for goma server
- 385321ccbc2988a9c4aedfd8d14576685c862edd server: use debug.FreeOSMemory instead of runtime.GC
- 42d70fca0b08e96a1131fcf1b2e2f0ad013da146 file-server: run gc if it closes to memory limit
- 9429c487a29f3ea81339f7a95319f1e926e0b511 roll cloud.google.com/go v0.43.0 -> v0.44.0
- 3f170eff09fc736e254180059e8e3cc48fc729ab Revert "gcs: use minimum object attrs"
- cac1c4d83526f60224aba62a8b5cd8bac331f039 roll google.golang.org/api v0.7.0 -> v0.9.0
- 01fdf185317e4caf233dcce5712fb8dc32b399ea gcs: use minimum object attrs
- 14ec7e530bfe82ff5d656b422d00323955300f95 [inventory] Fix a potential DoS bug in pickCmd
- a52be572c6807d30456e825e5a7698362d968562 [descriptor] Add dart toolchain support
- 75e121b560bdd00623d861a09c0857cf0ad8fc5d memroy -> memory
- 9c1f9e3da7dc4e30a92dd2aaf0cbd29ea852ca15 roll google.golang.org/grpc 1.22.1 -> 1.23.0
- 134589fd7a3ebd74517e286897d58b44480a26ad use go 1.12.8
- edde7c0ba6454173f3ec5a2d74c81f6d4a7528e0 remoteexec: retry for status Aborted
- 8e18012b0006f36ff3020a3aadb92ce456f4c35c command: pubsub-error uses last value
- 2610736422dbd6900481649d871480e3afb5e2c5 command: reports pubsubErrors=0 if pubsub is available
- aa10576e7eec25a69153ec4c5d7128223914cec3 command: set expiration policy to subscriptions
- 0a93bf24a2eef1314f7e419e739161ca843aa82a remoteexec: retry if aborted but caller ctx is active.
- fd6b433ad85171b8c2d8a07694ec9e7c2f810399 command: fallback poller if subscription is not available
- f020d98f49a687a2b67d21ddecc3cd62a7cc4a3a roll google.golang.org/grpc 1.22.0 to 1.22.1
GitOrigin-RevId: 385321ccbc2988a9c4aedfd8d14576685c862edd
Change-Id: Ida45d03d064ba365a882f8d4ed0ba3d5111704ac
TBR=yyanagisawa@google.com, tikuta@google.com, sque@google.com
diff --git a/cache/gcs/cache.go b/cache/gcs/cache.go
index 13c6845..ae672b0 100644
--- a/cache/gcs/cache.go
+++ b/cache/gcs/cache.go
@@ -25,12 +25,12 @@
// AdmissionController checks incoming request.
type AdmissionController interface {
- AdmitPut(*pb.PutReq) error
+ AdmitPut(context.Context, *pb.PutReq) error
}
type nullAdmissionController struct{}
-func (nullAdmissionController) AdmitPut(*pb.PutReq) error { return nil }
+func (nullAdmissionController) AdmitPut(context.Context, *pb.PutReq) error { return nil }
// Cache represents key-value cache using google cloud storage.
type Cache struct {
@@ -80,7 +80,7 @@
func (c *Cache) Put(ctx context.Context, in *pb.PutReq) (*pb.PutResp, error) {
logger := log.FromContext(ctx)
- if err := c.AdmissionController.AdmitPut(in); err != nil {
+ if err := c.AdmissionController.AdmitPut(ctx, in); err != nil {
logger.Warnf("admission error: %v", err)
return nil, err
}
diff --git a/cipd_manifest.txt b/cipd_manifest.txt
index 9ee7676..c1ed9fc 100644
--- a/cipd_manifest.txt
+++ b/cipd_manifest.txt
@@ -13,7 +13,7 @@
# https://chrome-infra-packages.appspot.com/
# go
-infra/go/${platform} version:1.12.7
+infra/go/${platform} version:1.12.8
# protoc
# If the version you want is missing, please follow the instruction in:
diff --git a/cipd_manifest.versions b/cipd_manifest.versions
index aa8ddf8..e872a11 100644
--- a/cipd_manifest.versions
+++ b/cipd_manifest.versions
@@ -2,8 +2,8 @@
# Do not modify manually. All changes will be overwritten.
infra/go/linux-amd64
- version:1.12.7
- lBm3oqkMtwrbllgPo-1cOqivkJcZpRUY-hO74LduBdMC
+ version:1.12.8
+ OLqQMFvS8z1pNzfA-phVWbqmITB3vqFIKGUMhEZtEcAC
infra/tools/protoc/linux-amd64
protobuf_version:v3.7.0
diff --git a/cmd/exec_server/main.go b/cmd/exec_server/main.go
index 68eaece..583489b 100644
--- a/cmd/exec_server/main.go
+++ b/cmd/exec_server/main.go
@@ -186,13 +186,7 @@
SubscriberID: fmt.Sprintf("toolchain-config-%s-%s", server.ClusterName(ctx), server.HostName(ctx)),
RemoteexecAddr: *remoteexecAddr,
}
- cs.w, err = cs.configmap.Watcher(ctx)
- if err != nil {
- if cs.psclient != nil {
- cs.psclient.Close()
- }
- return nil, fmt.Errorf("watch failed: %v", err)
- }
+ cs.w = cs.configmap.Watcher(ctx)
cs.loader = &command.ConfigMapLoader{
ConfigMap: cs.configmap,
ConfigLoader: command.ConfigLoader{
@@ -290,6 +284,10 @@
if err != nil {
logger.Fatal(err)
}
+ err = view.Register(command.DefaultViews...)
+ if err != nil {
+ logger.Fatal(err)
+ }
err = view.Register(exec.DefaultViews...)
if err != nil {
logger.Fatal(err)
diff --git a/cmd/file_server/main.go b/cmd/file_server/main.go
index 3424cce..3c5b333 100644
--- a/cmd/file_server/main.go
+++ b/cmd/file_server/main.go
@@ -45,17 +45,18 @@
limit int64
}
-func (a admissionController) AdmitPut(in *cachepb.PutReq) error {
+func (a admissionController) AdmitPut(ctx context.Context, in *cachepb.PutReq) error {
if a.limit <= 0 {
return nil
}
rss := server.ResidentMemorySize()
s := int64(len(in.Kv.Key) + len(in.Kv.Value))
- if rss+s <= a.limit {
+ if rss+2*s <= a.limit {
return nil
}
+ newRSS := server.GC(ctx)
// TODO: with retryinfo?
- return status.Errorf(codes.ResourceExhausted, "memory size %d + req:%d > limit %d", rss, s, a.limit)
+ return status.Errorf(codes.ResourceExhausted, "memory size %d + req:%d > limit %d: gc->%d", rss, s, a.limit, newRSS)
}
func main() {
diff --git a/command/configmap.go b/command/configmap.go
index 4275fd4..cd86678 100644
--- a/command/configmap.go
+++ b/command/configmap.go
@@ -9,23 +9,42 @@
"context"
"errors"
"fmt"
+ "math/rand"
"path"
"sort"
"strings"
"time"
- "google.golang.org/api/iterator"
-
"cloud.google.com/go/pubsub"
"cloud.google.com/go/storage"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/googleapis/google-cloud-go-testing/storage/stiface"
+ "go.opencensus.io/stats"
+ "go.opencensus.io/stats/view"
+ "google.golang.org/api/iterator"
"go.chromium.org/goma/server/log"
cmdpb "go.chromium.org/goma/server/proto/command"
)
+var (
+ pubsubErrors = stats.Int64(
+ "go.chromium.org/goma/command/configmap.pubsub-error",
+ "configmap pubsub error",
+ stats.UnitDimensionless)
+
+ // DefaultViews are the default views provided by this package.
+ // You need to register the view for data to actually be collected.
+ DefaultViews = []*view.View{
+ {
+ Description: "configmap pubsub error",
+ Measure: pubsubErrors,
+ Aggregation: view.LastValue(),
+ },
+ }
+)
+
// ConfigMapLoader loads toolchain_config config map.
//
// ConfigMap provides Watcher, Seqs, Bucket and RuntimeConfigs.
@@ -44,7 +63,7 @@
// ConfigMap is an interface to access toolchain config map.
type ConfigMap interface {
// Watcher returns config map watcher.
- Watcher(ctx context.Context) (ConfigMapWatcher, error)
+ Watcher(ctx context.Context) ConfigMapWatcher
// Seqs returns a map of config name to sequence.
Seqs(ctx context.Context) (map[string]string, error)
@@ -178,6 +197,34 @@
return w.s.Delete(ctx)
}
+type configMapBucketPoller struct {
+ baseDelay time.Duration
+ done chan bool
+}
+
+func (w configMapBucketPoller) Next(ctx context.Context) error {
+ logger := log.FromContext(ctx)
+ dur := time.Duration(float64(w.baseDelay) * (1 + 0.2*(rand.Float64()*2-1)))
+ logger.Infof("poll wait %s", dur)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-w.done:
+ return errors.New("poller closed")
+ case <-time.After(dur):
+ // trigger to load seqs, but loader might detect no seq updates.
+ return nil
+ }
+}
+
+func (w configMapBucketPoller) Close() error {
+ ctx := context.Background()
+ logger := log.FromContext(ctx)
+ logger.Infof("poller close")
+ close(w.done)
+ return nil
+}
+
func (c ConfigMapBucket) configMap(ctx context.Context) (*cmdpb.ConfigMap, error) {
bucket, obj, err := splitGCSPath(c.URI)
if err != nil {
@@ -221,7 +268,23 @@
var storageNotification = cloudStorageNotification
-func (c ConfigMapBucket) Watcher(ctx context.Context) (ConfigMapWatcher, error) {
+func (c ConfigMapBucket) Watcher(ctx context.Context) ConfigMapWatcher {
+ logger := log.FromContext(ctx)
+ w, err := c.pubsubWatcher(ctx)
+ if err == nil {
+ stats.Record(ctx, pubsubErrors.M(0))
+ logger.Infof("use pubsub watcher")
+ return w
+ }
+ stats.Record(ctx, pubsubErrors.M(1))
+ logger.Errorf("failed to use pubsub watcher: %v", err)
+ return configMapBucketPoller{
+ baseDelay: 1 * time.Hour,
+ done: make(chan bool),
+ }
+}
+
+func (c ConfigMapBucket) pubsubWatcher(ctx context.Context) (ConfigMapWatcher, error) {
bucket, _, err := splitGCSPath(c.URI)
if err != nil {
return nil, err
@@ -257,6 +320,11 @@
logger.Infof("subscriber:%s not found. creating", c.SubscriberID)
subscription, err = c.PubsubClient.CreateSubscription(ctx, c.SubscriberID, pubsub.SubscriptionConfig{
Topic: topic,
+ // experimental config.
+ // minimum is 1 day
+ // +12 hours margin, to cover summar time switch (+1 hour)
+ // b/112820308
+ ExpirationPolicy: 36 * time.Hour,
})
if err != nil {
return nil, fmt.Errorf("create subscription:%s err:%v", c.SubscriberID, err)
diff --git a/command/descriptor/descriptor.go b/command/descriptor/descriptor.go
index be043c8..9bb076f 100644
--- a/command/descriptor/descriptor.go
+++ b/command/descriptor/descriptor.go
@@ -529,6 +529,12 @@
return nil, fmt.Errorf("target %s [%s]: %v", c.Filename, sha256, err)
}
}
+ case "dartanalyzer":
+ v, t, err = dartAnalyzerVersionTarget(c.Filename, c.Runner)
+ if err != nil {
+ return nil, err
+ }
+
default:
// subprogram would not have version,target (?)
}
@@ -706,3 +712,25 @@
}
return ClangClTarget(out)
}
+
+// DartAnalyzerVersionTarget returns the dartanalyzer's version and target from
+// output of `dartanalyzer --version`
+func DartAnalyzerVersionTarget(out []byte) (string, string, error) {
+ // output should be like
+ // `dartanalyzer version 2.1.1-dev.1.0`.
+ const dartanalyzerPrefix = "dartanalyzer version "
+ output := strings.TrimSpace(string(out))
+ if !strings.HasPrefix(output, dartanalyzerPrefix) {
+ return "", "", fmt.Errorf("failed to parse dartanalyzer version: %q", output)
+ }
+ // dartanalyzer does not have a target. Always return linux here.
+ return output[len(dartanalyzerPrefix):], "x86_64-unknown-linux-gnu", nil
+}
+
+func dartAnalyzerVersionTarget(cmd string, runner Runner) (string, string, error) {
+ out, err := runner(cmd, "--version")
+ if err != nil {
+ return "", "", fmt.Errorf("failed to take dartanalyzer version and target: %v", err)
+ }
+ return DartAnalyzerVersionTarget(out)
+}
diff --git a/command/descriptor/descriptor_test.go b/command/descriptor/descriptor_test.go
index 8c97244..1c4008c 100644
--- a/command/descriptor/descriptor_test.go
+++ b/command/descriptor/descriptor_test.go
@@ -338,6 +338,46 @@
}
}
+func TestDartAnalyzerVersionTarget(t *testing.T) {
+ for _, tc := range []struct {
+ out string
+ version string
+ target string
+ }{
+ {
+ out: "dartanalyzer version 2.1.1-dev.1.0\n",
+ version: "2.1.1-dev.1.0",
+ target: "x86_64-unknown-linux-gnu",
+ },
+ {
+ out: "dartanalyzer version 2.5.0-edge.2b3336b51eda58fe049c8a8d81b7576aaa98c218\n",
+ version: "2.5.0-edge.2b3336b51eda58fe049c8a8d81b7576aaa98c218",
+ target: "x86_64-unknown-linux-gnu",
+ },
+ } {
+ version, target, err := DartAnalyzerVersionTarget([]byte(tc.out))
+ if err != nil {
+ t.Errorf("expect no error from test case %v+, got an error: %v", tc, err)
+ }
+ if version != tc.version {
+ t.Errorf("expect version %q, got %q", tc.version, version)
+ }
+ if target != tc.target {
+ t.Errorf("expect target %q, got %q", tc.target, target)
+ }
+ }
+
+ // failure case
+ for _, tc := range []string{
+ "Dart VM version: 2.5.0-edge.2b3336b51eda58fe049c8a8d81b7576aaa98c218 (Wed Jul 17 09:11:15 2019 +0000) on \"linux_x64\"",
+ } {
+ _, _, err := DartAnalyzerVersionTarget([]byte(tc))
+ if err == nil {
+ t.Errorf("expect parsing error in %q, but got nil", tc)
+ }
+ }
+}
+
func TestResolveSymlinks(t *testing.T) {
d := &Descriptor{
fname: "dummy",
diff --git a/exec/inventory.go b/exec/inventory.go
index d34d8da..48e5cb8 100644
--- a/exec/inventory.go
+++ b/exec/inventory.go
@@ -53,6 +53,13 @@
}
)
+const (
+ maxKeyLength = 255
+ // Printable ASCII characters range from 0x20 to 0x7e
+ validKeyValueMin = 32
+ validKeyValueMax = 126
+)
+
type resultValue string
const (
@@ -72,6 +79,21 @@
)
func recordToolchainSelect(ctx context.Context, s selector, result resultValue) error {
+ // tag string cannot be over 255 or containing non-printable ascii characters.
+ // https://github.com/census-instrumentation/opencensus-go/blob/264a2a48d94c062252389fffbc308ba555e35166/tag/validate.go
+ tagNormalizer := func(tag string) string {
+ if len(tag) > maxKeyLength {
+ tag = tag[:maxKeyLength]
+ }
+ buf := []rune(tag)
+ for i, v := range buf {
+ if validKeyValueMin > v || v > validKeyValueMax {
+ buf[i] = '_'
+ }
+ }
+ return string(buf)
+ }
+
// selector string can be too long, more than tag value limit
// (255 ASCII characters).
// http://b/115441117
@@ -80,13 +102,10 @@
fmt.Fprintf(&buf, " t:%s", s.Target)
fmt.Fprintf(&buf, " b:%s", s.BinaryHash)
fmt.Fprintf(&buf, " v:%s", s.Version)
- sval := buf.String()
- if len(sval) > 255 {
- sval = sval[:255]
- }
+
ctx, err := tag.New(ctx,
- tag.Upsert(selectorKey, sval),
- tag.Upsert(resultKey, string(result)))
+ tag.Upsert(selectorKey, tagNormalizer(buf.String())),
+ tag.Upsert(resultKey, tagNormalizer(string(result))))
if err != nil {
return err
}
@@ -263,7 +282,7 @@
record := func(ctx context.Context, s selector, result resultValue) {
err := recordToolchainSelect(ctx, s, result)
if err != nil {
- logger.Fatalf("failed to record stats: %s=%s", s, result)
+ logger.Errorf("failed to record stats: %s=%s, err: %v", s, result, err)
}
}
diff --git a/go.mod b/go.mod
index da967e7..3490d9b 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@
go 1.12
require (
- cloud.google.com/go v0.43.0
+ cloud.google.com/go v0.44.0
contrib.go.opencensus.io/exporter/stackdriver v0.12.2
github.com/bazelbuild/remote-apis v0.0.0-20190606163526-a5c577357528
github.com/fsnotify/fsnotify v1.4.7
@@ -31,8 +31,8 @@
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190423024810-112230192c58
- google.golang.org/api v0.7.0
- google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610
- google.golang.org/grpc v1.22.0
+ google.golang.org/api v0.9.0
+ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64
+ google.golang.org/grpc v1.23.0
honnef.co/go/tools v0.0.0-20190614002413-cb51c254f01b // indirect
)
diff --git a/go.sum b/go.sum
index 6c2ca7f..8ce04e8 100644
--- a/go.sum
+++ b/go.sum
@@ -12,6 +12,8 @@
cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg=
cloud.google.com/go v0.43.0 h1:banaiRPAM8kUVYneOSkhgcDsLzEvL25FinuiSZaH/2w=
cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg=
+cloud.google.com/go v0.44.0 h1:0BWXxb/yzTc5MjzcLfBceY2xuwawl5cIbCC7qsLuktA=
+cloud.google.com/go v0.44.0/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
contrib.go.opencensus.io/exporter/stackdriver v0.12.1 h1:Dll2uFfOVI3fa8UzsHyP6z0M6fEc9ZTAMo+Y3z282Xg=
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
contrib.go.opencensus.io/exporter/stackdriver v0.12.2 h1:jU1p9F07ASK11wYgSTPKtFlTvTtCDj6R1d3nRt0ZHDE=
@@ -287,6 +289,9 @@
google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -320,6 +325,8 @@
google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -333,6 +340,10 @@
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
diff --git a/remoteexec/client.go b/remoteexec/client.go
index 3e3f991..14f7ffc 100644
--- a/remoteexec/client.go
+++ b/remoteexec/client.go
@@ -182,8 +182,9 @@
type responseStream interface {
Recv() (*lpb.Operation, error)
}
+ pctx := ctx
err := rpc.Retry{}.Do(ctx, func() error {
- ctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
+ ctx, cancel := context.WithTimeout(pctx, 1*time.Minute)
defer cancel()
var stream responseStream
var err error
@@ -226,7 +227,7 @@
logger.Errorf("%s", err)
return err
}
- return erespErr(ctx, resp)
+ return erespErr(pctx, resp)
}
})
recordFinish()
@@ -264,6 +265,19 @@
// codes.Unavailable, so that rpc.Retry will retry.
st.Code = int32(codes.Unavailable)
return status.FromProto(st).Err()
+
+ case codes.Aborted:
+ if ctx.Err() == nil {
+ // ctx is not cancelled, but returned
+ // code = Aborted, context canceled
+ // in this case, it would be retriable.
+ logger.Warnf("execute reponse: aborted %s, but ctx is still active", st)
+ st = proto.Clone(st).(*spb.Status)
+ // codes.Unavailable, so that rpc.Retry will retry.
+ st.Code = int32(codes.Unavailable)
+ return status.FromProto(st).Err()
+ }
+ fallthrough
default:
logger.Errorf("execute response: error %s", st)
}
diff --git a/server/process_collector.go b/server/process_collector.go
index 6d2d6ef..384645f 100644
--- a/server/process_collector.go
+++ b/server/process_collector.go
@@ -13,7 +13,7 @@
"io"
"io/ioutil"
"os"
- "runtime"
+ "runtime/debug"
"strconv"
"sync/atomic"
"time"
@@ -53,7 +53,7 @@
Aggregation: view.LastValue(),
},
{
- Name: "go.chromium.org/goma/server/server/process-virtual-memroy",
+ Name: "go.chromium.org/goma/server/server/process-virtual-memory",
Description: "Virtual memory size",
Measure: virtualMemorySize,
Aggregation: view.LastValue(),
@@ -85,7 +85,7 @@
logger.Infof("GC start: rss=%d", rss)
select {
case gcSema <- true:
- runtime.GC()
+ debug.FreeOSMemory()
<-gcSema
default:
logger.Infof("GC already running")
diff --git a/server/process_collector_test.go b/server/process_collector_test.go
index e94f1d1..0ef11a9 100644
--- a/server/process_collector_test.go
+++ b/server/process_collector_test.go
@@ -79,7 +79,7 @@
t.Errorf("parseStatMemory(ctx, procSelfStat)=_, _, %v", err)
}
if got, want := vsize, int64(8044544); got != want {
- t.Errorf("parseStatMemroy(ctx, procSelfStat).vss=%d; want=%d", got, want)
+ t.Errorf("parseStatMemory(ctx, procSelfStat).vss=%d; want=%d", got, want)
}
if got, want := rss, int64(169*os.Getpagesize()); got != want {
t.Errorf("parseStatMemory(ctx, procSelfStat).rss=%d; want=%d", got, want)