// resetNotifyTimer should only ever be called when notifyTimer has stopped
// and notifyTimer.C been read from. Otherwise, call resetNotifyTimerIfNeeded.
517553
func (a *aggregator) resetNotifyTimer(duration time.Duration) {
	l.Debugln(a, "Resetting notifyTimer to", duration.String())
	a.notifyTimerNeedsReset = false
	a.notifyTimer.Reset(duration)
}
533414
func (l *logger) resetTimer(d time.Duration) (expired bool) {
	expired = !l.timer.Reset(d)
	if expired {
		l.start = time.Now()
	}
	return expired
}
727404
func (s *CreateClusterInput) SetNotification(v *Notification) *CreateClusterInput {
	s.Notification = v
	return s
}
459692
func (t *PCPTimer) Reset() error {
	t.mutex.Lock()
	defer t.mutex.Unlock()

	if t.started {
		return errors.New("trying to reset an already started timer")
	}

	return t.set(float64(0))
}
484990
func (w *responseWriter) CloseNotify() <-chan bool {
	if w, ok := w.ResponseWriter.(http.CloseNotifier); ok {
		return w.CloseNotify()
	}
	return nil
}
213796
func (s *Subscription) notify(event interface{}) error {
	timeout := time.After(DefaultTimeout)
	select {
	case <-s.quitChan:
		Log.Debugf("Subscription %s already closed", s.id)
		return ErrClosed
	case s.events <- event:
		return nil
	case <-timeout:
		Log.Debugf("Timeout on subscription %s", s.id)
		return ErrTimeout
	}
}
1110205
func (c *ConsulAlertClient) SetReminder(m notifier.Message) {
	data, _ := json.Marshal(m)
	key := fmt.Sprintf("consul-alerts/reminders/%s/%s", m.Node, m.CheckId)
	c.api.KV().Put(&consulapi.KVPair{Key: key, Value: data}, nil)
	log.Println("Setting reminder for node: ", m.Node)
}
25683
func (state *ServicesState) NotifyListeners(svc *service.Service, previousStatus int, changedTime time.Time) {
	listeners := state.listeners

	if len(listeners) < 1 {
		log.Debugf("Skipping listeners, there are none")
		return
	}

	log.Debugf("Notifying listeners of change at %s", changedTime.String())

	event := ChangeEvent{Service: *svc, PreviousStatus: previousStatus, Time: changedTime}
	for _, listener := range listeners {
		if listener == nil {
			continue
		}

		select {
		case listener.Chan() <- event:
			continue
		default:
			log.Warnf("Can't notify listener (%s). May not be ready yet.", listener.Name())
		}
	}
}
248608
func (s *Stopwatch) Reset() {
	s.Lock()
	defer s.Unlock()

	if s.isRunning() {
		fmt.Printf("WARNING: Stopwatch.Reset() isRunning is true\n")
	}
	s.refTime = time.Time{}
	s.elapsedTime = 0
}
669043
func TimeRepr(t time.Time) (string, error) {
	notification := TimeNotification{
		Time: t.String(),
	}
	repr, err := json.Marshal(notification)
	return string(repr), err
}
997754
func (self *Context) SetTimer(id string, tol time.Duration, bell *Bell) bool {
	return self.spider.SetTimer(id, tol, bell)
}
562699
func (df *DirtyFile) NotifyErrListeners(err error) {
	df.lock.Lock()
	listeners := df.errListeners
	df.errListeners = nil
	df.lock.Unlock()
	if err == nil {
		return
	}
	for _, listener := range listeners {
		listener <- err
	}
}
1360236
func (b *BulkIndexer) startTimer() {
	ticker := time.NewTicker(b.BufferDelayMax)
	go func() {
		for {
			select {
			case <-ticker.C:
				b.mu.Lock()
				// don't send unless last sendor was the time,
				// otherwise an indication of other thresholds being hit
				// where time isn't needed
				if b.buf.Len() > 0 && b.needsTimeBasedFlush {
					b.needsTimeBasedFlush = true
					b.send(b.buf)
				} else if b.buf.Len() > 0 {
					b.needsTimeBasedFlush = true
				}
				b.mu.Unlock()
			case <-b.timerDoneChan:
				// shutdown this go routine
				ticker.Stop()
				return
			}

		}
	}()
}
1342587
func (n *NeutrinoNotifier) notificationDispatcher() {
	defer n.wg.Done()
out:
	for {
		select {
		case cancelMsg := <-n.notificationCancels:
			switch msg := cancelMsg.(type) {
			case *epochCancel:
				chainntnfs.Log.Infof("Cancelling epoch "+
					"notification, epoch_id=%v", msg.epochID)

				// First, we'll lookup the original
				// registration in order to stop the active
				// queue goroutine.
				reg := n.blockEpochClients[msg.epochID]
				reg.epochQueue.Stop()

				// Next, close the cancel channel for this
				// specific client, and wait for the client to
				// exit.
				close(n.blockEpochClients[msg.epochID].cancelChan)
				n.blockEpochClients[msg.epochID].wg.Wait()

				// Once the client has exited, we can then
				// safely close the channel used to send epoch
				// notifications, in order to notify any
				// listeners that the intent has been
				// cancelled.
				close(n.blockEpochClients[msg.epochID].epochChan)
				delete(n.blockEpochClients, msg.epochID)
			}

		case registerMsg := <-n.notificationRegistry:
			switch msg := registerMsg.(type) {
			case *chainntnfs.HistoricalConfDispatch:
				// We'll start a historical rescan chain of the
				// chain asynchronously to prevent blocking
				// potentially long rescans.
				n.wg.Add(1)
				go func() {
					defer n.wg.Done()

					confDetails, err := n.historicalConfDetails(
						msg.ConfRequest,
						msg.StartHeight, msg.EndHeight,
					)
					if err != nil {
						chainntnfs.Log.Error(err)
						return
					}

					// If the historical dispatch finished
					// without error, we will invoke
					// UpdateConfDetails even if none were
					// found. This allows the notifier to
					// begin safely updating the height hint
					// cache at tip, since any pending
					// rescans have now completed.
					err = n.txNotifier.UpdateConfDetails(
						msg.ConfRequest, confDetails,
					)
					if err != nil {
						chainntnfs.Log.Error(err)
					}
				}()

			case *blockEpochRegistration:
				chainntnfs.Log.Infof("New block epoch subscription")

				n.blockEpochClients[msg.epochID] = msg

				// If the client did not provide their best
				// known block, then we'll immediately dispatch
				// a notification for the current tip.
				if msg.bestBlock == nil {
					n.notifyBlockEpochClient(
						msg, n.bestBlock.Height,
						n.bestBlock.Hash,
					)

					msg.errorChan <- nil
					continue
				}

				// Otherwise, we'll attempt to deliver the
				// backlog of notifications from their best
				// known block.
				n.bestBlockMtx.Lock()
				bestHeight := n.bestBlock.Height
				n.bestBlockMtx.Unlock()

				missedBlocks, err := chainntnfs.GetClientMissedBlocks(
					n.chainConn, msg.bestBlock, bestHeight,
					false,
				)
				if err != nil {
					msg.errorChan <- err
					continue
				}

				for _, block := range missedBlocks {
					n.notifyBlockEpochClient(
						msg, block.Height, block.Hash,
					)
				}

				msg.errorChan <- nil

			case *rescanFilterUpdate:
				err := n.chainView.Update(msg.updateOptions...)
				if err != nil {
					chainntnfs.Log.Errorf("Unable to "+
						"update rescan filter: %v", err)
				}
				msg.errChan <- err
			}

		case item := <-n.chainUpdates.ChanOut():
			update := item.(*filteredBlock)
			if update.connect {
				n.bestBlockMtx.Lock()
				// Since neutrino has no way of knowing what
				// height to rewind to in the case of a reorged
				// best known height, there is no point in
				// checking that the previous hash matches the
				// the hash from our best known height the way
				// the other notifiers do when they receive
				// a new connected block. Therefore, we just
				// compare the heights.
				if update.height != uint32(n.bestBlock.Height+1) {
					// Handle the case where the notifier
					// missed some blocks from its chain
					// backend
					chainntnfs.Log.Infof("Missed blocks, " +
						"attempting to catch up")

					_, missedBlocks, err :=
						chainntnfs.HandleMissedBlocks(
							n.chainConn,
							n.txNotifier,
							n.bestBlock,
							int32(update.height),
							false,
						)
					if err != nil {
						chainntnfs.Log.Error(err)
						n.bestBlockMtx.Unlock()
						continue
					}

					for _, block := range missedBlocks {
						filteredBlock, err :=
							n.getFilteredBlock(block)
						if err != nil {
							chainntnfs.Log.Error(err)
							n.bestBlockMtx.Unlock()
							continue out
						}
						err = n.handleBlockConnected(filteredBlock)
						if err != nil {
							chainntnfs.Log.Error(err)
							n.bestBlockMtx.Unlock()
							continue out
						}
					}

				}

				err := n.handleBlockConnected(update)
				if err != nil {
					chainntnfs.Log.Error(err)
				}

				n.bestBlockMtx.Unlock()
				continue
			}

			n.bestBlockMtx.Lock()
			if update.height != uint32(n.bestBlock.Height) {
				chainntnfs.Log.Infof("Missed disconnected " +
					"blocks, attempting to catch up")
			}
			newBestBlock, err := chainntnfs.RewindChain(
				n.chainConn, n.txNotifier, n.bestBlock,
				int32(update.height-1),
			)
			if err != nil {
				chainntnfs.Log.Errorf("Unable to rewind chain "+
					"from height %d to height %d: %v",
					n.bestBlock.Height, update.height-1, err)
			}

			// Set the bestHeight here in case a chain rewind
			// partially completed.
			n.bestBlock = newBestBlock
			n.bestBlockMtx.Unlock()

		case txUpdate := <-n.txUpdates.ChanOut():
			// A new relevant transaction notification has been
			// received from the backend. We'll attempt to process
			// it to determine if it fulfills any outstanding
			// confirmation and/or spend requests and dispatch
			// notifications for them.
			update := txUpdate.(*relevantTx)
			err := n.txNotifier.ProcessRelevantSpendTx(
				update.tx, uint32(update.details.Height),
			)
			if err != nil {
				chainntnfs.Log.Errorf("Unable to process "+
					"transaction %v: %v", update.tx.Hash(),
					err)
			}

		case err := <-n.rescanErr:
			chainntnfs.Log.Errorf("Error during rescan: %v", err)

		case <-n.quit:
			return

		}
	}
}
809640
func (b *BitcoindNotifier) notificationDispatcher() {
out:
	for {
		select {
		case cancelMsg := <-b.notificationCancels:
			switch msg := cancelMsg.(type) {
			case *epochCancel:
				chainntnfs.Log.Infof("Cancelling epoch "+
					"notification, epoch_id=%v", msg.epochID)

				// First, we'll lookup the original
				// registration in order to stop the active
				// queue goroutine.
				reg := b.blockEpochClients[msg.epochID]
				reg.epochQueue.Stop()

				// Next, close the cancel channel for this
				// specific client, and wait for the client to
				// exit.
				close(b.blockEpochClients[msg.epochID].cancelChan)
				b.blockEpochClients[msg.epochID].wg.Wait()

				// Once the client has exited, we can then
				// safely close the channel used to send epoch
				// notifications, in order to notify any
				// listeners that the intent has been
				// cancelled.
				close(b.blockEpochClients[msg.epochID].epochChan)
				delete(b.blockEpochClients, msg.epochID)

			}
		case registerMsg := <-b.notificationRegistry:
			switch msg := registerMsg.(type) {
			case *chainntnfs.HistoricalConfDispatch:
				// Look up whether the transaction is already
				// included in the active chain. We'll do this
				// in a goroutine to prevent blocking
				// potentially long rescans.
				//
				// TODO(wilmer): add retry logic if rescan fails?
				b.wg.Add(1)
				go func() {
					defer b.wg.Done()

					confDetails, _, err := b.historicalConfDetails(
						msg.ConfRequest,
						msg.StartHeight, msg.EndHeight,
					)
					if err != nil {
						chainntnfs.Log.Errorf("Rescan to "+
							"determine the conf "+
							"details of %v within "+
							"range %d-%d failed: %v",
							msg.ConfRequest,
							msg.StartHeight,
							msg.EndHeight, err)
						return
					}

					// If the historical dispatch finished
					// without error, we will invoke
					// UpdateConfDetails even if none were
					// found. This allows the notifier to
					// begin safely updating the height hint
					// cache at tip, since any pending
					// rescans have now completed.
					err = b.txNotifier.UpdateConfDetails(
						msg.ConfRequest, confDetails,
					)
					if err != nil {
						chainntnfs.Log.Errorf("Unable "+
							"to update conf "+
							"details of %v: %v",
							msg.ConfRequest, err)
					}
				}()

			case *chainntnfs.HistoricalSpendDispatch:
				// In order to ensure we don't block the caller
				// on what may be a long rescan, we'll launch a
				// goroutine to do so in the background.
				//
				// TODO(wilmer): add retry logic if rescan fails?
				b.wg.Add(1)
				go func() {
					defer b.wg.Done()

					spendDetails, err := b.historicalSpendDetails(
						msg.SpendRequest,
						msg.StartHeight, msg.EndHeight,
					)
					if err != nil {
						chainntnfs.Log.Errorf("Rescan to "+
							"determine the spend "+
							"details of %v within "+
							"range %d-%d failed: %v",
							msg.SpendRequest,
							msg.StartHeight,
							msg.EndHeight, err)
						return
					}

					// If the historical dispatch finished
					// without error, we will invoke
					// UpdateSpendDetails even if none were
					// found. This allows the notifier to
					// begin safely updating the height hint
					// cache at tip, since any pending
					// rescans have now completed.
					err = b.txNotifier.UpdateSpendDetails(
						msg.SpendRequest, spendDetails,
					)
					if err != nil {
						chainntnfs.Log.Errorf("Unable "+
							"to update spend "+
							"details of %v: %v",
							msg.SpendRequest, err)
					}
				}()

			case *blockEpochRegistration:
				chainntnfs.Log.Infof("New block epoch subscription")

				b.blockEpochClients[msg.epochID] = msg

				// If the client did not provide their best
				// known block, then we'll immediately dispatch
				// a notification for the current tip.
				if msg.bestBlock == nil {
					b.notifyBlockEpochClient(
						msg, b.bestBlock.Height,
						b.bestBlock.Hash,
					)

					msg.errorChan <- nil
					continue
				}

				// Otherwise, we'll attempt to deliver the
				// backlog of notifications from their best
				// known block.
				missedBlocks, err := chainntnfs.GetClientMissedBlocks(
					b.chainConn, msg.bestBlock,
					b.bestBlock.Height, true,
				)
				if err != nil {
					msg.errorChan <- err
					continue
				}

				for _, block := range missedBlocks {
					b.notifyBlockEpochClient(
						msg, block.Height, block.Hash,
					)
				}

				msg.errorChan <- nil
			}

		case ntfn := <-b.chainConn.Notifications():
			switch item := ntfn.(type) {
			case chain.BlockConnected:
				blockHeader, err :=
					b.chainConn.GetBlockHeader(&item.Hash)
				if err != nil {
					chainntnfs.Log.Errorf("Unable to fetch "+
						"block header: %v", err)
					continue
				}

				if blockHeader.PrevBlock != *b.bestBlock.Hash {
					// Handle the case where the notifier
					// missed some blocks from its chain
					// backend.
					chainntnfs.Log.Infof("Missed blocks, " +
						"attempting to catch up")
					newBestBlock, missedBlocks, err :=
						chainntnfs.HandleMissedBlocks(
							b.chainConn,
							b.txNotifier,
							b.bestBlock, item.Height,
							true,
						)

					if err != nil {
						// Set the bestBlock here in case
						// a catch up partially completed.
						b.bestBlock = newBestBlock
						chainntnfs.Log.Error(err)
						continue
					}

					for _, block := range missedBlocks {
						err := b.handleBlockConnected(block)
						if err != nil {
							chainntnfs.Log.Error(err)
							continue out
						}
					}
				}

				newBlock := chainntnfs.BlockEpoch{
					Height: item.Height,
					Hash:   &item.Hash,
				}
				if err := b.handleBlockConnected(newBlock); err != nil {
					chainntnfs.Log.Error(err)
				}

				continue

			case chain.BlockDisconnected:
				if item.Height != b.bestBlock.Height {
					chainntnfs.Log.Infof("Missed disconnected" +
						"blocks, attempting to catch up")
				}

				newBestBlock, err := chainntnfs.RewindChain(
					b.chainConn, b.txNotifier,
					b.bestBlock, item.Height-1,
				)
				if err != nil {
					chainntnfs.Log.Errorf("Unable to rewind chain "+
						"from height %d to height %d: %v",
						b.bestBlock.Height, item.Height-1, err)
				}

				// Set the bestBlock here in case a chain
				// rewind partially completed.
				b.bestBlock = newBestBlock

			case chain.RelevantTx:
				// We only care about notifying on confirmed
				// spends, so if this is a mempool spend, we can
				// ignore it and wait for the spend to appear in
				// on-chain.
				if item.Block == nil {
					continue
				}

				tx := btcutil.NewTx(&item.TxRecord.MsgTx)
				err := b.txNotifier.ProcessRelevantSpendTx(
					tx, uint32(item.Block.Height),
				)
				if err != nil {
					chainntnfs.Log.Errorf("Unable to "+
						"process transaction %v: %v",
						tx.Hash(), err)
				}
			}

		case <-b.quit:
			break out
		}
	}
	b.wg.Done()
}
1213246
func (w *Watcher) notifyInProcess(listener Listener) (err *utils.Error) {
	shouldReturn := false
	// This code block ensures that either a timer is created
	// or that a process would be added the the h.refreshChannel
	func() {
		w.timerMutex.Lock()
		defer w.timerMutex.Unlock()
		// If we are in the process of a rebuild, forceRefresh will always be true
		w.forceRefresh = true
		if w.refreshTimer != nil {
			utils.Logger.Info("Found existing timer running, resetting")
			w.refreshTimer.Reset(time.Millisecond * w.refreshTimerMS)
			shouldReturn = true
			w.refreshChannelCount++
		} else {
			w.refreshTimer = time.NewTimer(time.Millisecond * w.refreshTimerMS)
		}
	}()

	// If another process is already waiting for the timer this one
	// only needs to return the output from the channel
	if shouldReturn {
		return <-w.refreshChannel
	}
	utils.Logger.Info("Waiting for refresh timer to expire")
	<-w.refreshTimer.C
	w.timerMutex.Lock()

	// Ensure the queue is properly dispatched even if a panic occurs
	defer func() {
		for x := 0; x < w.refreshChannelCount; x++ {
			w.refreshChannel <- err
		}
		w.refreshChannelCount = 0
		w.refreshTimer = nil
		w.timerMutex.Unlock()
	}()

	err = listener.Refresh()
	if err != nil {
		utils.Logger.Info("Watcher: Recording error last build, setting rebuild on", "error", err)
	} else {
		w.lastError = -1
		w.forceRefresh = false
	}
	utils.Logger.Info("Rebuilt, result", "error", err)
	return
}
843378
func (l *State) StopNotify(ch chan<- struct{}) {
	l.Lock()
	defer l.Unlock()
	delete(l.notifyHandlers, ch)
}