// simple view. No in place updates func RenderQuietView(progressChannel chan models.SyncProgress, wg *sync.WaitGroup) { depthChar := "--- " defer wg.Done() syncStates := make(map[string]map[string]string) for sp := range progressChannel { if _, exists := syncStates[sp.Node.Fqdn]; !exists { syncStates[sp.Node.Fqdn] = make(map[string]string) } switch sp.State { case "skipped": for i := 0; i < sp.Node.Depth; i++ { fmt.Printf(depthChar) } line := fmt.Sprintf("%v %v %v", sp.Node.Fqdn, sp.Repository, sp.State) tm.Printf(tm.Color(tm.Bold(line), tm.MAGENTA)) tm.Flush() case "error": for i := 0; i < sp.Node.Depth; i++ { fmt.Printf(depthChar) } line := fmt.Sprintf("%v %v %v", sp.Node.Fqdn, sp.Repository, sp.State) tm.Printf(tm.Color(tm.Bold(line), tm.RED)) tm.Flush() case "running": // only output state changes if syncStates[sp.Node.Fqdn][sp.Repository] != sp.State { for i := 0; i < sp.Node.Depth; i++ { fmt.Printf(depthChar) } line := fmt.Sprintf("%v %v %v", sp.Node.Fqdn, sp.Repository, sp.State) tm.Printf(tm.Color(line, tm.BLUE)) tm.Flush() } syncStates[sp.Node.Fqdn][sp.Repository] = sp.State case "finished": for i := 0; i < sp.Node.Depth; i++ { fmt.Printf(depthChar) } line := fmt.Sprintf("%v %v %v", sp.Node.Fqdn, sp.Repository, sp.State) tm.Printf(tm.Color(tm.Bold(line), tm.GREEN)) tm.Flush() } } }
func termPrintln(s string) { if verbose { // log.Println(s) return } t := tm.Width() line := make([]byte, t) for i := 0; i < t; i++ { line[i] = []byte(" ")[0] } line = append([]byte(s), line[len(s):]...) tm.Printf(string(line)) }
func main() { var ( errCh = make(chan error, 16) receivedCh = make(chan int, 1024) sentCh = make(chan int, 1024) sent = 0 lastSent = 0 received = 0 lastReceived = 0 ) // read params (server address:port, qos settings, number of publishers, number of subscribers) flag.Parse() // generate topics in advance, so we can run the subscribers before starting to publish for i := 0; i < *numTop; i++ { newTopic() } // // subscribe to topics // // TODO: multiple subscribers. // initialise a timeout (if no messages are received in the given time since the last publish.) timeout := time.NewTimer(10 * time.Second) resetSubTimeout := func() { timeout.Reset(time.Duration(*subTimeout) * time.Second) } // discarding received messages messageHandler := func(client *mqtt.Client, m mqtt.Message) { if string(m.Payload()) == "hello world" { receivedCh <- 1 resetSubTimeout() // reset timeout } } // prepare filter from topics and qos filters := map[string]byte{} for _, topic := range getTopics() { fmt.Printf("Created topic %s with qos %v\n", topic, *qos) filters[topic] = byte(*qos) } // multisubscribers fmt.Println("Connecting subscribers...") for i := 0; i < *numSub; i++ { subscriber := newClient() if token := subscriber.client.Connect(); token.Wait() && token.Error() != nil { errCh <- token.Error() } defer subscriber.client.Disconnect(250) token := subscriber.client.SubscribeMultiple(filters, messageHandler) if token.Wait() && token.Error() != nil { errCh <- token.Error() } } // // Publish to topics // // set value for timeout timeout = time.NewTimer(time.Duration(*subTimeout) * time.Second) go func() { for { select { case <-timeout.C: errCh <- fmt.Errorf("Subscriber timeout.. no more messages?") } } }() // publishers for i := 0; i < *numPub; i++ { go func() { c := newClient() if token := c.client.Connect(); token.Wait() && token.Error() != nil { errCh <- token.Error() } defer c.client.Disconnect(100) // publish (sequential per client) topics := getTopics() for k := 0; k < *numMessages; k++ { topic := topics[k%len(topics)] token := c.client.Publish(topic, byte(*qos), *retained, "hello world") if token.Wait() && token.Error() != nil { errCh <- token.Error() } sentCh <- 1 time.Sleep(time.Duration(*pubDelay) * time.Millisecond) } }() } // creating fancy output // start := time.Now() redraw := time.NewTicker(100 * time.Millisecond) if *nograph { redraw = time.NewTicker(1 * time.Second) } row := 0.0 // table data := new(tm.DataTable) data.AddColumn("Time (sec)") data.AddColumn("Sent") data.AddColumn("Received") for { select { case <-redraw.C: if !*nograph { tm.Clear() tm.Printf("[Published : Received]: [%v : %v]\n\n", sent, received) row += 1.0 data.AddRow(row/10.0, float64(sent), float64(received)) tm.Print(tm.NewLineChart(tm.Width()-4, tm.Height()-6).Draw(data)) tm.Flush() } else { if sent != lastSent || received != lastReceived { fmt.Printf("[Published : Received]: [%v : %v]\n", sent, received) lastSent, lastReceived = sent, received } } case e := <-errCh: fmt.Println(e.Error()) return case s := <-sentCh: sent += s case r := <-receivedCh: received += r } } }