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/exemplar"
26 "go.opencensus.io/stats"
27 "go.opencensus.io/stats/internal"
28 "go.opencensus.io/tag"
31 type command interface {
32 handleCommand(w *worker)
35 // getViewByNameReq is the command to get a view given its name.
36 type getViewByNameReq struct {
38 c chan *getViewByNameResp
41 type getViewByNameResp struct {
45 func (cmd *getViewByNameReq) handleCommand(w *worker) {
46 v := w.views[cmd.name]
48 cmd.c <- &getViewByNameResp{nil}
51 cmd.c <- &getViewByNameResp{v.view}
54 // registerViewReq is the command to register a view.
55 type registerViewReq struct {
60 func (cmd *registerViewReq) handleCommand(w *worker) {
62 for _, view := range cmd.views {
63 vi, err := w.tryRegisterView(view)
65 errstr = append(errstr, fmt.Sprintf("%s: %v", view.Name, err))
68 internal.SubscriptionReporter(view.Measure.Name())
72 cmd.err <- errors.New(strings.Join(errstr, "\n"))
78 // unregisterFromViewReq is the command to unregister to a view. Has no
79 // impact on the data collection for client that are pulling data from the
81 type unregisterFromViewReq struct {
86 func (cmd *unregisterFromViewReq) handleCommand(w *worker) {
87 for _, name := range cmd.views {
88 vi, ok := w.views[name]
93 // Report pending data for this view before removing it.
94 w.reportView(vi, time.Now())
97 if !vi.isSubscribed() {
98 // this was the last subscription and view is not collecting anymore.
99 // The collected data can be cleared.
102 delete(w.views, name)
104 cmd.done <- struct{}{}
107 // retrieveDataReq is the command to retrieve data for a view.
108 type retrieveDataReq struct {
111 c chan *retrieveDataResp
114 type retrieveDataResp struct {
119 func (cmd *retrieveDataReq) handleCommand(w *worker) {
120 vi, ok := w.views[cmd.v]
122 cmd.c <- &retrieveDataResp{
124 fmt.Errorf("cannot retrieve data; view %q is not registered", cmd.v),
129 if !vi.isSubscribed() {
130 cmd.c <- &retrieveDataResp{
132 fmt.Errorf("cannot retrieve data; view %q has no subscriptions or collection is not forcibly started", cmd.v),
136 cmd.c <- &retrieveDataResp{
142 // recordReq is the command to record data related to multiple measures
144 type recordReq struct {
146 ms []stats.Measurement
147 attachments map[string]string
151 func (cmd *recordReq) handleCommand(w *worker) {
152 for _, m := range cmd.ms {
153 if (m == stats.Measurement{}) { // not registered
156 ref := w.getMeasureRef(m.Measure().Name())
157 for v := range ref.views {
158 e := &exemplar.Exemplar{
161 Attachments: cmd.attachments,
163 v.addSample(cmd.tm, e)
168 // setReportingPeriodReq is the command to modify the duration between
169 // reporting the collected data to the registered clients.
170 type setReportingPeriodReq struct {
175 func (cmd *setReportingPeriodReq) handleCommand(w *worker) {
178 w.timer = time.NewTicker(defaultReportingDuration)
180 w.timer = time.NewTicker(cmd.d)