blob: 779a88f2dde8c04ae310d7bff60a94e022c3cda6 [file] [log] [blame]
Robin Thellend7a442432014-08-22 09:05:08 -07001// Package impl implements the Stats interface from
2// veyron2/services/mgmt/stats.
3package impl
4
5import (
Todd Wangb31da592015-02-20 12:50:39 -08006 "reflect"
Robin Thellend7a442432014-08-22 09:05:08 -07007 "time"
8
Jiri Simsaffceefa2015-02-28 11:03:34 -08009 libstats "v.io/x/ref/lib/stats"
Robin Thellend7a442432014-08-22 09:05:08 -070010
Jiri Simsa6ac95222015-02-23 16:11:49 -080011 "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 Simsa337af232015-02-27 14:36:46 -080018 "v.io/x/lib/vlog"
Robin Thellend7a442432014-08-22 09:05:08 -070019)
20
Robin Thellend8a0f04f2014-11-17 10:40:24 -080021type statsService struct {
Robin Thellend7a442432014-08-22 09:05:08 -070022 suffix string
23 watchFreq time.Duration
24}
25
Jiri Simsaffceefa2015-02-28 11:03:34 -080026const pkgPath = "v.io/x/ref/services/mgmt/stats/impl"
Mike Burrowsd65df962014-12-17 10:01:19 -080027
Robin Thellend7a442432014-08-22 09:05:08 -070028var (
Mike Burrowsd65df962014-12-17 10:01:19 -080029 errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
Robin Thellend7a442432014-08-22 09:05:08 -070030)
31
Robin Thellend8a0f04f2014-11-17 10:40:24 -080032// NewStatsService returns a stats server implementation. The value of watchFreq
Robin Thellende34761d2014-11-13 13:11:25 -080033// is used to specify the time between WatchGlob updates.
Robin Thellend8a0f04f2014-11-17 10:40:24 -080034func NewStatsService(suffix string, watchFreq time.Duration) interface{} {
Robin Thellendbde278d2014-11-19 15:07:32 -080035 return stats.StatsServer(&statsService{suffix, watchFreq})
Robin Thellend7a442432014-08-22 09:05:08 -070036}
37
Robin Thellend39ac3232014-12-02 09:50:41 -080038// Glob__ returns the name of all objects that match pattern.
Todd Wang2331dd02015-03-17 15:38:39 -070039func (i *statsService) Glob__(call ipc.ServerCall, pattern string) (<-chan naming.GlobReply, error) {
Robin Thellend39ac3232014-12-02 09:50:41 -080040 vlog.VI(1).Infof("%v.Glob__(%q)", i.suffix, pattern)
Robin Thellend7a442432014-08-22 09:05:08 -070041
Todd Wang2331dd02015-03-17 15:38:39 -070042 ch := make(chan naming.GlobReply)
Robin Thellend39ac3232014-12-02 09:50:41 -080043 go func() {
44 defer close(ch)
45 it := libstats.Glob(i.suffix, pattern, time.Time{}, false)
46 for it.Advance() {
Todd Wang2331dd02015-03-17 15:38:39 -070047 ch <- naming.GlobReplyEntry{naming.MountEntry{Name: it.Value().Key}}
Robin Thellend7a442432014-08-22 09:05:08 -070048 }
Robin Thellend39ac3232014-12-02 09:50:41 -080049 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 Thellend7a442432014-08-22 09:05:08 -070054}
55
56// WatchGlob returns the name and value of the objects that match the request,
57// followed by periodic updates when values change.
Suharsh Sivakumar31f49852015-03-03 16:13:20 -080058func (i *statsService) WatchGlob(call watch.GlobWatcherWatchGlobServerCall, req watchtypes.GlobRequest) error {
Robin Thellend7a442432014-08-22 09:05:08 -070059 vlog.VI(1).Infof("%v.WatchGlob(%+v)", i.suffix, req)
60
61 var t time.Time
62Loop:
63 for {
64 prevTime := t
65 t = time.Now()
Robin Thellendbde278d2014-11-19 15:07:32 -080066 it := libstats.Glob(i.suffix, req.Pattern, prevTime, true)
Robin Thellend7a442432014-08-22 09:05:08 -070067 changes := []watchtypes.Change{}
68 for it.Advance() {
69 v := it.Value()
70 c := watchtypes.Change{
71 Name: v.Key,
72 State: watchtypes.Exists,
Todd Wangb31da592015-02-20 12:50:39 -080073 Value: vdl.ValueOf(v.Value),
Robin Thellend7a442432014-08-22 09:05:08 -070074 }
75 changes = append(changes, c)
76 }
77 if err := it.Err(); err != nil {
Robin Thellendbde278d2014-11-19 15:07:32 -080078 if err == libstats.ErrNotFound {
Suharsh Sivakumar31f49852015-03-03 16:13:20 -080079 return verror.New(verror.ErrNoExist, call.Context(), i.suffix)
Robin Thellend7a442432014-08-22 09:05:08 -070080 }
Suharsh Sivakumar31f49852015-03-03 16:13:20 -080081 return verror.New(errOperationFailed, call.Context(), i.suffix)
Robin Thellend7a442432014-08-22 09:05:08 -070082 }
Tilak Sharma8ef60262014-08-26 14:54:37 -070083 for _, change := range changes {
Suharsh Sivakumar31f49852015-03-03 16:13:20 -080084 if err := call.SendStream().Send(change); err != nil {
Tilak Sharma8ef60262014-08-26 14:54:37 -070085 return err
86 }
Robin Thellend7a442432014-08-22 09:05:08 -070087 }
88 select {
Suharsh Sivakumar31f49852015-03-03 16:13:20 -080089 case <-call.Context().Done():
Robin Thellend7a442432014-08-22 09:05:08 -070090 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 Rosencrantz9dce9b22015-03-02 10:48:37 -080098func (i *statsService) Value(call ipc.ServerCall) (*vdl.Value, error) {
Robin Thellend7a442432014-08-22 09:05:08 -070099 vlog.VI(1).Infof("%v.Value()", i.suffix)
100
Todd Wangb31da592015-02-20 12:50:39 -0800101 rv, err := libstats.Value(i.suffix)
102 switch {
103 case err == libstats.ErrNotFound:
Matt Rosencrantz9dce9b22015-03-02 10:48:37 -0800104 return nil, verror.New(verror.ErrNoExist, call.Context(), i.suffix)
Todd Wangb31da592015-02-20 12:50:39 -0800105 case err == libstats.ErrNoValue:
Matt Rosencrantz9dce9b22015-03-02 10:48:37 -0800106 return nil, stats.NewErrNoValue(call.Context(), i.suffix)
Todd Wangb31da592015-02-20 12:50:39 -0800107 case err != nil:
Matt Rosencrantz9dce9b22015-03-02 10:48:37 -0800108 return nil, verror.New(errOperationFailed, call.Context(), i.suffix)
Robin Thellend7a442432014-08-22 09:05:08 -0700109 }
Todd Wangb31da592015-02-20 12:50:39 -0800110 vv, err := vdl.ValueFromReflect(reflect.ValueOf(rv))
111 if err != nil {
Matt Rosencrantz9dce9b22015-03-02 10:48:37 -0800112 return nil, verror.New(verror.ErrInternal, call.Context(), i.suffix, err)
Todd Wangb31da592015-02-20 12:50:39 -0800113 }
114 return vv, nil
Robin Thellend7a442432014-08-22 09:05:08 -0700115}