Exemple #1
0
func bcastToRedisPubSub(pool *redis.Pool, psgroup *bcast.Group, redischannel string) {
	conn := pool.Get()
	defer conn.Close()
	psc := redis.PubSubConn{Conn: conn}
	psc.Subscribe(redischannel)
	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			h1 := psgroup.Join()
			h1.Send(string(v.Data))
			h1.Close()
		}
	}
}
// Check & report internet availability. Stop all probers when sample internet resources not available.
// Refs to config option ``samples``.
func Heartbeat(ctl *bcast.Group) {
	var previous bool

	ctlsnr := ctl.Join()

	time.Sleep(1 * time.Second)

	for {
		for _, uri := range cfg.Samples {
			client := NewTimeoutClient(12*time.Second, 6*time.Second)
			req, err := http.NewRequest("HEAD", uri, nil)
			if err != nil {
				fmt.Println("Internet not available. All checks stopped.")
				StatsGlobals.MonitoringState = false
				continue
			}
			_, err = client.Do(req)
			if err != nil {
				StatsGlobals.MonitoringState = false
				continue
			}
			StatsGlobals.MonitoringState = true
		}
		if previous != StatsGlobals.MonitoringState {
			if StatsGlobals.MonitoringState {
				ctlsnr.Send(START_MON)
				fmt.Println("Internet Ok. Monitoring started.")
			} else {
				ctlsnr.Send(STOP_MON)
				fmt.Println("Internet not available. Monitoring stopped.")
			}
		}
		previous = StatsGlobals.MonitoringState
		time.Sleep(4 * time.Second)
	}
}
//TimeProvider provide time stamp every configured time
func TimeProvider(group *bcast.Group, d time.Duration) {
	defer group.Close()
	for x := range time.Tick(d) {
		group.Send(x.String())
	}
}
func newReciever(group *bcast.Group) {
	member := group.Join()
	for {
		println("message", member.Recv().(string))
	}
}
// Container keep single stream properties and regulary make tasks for appropriate probers.
func StreamBox(ctl *bcast.Group, stream Stream, streamType StreamType, taskq chan *Task, debugvars *expvar.Map) {
	var checkCount uint64 // число прошедших проверок
	var addSleepToBrokenStream time.Duration
	var tid int64 = time.Now().Unix() // got increasing offset on each program start
	var min, max int
	var command Command
	var online bool = false
	var stats Stats

	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("Stream %s trace: %s\n", stream.Name, r)
		}
	}()

	task := &Task{Stream: stream, ReplyTo: make(chan *Result)}
	switch streamType {
	case HTTP:
		task.ReadBody = false
	case HLS:
		task.ReadBody = true
	case HDS:
		task.ReadBody = true
	case WV:
		task.ReadBody = false
	default:
		task.ReadBody = false
	}
	ctlrcv := ctl.Join() // управление мониторингом
	timer := time.Tick(3 * time.Second)

	for {
		select {
		case recv := <-ctlrcv.In:
			command = recv.(Command)
			switch command {
			case START_MON:
				online = true
			case STOP_MON:
				online = false
			}
		case <-timer:
			SaveStats(stream, stats)
		default:
			if !online {
				time.Sleep(1 * time.Second)
				continue
			}
			max = int(cfg.Params(stream.Group).TimeBetweenTasks)
			min = int(cfg.Params(stream.Group).TimeBetweenTasks / 4. * 3.)
			time.Sleep(time.Duration(rand.Intn(max-min)+min)*time.Second + addSleepToBrokenStream) // randomize streams order
			tid++
			task.Tid = tid
			task.TTL = time.Now().Add(time.Duration(cfg.Params(stream.Group).TaskTTL * time.Second))
			stats.Checks++ // TODO potentially overflow
			taskq <- task
			debugvars.Add("requested-tasks", 1)
			result := <-task.ReplyTo
			if result.ErrType == TTLEXPIRED {
				continue
			} else {
				checkCount++
				if checkCount > 144 {
					fmt.Printf("Repeated %d times %s\n", checkCount, task.Name)
				}
			}

			for _, subres := range result.SubResults {
				subres.Pid = result
				go SaveResult(stream, *subres)
			}
			go SaveResult(stream, *result)

			max = int(cfg.Params(stream.Group).CheckBrokenTime)
			min = int(cfg.Params(stream.Group).CheckBrokenTime / 4. * 3.)

			switch {
			// permanent error, not a timeout:
			case result.ErrType > CRITICAL_LEVEL, result.ErrType == TTLEXPIRED:
				addSleepToBrokenStream = time.Duration(rand.Intn(max-min)+min) * time.Second
			// works ok:
			case result.ErrType == SUCCESS:
				addSleepToBrokenStream = 0
			default:
				addSleepToBrokenStream = 0
			}

			if result.ErrType != TTLEXPIRED {
				if result.ErrType >= WARNING_LEVEL {
					go Log(ERROR, stream, *result)
				} else {
					if result.Elapsed >= cfg.Params(stream.Group).VerySlowWarningTimeout*time.Second {
						result.ErrType = VERYSLOW
						go Log(WARNING, stream, *result)
					} else if result.Elapsed >= cfg.Params(stream.Group).SlowWarningTimeout*time.Second {
						result.ErrType = SLOW
						go Log(WARNING, stream, *result)
					}
				}
			}
		}
	}
}