Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 1 | // Package impl implements the Stats interface from |
| 2 | // veyron2/services/mgmt/stats. |
| 3 | package impl |
| 4 | |
| 5 | import ( |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 6 | "reflect" |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 7 | "time" |
| 8 | |
Jiri Simsa | ffceefa | 2015-02-28 11:03:34 -0800 | [diff] [blame] | 9 | libstats "v.io/x/ref/lib/stats" |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 10 | |
Jiri Simsa | 6ac9522 | 2015-02-23 16:11:49 -0800 | [diff] [blame] | 11 | "v.io/v23/ipc" |
| 12 | "v.io/v23/naming" |
| 13 | "v.io/v23/services/mgmt/stats" |
| 14 | "v.io/v23/services/watch" |
| 15 | watchtypes "v.io/v23/services/watch/types" |
| 16 | "v.io/v23/vdl" |
| 17 | "v.io/v23/verror" |
Jiri Simsa | 337af23 | 2015-02-27 14:36:46 -0800 | [diff] [blame] | 18 | "v.io/x/lib/vlog" |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 19 | ) |
| 20 | |
Robin Thellend | 8a0f04f | 2014-11-17 10:40:24 -0800 | [diff] [blame] | 21 | type statsService struct { |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 22 | suffix string |
| 23 | watchFreq time.Duration |
| 24 | } |
| 25 | |
Jiri Simsa | ffceefa | 2015-02-28 11:03:34 -0800 | [diff] [blame] | 26 | const pkgPath = "v.io/x/ref/services/mgmt/stats/impl" |
Mike Burrows | d65df96 | 2014-12-17 10:01:19 -0800 | [diff] [blame] | 27 | |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 28 | var ( |
Mike Burrows | d65df96 | 2014-12-17 10:01:19 -0800 | [diff] [blame] | 29 | errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}") |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 30 | ) |
| 31 | |
Robin Thellend | 8a0f04f | 2014-11-17 10:40:24 -0800 | [diff] [blame] | 32 | // NewStatsService returns a stats server implementation. The value of watchFreq |
Robin Thellend | e34761d | 2014-11-13 13:11:25 -0800 | [diff] [blame] | 33 | // is used to specify the time between WatchGlob updates. |
Robin Thellend | 8a0f04f | 2014-11-17 10:40:24 -0800 | [diff] [blame] | 34 | func NewStatsService(suffix string, watchFreq time.Duration) interface{} { |
Robin Thellend | bde278d | 2014-11-19 15:07:32 -0800 | [diff] [blame] | 35 | return stats.StatsServer(&statsService{suffix, watchFreq}) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 36 | } |
| 37 | |
Robin Thellend | 39ac323 | 2014-12-02 09:50:41 -0800 | [diff] [blame] | 38 | // Glob__ returns the name of all objects that match pattern. |
Todd Wang | 2331dd0 | 2015-03-17 15:38:39 -0700 | [diff] [blame^] | 39 | func (i *statsService) Glob__(call ipc.ServerCall, pattern string) (<-chan naming.GlobReply, error) { |
Robin Thellend | 39ac323 | 2014-12-02 09:50:41 -0800 | [diff] [blame] | 40 | vlog.VI(1).Infof("%v.Glob__(%q)", i.suffix, pattern) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 41 | |
Todd Wang | 2331dd0 | 2015-03-17 15:38:39 -0700 | [diff] [blame^] | 42 | ch := make(chan naming.GlobReply) |
Robin Thellend | 39ac323 | 2014-12-02 09:50:41 -0800 | [diff] [blame] | 43 | go func() { |
| 44 | defer close(ch) |
| 45 | it := libstats.Glob(i.suffix, pattern, time.Time{}, false) |
| 46 | for it.Advance() { |
Todd Wang | 2331dd0 | 2015-03-17 15:38:39 -0700 | [diff] [blame^] | 47 | ch <- naming.GlobReplyEntry{naming.MountEntry{Name: it.Value().Key}} |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 48 | } |
Robin Thellend | 39ac323 | 2014-12-02 09:50:41 -0800 | [diff] [blame] | 49 | if err := it.Err(); err != nil { |
| 50 | vlog.VI(1).Infof("libstats.Glob(%q, %q) failed: %v", i.suffix, pattern, err) |
| 51 | } |
| 52 | }() |
| 53 | return ch, nil |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | // WatchGlob returns the name and value of the objects that match the request, |
| 57 | // followed by periodic updates when values change. |
Suharsh Sivakumar | 31f4985 | 2015-03-03 16:13:20 -0800 | [diff] [blame] | 58 | func (i *statsService) WatchGlob(call watch.GlobWatcherWatchGlobServerCall, req watchtypes.GlobRequest) error { |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 59 | vlog.VI(1).Infof("%v.WatchGlob(%+v)", i.suffix, req) |
| 60 | |
| 61 | var t time.Time |
| 62 | Loop: |
| 63 | for { |
| 64 | prevTime := t |
| 65 | t = time.Now() |
Robin Thellend | bde278d | 2014-11-19 15:07:32 -0800 | [diff] [blame] | 66 | it := libstats.Glob(i.suffix, req.Pattern, prevTime, true) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 67 | changes := []watchtypes.Change{} |
| 68 | for it.Advance() { |
| 69 | v := it.Value() |
| 70 | c := watchtypes.Change{ |
| 71 | Name: v.Key, |
| 72 | State: watchtypes.Exists, |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 73 | Value: vdl.ValueOf(v.Value), |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 74 | } |
| 75 | changes = append(changes, c) |
| 76 | } |
| 77 | if err := it.Err(); err != nil { |
Robin Thellend | bde278d | 2014-11-19 15:07:32 -0800 | [diff] [blame] | 78 | if err == libstats.ErrNotFound { |
Suharsh Sivakumar | 31f4985 | 2015-03-03 16:13:20 -0800 | [diff] [blame] | 79 | return verror.New(verror.ErrNoExist, call.Context(), i.suffix) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 80 | } |
Suharsh Sivakumar | 31f4985 | 2015-03-03 16:13:20 -0800 | [diff] [blame] | 81 | return verror.New(errOperationFailed, call.Context(), i.suffix) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 82 | } |
Tilak Sharma | 8ef6026 | 2014-08-26 14:54:37 -0700 | [diff] [blame] | 83 | for _, change := range changes { |
Suharsh Sivakumar | 31f4985 | 2015-03-03 16:13:20 -0800 | [diff] [blame] | 84 | if err := call.SendStream().Send(change); err != nil { |
Tilak Sharma | 8ef6026 | 2014-08-26 14:54:37 -0700 | [diff] [blame] | 85 | return err |
| 86 | } |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 87 | } |
| 88 | select { |
Suharsh Sivakumar | 31f4985 | 2015-03-03 16:13:20 -0800 | [diff] [blame] | 89 | case <-call.Context().Done(): |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 90 | break Loop |
| 91 | case <-time.After(i.watchFreq): |
| 92 | } |
| 93 | } |
| 94 | return nil |
| 95 | } |
| 96 | |
| 97 | // Value returns the value of the receiver object. |
Matt Rosencrantz | 9dce9b2 | 2015-03-02 10:48:37 -0800 | [diff] [blame] | 98 | func (i *statsService) Value(call ipc.ServerCall) (*vdl.Value, error) { |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 99 | vlog.VI(1).Infof("%v.Value()", i.suffix) |
| 100 | |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 101 | rv, err := libstats.Value(i.suffix) |
| 102 | switch { |
| 103 | case err == libstats.ErrNotFound: |
Matt Rosencrantz | 9dce9b2 | 2015-03-02 10:48:37 -0800 | [diff] [blame] | 104 | return nil, verror.New(verror.ErrNoExist, call.Context(), i.suffix) |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 105 | case err == libstats.ErrNoValue: |
Matt Rosencrantz | 9dce9b2 | 2015-03-02 10:48:37 -0800 | [diff] [blame] | 106 | return nil, stats.NewErrNoValue(call.Context(), i.suffix) |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 107 | case err != nil: |
Matt Rosencrantz | 9dce9b2 | 2015-03-02 10:48:37 -0800 | [diff] [blame] | 108 | return nil, verror.New(errOperationFailed, call.Context(), i.suffix) |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 109 | } |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 110 | vv, err := vdl.ValueFromReflect(reflect.ValueOf(rv)) |
| 111 | if err != nil { |
Matt Rosencrantz | 9dce9b2 | 2015-03-02 10:48:37 -0800 | [diff] [blame] | 112 | return nil, verror.New(verror.ErrInternal, call.Context(), i.suffix, err) |
Todd Wang | b31da59 | 2015-02-20 12:50:39 -0800 | [diff] [blame] | 113 | } |
| 114 | return vv, nil |
Robin Thellend | 7a44243 | 2014-08-22 09:05:08 -0700 | [diff] [blame] | 115 | } |