1 // Copyright 2017, OpenCensus Authors
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
24 "go.opencensus.io/stats"
25 "go.opencensus.io/stats/internal"
26 "go.opencensus.io/tag"
29 type command interface {
30 handleCommand(w *worker)
33 // getViewByNameReq is the command to get a view given its name.
34 type getViewByNameReq struct {
36 c chan *getViewByNameResp
39 type getViewByNameResp struct {
43 func (cmd *getViewByNameReq) handleCommand(w *worker) {
44 v := w.views[cmd.name]
46 cmd.c <- &getViewByNameResp{nil}
49 cmd.c <- &getViewByNameResp{v.view}
52 // registerViewReq is the command to register a view.
53 type registerViewReq struct {
58 func (cmd *registerViewReq) handleCommand(w *worker) {
59 for _, v := range cmd.views {
60 if err := v.canonicalize(); err != nil {
66 for _, view := range cmd.views {
67 vi, err := w.tryRegisterView(view)
69 errstr = append(errstr, fmt.Sprintf("%s: %v", view.Name, err))
72 internal.SubscriptionReporter(view.Measure.Name())
76 cmd.err <- errors.New(strings.Join(errstr, "\n"))
82 // unregisterFromViewReq is the command to unregister to a view. Has no
83 // impact on the data collection for client that are pulling data from the
85 type unregisterFromViewReq struct {
90 func (cmd *unregisterFromViewReq) handleCommand(w *worker) {
91 for _, name := range cmd.views {
92 vi, ok := w.views[name]
97 // Report pending data for this view before removing it.
98 w.reportView(vi, time.Now())
101 if !vi.isSubscribed() {
102 // this was the last subscription and view is not collecting anymore.
103 // The collected data can be cleared.
106 w.unregisterView(name)
108 cmd.done <- struct{}{}
111 // retrieveDataReq is the command to retrieve data for a view.
112 type retrieveDataReq struct {
115 c chan *retrieveDataResp
118 type retrieveDataResp struct {
123 func (cmd *retrieveDataReq) handleCommand(w *worker) {
124 vi, ok := w.views[cmd.v]
126 cmd.c <- &retrieveDataResp{
128 fmt.Errorf("cannot retrieve data; view %q is not registered", cmd.v),
133 if !vi.isSubscribed() {
134 cmd.c <- &retrieveDataResp{
136 fmt.Errorf("cannot retrieve data; view %q has no subscriptions or collection is not forcibly started", cmd.v),
140 cmd.c <- &retrieveDataResp{
146 // recordReq is the command to record data related to multiple measures
148 type recordReq struct {
150 ms []stats.Measurement
151 attachments map[string]interface{}
155 func (cmd *recordReq) handleCommand(w *worker) {
156 for _, m := range cmd.ms {
157 if (m == stats.Measurement{}) { // not registered
160 ref := w.getMeasureRef(m.Measure().Name())
161 for v := range ref.views {
162 v.addSample(cmd.tm, m.Value(), cmd.attachments, time.Now())
167 // setReportingPeriodReq is the command to modify the duration between
168 // reporting the collected data to the registered clients.
169 type setReportingPeriodReq struct {
174 func (cmd *setReportingPeriodReq) handleCommand(w *worker) {
177 w.timer = time.NewTicker(defaultReportingDuration)
179 w.timer = time.NewTicker(cmd.d)