Exemple #1
0
func sendLoop(stream pb.Watch_WatchServer, watcher storage.Watcher, closec chan struct{}) {
	for {
		select {
		case e, ok := <-watcher.Chan():
			if !ok {
				return
			}
			err := stream.Send(&pb.WatchResponse{Event: &e})
			storage.ReportEventReceived()
			if err != nil {
				return
			}
		case <-closec:
			// drain the chan to clean up pending events
			for {
				_, ok := <-watcher.Chan()
				if !ok {
					return
				}
				storage.ReportEventReceived()
			}
			return
		}
	}
}
Exemple #2
0
func (sws *serverWatchStream) sendLoop() {
	for {
		select {
		case wresp, ok := <-sws.watchStream.Chan():
			if !ok {
				return
			}

			// TODO: evs is []storagepb.Event type
			// either return []*storagepb.Event from storage package
			// or define protocol buffer with []storagepb.Event.
			evs := wresp.Events
			events := make([]*storagepb.Event, len(evs))
			for i := range evs {
				events[i] = &evs[i]
			}

			err := sws.gRPCStream.Send(&pb.WatchResponse{
				Header:          sws.newResponseHeader(wresp.Revision),
				WatchId:         int64(wresp.WatchID),
				Events:          events,
				CompactRevision: wresp.CompactRevision,
			})
			storage.ReportEventReceived()
			if err != nil {
				return
			}

		case c, ok := <-sws.ctrlStream:
			if !ok {
				return
			}

			if err := sws.gRPCStream.Send(c); err != nil {
				return
			}

		case <-sws.closec:
			// drain the chan to clean up pending events
			for {
				_, ok := <-sws.watchStream.Chan()
				if !ok {
					return
				}
				storage.ReportEventReceived()
			}
		}
	}
}
Exemple #3
0
func (sws *serverWatchStream) sendLoop() {
	// watch ids that are currently active
	ids := make(map[storage.WatchID]struct{})
	// watch responses pending on a watch id creation message
	pending := make(map[storage.WatchID][]*pb.WatchResponse)

	progressTicker := time.NewTicker(ProgressReportInterval)
	defer progressTicker.Stop()

	for {
		select {
		case wresp, ok := <-sws.watchStream.Chan():
			if !ok {
				return
			}

			// TODO: evs is []storagepb.Event type
			// either return []*storagepb.Event from storage package
			// or define protocol buffer with []storagepb.Event.
			evs := wresp.Events
			events := make([]*storagepb.Event, len(evs))
			for i := range evs {
				events[i] = &evs[i]
			}

			wr := &pb.WatchResponse{
				Header:          sws.newResponseHeader(wresp.Revision),
				WatchId:         int64(wresp.WatchID),
				Events:          events,
				CompactRevision: wresp.CompactRevision,
			}

			if _, hasId := ids[wresp.WatchID]; !hasId {
				// buffer if id not yet announced
				wrs := append(pending[wresp.WatchID], wr)
				pending[wresp.WatchID] = wrs
				continue
			}

			storage.ReportEventReceived()
			if err := sws.gRPCStream.Send(wr); err != nil {
				return
			}

			if _, ok := sws.progress[wresp.WatchID]; ok {
				sws.progress[wresp.WatchID] = false
			}

		case c, ok := <-sws.ctrlStream:
			if !ok {
				return
			}

			if err := sws.gRPCStream.Send(c); err != nil {
				return
			}

			// track id creation
			wid := storage.WatchID(c.WatchId)
			if c.Canceled {
				delete(ids, wid)
				continue
			}
			if c.Created {
				// flush buffered events
				ids[wid] = struct{}{}
				for _, v := range pending[wid] {
					storage.ReportEventReceived()
					if err := sws.gRPCStream.Send(v); err != nil {
						return
					}
				}
				delete(pending, wid)
			}
		case <-progressTicker.C:
			for id, ok := range sws.progress {
				if ok {
					sws.watchStream.RequestProgress(id)
				}
				sws.progress[id] = true
			}
		case <-sws.closec:
			// drain the chan to clean up pending events
			for range sws.watchStream.Chan() {
				storage.ReportEventReceived()
			}
			for _, wrs := range pending {
				for range wrs {
					storage.ReportEventReceived()
				}
			}
		}
	}
}