| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package bigtable | 5 package bigtable |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "time" | 9 "time" |
| 10 | 10 |
| 11 "github.com/luci/luci-go/common/errors" | |
| 12 "github.com/luci/luci-go/common/grpcutil" | 11 "github.com/luci/luci-go/common/grpcutil" |
| 13 "github.com/luci/luci-go/server/logdog/storage" | 12 "github.com/luci/luci-go/server/logdog/storage" |
| 14 "golang.org/x/net/context" | 13 "golang.org/x/net/context" |
| 15 "google.golang.org/cloud/bigtable" | 14 "google.golang.org/cloud/bigtable" |
| 16 ) | 15 ) |
| 17 | 16 |
| 18 const ( | 17 const ( |
| 19 logColumnFamily = "log" | 18 logColumnFamily = "log" |
| 20 | 19 |
| 21 // The data column stores raw low row data (RecordIO blob). | 20 // The data column stores raw low row data (RecordIO blob). |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 *btStorage | 68 *btStorage |
| 70 } | 69 } |
| 71 | 70 |
| 72 func (t *btTableProd) putLogData(c context.Context, rk *rowKey, data []byte) err
or { | 71 func (t *btTableProd) putLogData(c context.Context, rk *rowKey, data []byte) err
or { |
| 73 m := bigtable.NewMutation() | 72 m := bigtable.NewMutation() |
| 74 m.Set(logColumnFamily, logColumn, bigtable.ServerTime, data) | 73 m.Set(logColumnFamily, logColumn, bigtable.ServerTime, data) |
| 75 cm := bigtable.NewCondMutation(bigtable.RowKeyFilter(rk.encode()), nil,
m) | 74 cm := bigtable.NewCondMutation(bigtable.RowKeyFilter(rk.encode()), nil,
m) |
| 76 | 75 |
| 77 rowExists := false | 76 rowExists := false |
| 78 if err := t.logTable.Apply(c, rk.encode(), cm, bigtable.GetCondMutationR
esult(&rowExists)); err != nil { | 77 if err := t.logTable.Apply(c, rk.encode(), cm, bigtable.GetCondMutationR
esult(&rowExists)); err != nil { |
| 79 » » return wrapTransient(err) | 78 » » return grpcutil.WrapIfTransient(err) |
| 80 } | 79 } |
| 81 if rowExists { | 80 if rowExists { |
| 82 return storage.ErrExists | 81 return storage.ErrExists |
| 83 } | 82 } |
| 84 return nil | 83 return nil |
| 85 } | 84 } |
| 86 | 85 |
| 87 func (t *btTableProd) getLogData(c context.Context, rk *rowKey, limit int, keysO
nly bool, cb btGetCallback) error { | 86 func (t *btTableProd) getLogData(c context.Context, rk *rowKey, limit int, keysO
nly bool, cb btGetCallback) error { |
| 88 // Construct read options based on Get request. | 87 // Construct read options based on Get request. |
| 89 ropts := []bigtable.ReadOption{ | 88 ropts := []bigtable.ReadOption{ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 115 innerErr = err | 114 innerErr = err |
| 116 return false | 115 return false |
| 117 } | 116 } |
| 118 | 117 |
| 119 if err := cb(drk, data); err != nil { | 118 if err := cb(drk, data); err != nil { |
| 120 innerErr = err | 119 innerErr = err |
| 121 return false | 120 return false |
| 122 } | 121 } |
| 123 return true | 122 return true |
| 124 }, ropts...) | 123 }, ropts...) |
| 125 » if err == nil { | 124 » if err != nil { |
| 126 » » err = innerErr | 125 » » return grpcutil.WrapIfTransient(err) |
| 127 } | 126 } |
| 128 » return wrapTransient(err) | 127 » if innerErr != nil { |
| 128 » » return innerErr |
| 129 » } |
| 130 » return nil |
| 129 } | 131 } |
| 130 | 132 |
| 131 func (t *btTableProd) setMaxLogAge(c context.Context, d time.Duration) error { | 133 func (t *btTableProd) setMaxLogAge(c context.Context, d time.Duration) error { |
| 132 var logGCPolicy bigtable.GCPolicy | 134 var logGCPolicy bigtable.GCPolicy |
| 133 if d > 0 { | 135 if d > 0 { |
| 134 logGCPolicy = bigtable.MaxAgePolicy(d) | 136 logGCPolicy = bigtable.MaxAgePolicy(d) |
| 135 } | 137 } |
| 136 if err := t.adminClient.SetGCPolicy(c, t.LogTable, logColumnFamily, logG
CPolicy); err != nil { | 138 if err := t.adminClient.SetGCPolicy(c, t.LogTable, logColumnFamily, logG
CPolicy); err != nil { |
| 137 » » return wrapTransient(err) | 139 » » return grpcutil.WrapIfTransient(err) |
| 138 } | 140 } |
| 139 return nil | 141 return nil |
| 140 } | 142 } |
| 141 | 143 |
| 142 // wrapTransient wraps the supplied error in an errors.TransientError if it is | |
| 143 // transient. | |
| 144 func wrapTransient(err error) error { | |
| 145 if isTransient(err) { | |
| 146 err = errors.WrapTransient(err) | |
| 147 } | |
| 148 return err | |
| 149 } | |
| 150 | |
| 151 // isTransient tests if a BigTable SDK error is transient. | |
| 152 // | |
| 153 // Since the BigTable API doesn't give us this information, we will identify | |
| 154 // transient errors by parsing their error string :( | |
| 155 func isTransient(err error) bool { | |
| 156 return (err != errStop) && grpcutil.IsTransient(err) | |
| 157 } | |
| 158 | |
| 159 // getLogRowData loads the []byte contents of the supplied log row. | 144 // getLogRowData loads the []byte contents of the supplied log row. |
| 160 // | 145 // |
| 161 // If the row doesn't exist, storage.ErrDoesNotExist will be returned. | 146 // If the row doesn't exist, storage.ErrDoesNotExist will be returned. |
| 162 func getLogRowData(row bigtable.Row) (data []byte, err error) { | 147 func getLogRowData(row bigtable.Row) (data []byte, err error) { |
| 163 items, ok := row[logColumnFamily] | 148 items, ok := row[logColumnFamily] |
| 164 if !ok { | 149 if !ok { |
| 165 err = storage.ErrDoesNotExist | 150 err = storage.ErrDoesNotExist |
| 166 return | 151 return |
| 167 } | 152 } |
| 168 | 153 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 189 | 174 |
| 190 // Get the specific ReadItem for our column | 175 // Get the specific ReadItem for our column |
| 191 colName := fmt.Sprintf("%s:%s", family, column) | 176 colName := fmt.Sprintf("%s:%s", family, column) |
| 192 for _, item := range items { | 177 for _, item := range items { |
| 193 if item.Column == colName { | 178 if item.Column == colName { |
| 194 return &item | 179 return &item |
| 195 } | 180 } |
| 196 } | 181 } |
| 197 return nil | 182 return nil |
| 198 } | 183 } |
| OLD | NEW |