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) } }
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) } } } } } }