client/bill/monitor.go
func (m *Monitor) Run() error {
	m.mtx.Lock()
	if m.exit != nil {
		m.mtx.Unlock()
		return ErrAlreadyRunning
	}
	m.exit = make(chan struct{}, 1)
	m.exited = make(chan struct{}, 1)
	m.mtx.Unlock()

	period := time.Duration(m.conf.CollectPeriod) * time.Millisecond
L:
	for {
		select {
		case <-m.exit:
			break L
		default:
		}

		started := time.Now()

		chans, err := m.db.SelectAllFrom(data.ChannelTable, `
			 JOIN accounts ON eth_addr = client
			WHERE service_status IN ('active', 'suspended')
			  AND channel_status = 'active' AND in_use`)
		if err != nil {
			m.logger.Error(err.Error())
			break L
		}

		for _, v := range chans {
			err := m.processChannel(v.(*data.Channel))

			select {
			case m.processErrors <- err:
			default:
			}

			if err != nil {
				break L
			}
		}

		time.Sleep(period - time.Now().Sub(started))
	}

	m.exited <- struct{}{}

	m.mtx.Lock()
	m.exit = nil
	m.mtx.Unlock()

	m.logger.Info(ErrMonitorClosed.Error())
	return ErrMonitorClosed
}
func (m *Monitor) Run() error {
	m.mtx.Lock()
	if m.exit != nil {
		m.mtx.Unlock()
		return ErrAlreadyRunning
	}
	m.exit = make(chan struct{}, 1)
	m.exited = make(chan struct{}, 1)
	m.mtx.Unlock()

	period := time.Duration(m.conf.CollectPeriod) * time.Millisecond
L:
	for {
		select {
		case <-m.exit:
			break L
		default:
		}

		started := time.Now()

		chans, err := m.db.SelectAllFrom(data.ChannelTable, `
			 JOIN accounts ON eth_addr = client
			WHERE service_status IN ('active', 'suspended')
			  AND channel_status = 'active' AND in_use`)
		if err != nil {
			m.logger.Error(err.Error())
			break L
		}

		for _, v := range chans {
			err := m.processChannel(v.(*data.Channel))

			select {
			case m.processErrors <- err:
			default:
			}

			if err != nil {
				break L
			}
		}

		time.Sleep(period - time.Now().Sub(started))
	}

	m.exited <- struct{}{}

	m.mtx.Lock()
	m.exit = nil
	m.mtx.Unlock()

	m.logger.Info(ErrMonitorClosed.Error())
	return ErrMonitorClosed
}
func ( m * Monitor ) Run ( ) error { m . mtx . Lock ( ) if m . exit != nil { m . mtx . Unlock ( ) return ErrAlreadyRunning } m . exit = make ( chan struct { } , 1 ) m . exited = make ( chan struct { } , 1 ) m . mtx . Unlock ( ) period := time . Duration ( m . conf . CollectPeriod ) * time . Millisecond L : for { select { case <- m . exit : break L default : } started := time . Now ( ) chans , err := m . db . SelectAllFrom ( data . ChannelTable , `
			 JOIN accounts ON eth_addr = client
			WHERE service_status IN ('active', 'suspended')
			  AND channel_status = 'active' AND in_use` ) if err != nil { m . logger . Error ( err . Error ( ) ) break L } for _ , v := range chans { err := m . processChannel ( v . ( * data . Channel ) ) select { case m . processErrors <- err : default : } if err != nil { break L } } time . Sleep ( period - time . Now ( ) . Sub ( started ) ) } m . exited <- struct { } { } m . mtx . Lock ( ) m . exit = nil m . mtx . Unlock ( ) m . logger . Info ( ErrMonitorClosed . Error ( ) ) return ErrMonitorClosed }
// Run processes billing for active client channels. This function does not
// return until an error occurs or Close() is called.
Run processes billing for active client channels . This function does not return until an error occurs or Close () is called .