desertbit/grumble

Println arbitrarily prints line after the prompt

cassanof opened this issue · 15 comments

Hello,
Sometimes when using Println, Printf, etc... the text gets printed after the prompt instead of in a new line.
This also happens if I use grumble.Println.
I have a whole program using grumble right now which has this issue.
Link to my program: https://github.com/elleven11/pantegana

I think that the issue rises from the fact that the println calls come from a separate goroutine.
How would I be able to fix this issue? thank you.

Hi,
Can you give a reproducible example of this? Best would be with the (slightly modified) samples of this repo. Or you give me the exact commands that I need to run after I cloned your program from your repo.

yes, and thank you for investigating my issue.
My program pre-requirements go-binadata (go get -u github.com/go-bindata/go-bindata/...) and openssl.
So after you clone my repo you have to run make IP=127.0.0.1 DOMAIN=localhost then run the binary in ./out/server.bin after that you can just try to spam listen in the cli and you will see that sometimes the output gets printed after the prompt:
image

Great, I'll try it out :)

Unfortunately, I could not reproduce this behaviour:

[pantegana]$ listen
[+] Server listening on (localhost:1337)
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$
[pantegana]$
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$ listen
[-] A listener is already running.
[pantegana]$

Thats weird... I even tried with another machine and with using another terminal (i use st, tried to use xterm and xfce-terminal).
What could be wrong?

Can you reproduce it consistently? Like does it work every time after a few trials?

Can you reproduce it consistently? Like does it work every time after a few trials?

yes, it happens like once every 10 stdout writes i could say.

Ok. I will check the source code to see, if anything is obvious from there

Btw, so you are using App.Println(), right? Could you show the relevant code from your application?

Yes. This is ./server/listener.go
I instantiated the clivariable as the App
Btw, ctfm.Sprintln just formats the string with color, and even if removed the issue still persists. And I am switching to fatih/color
Also, the issue is present in other parts of the code, this is just the simplest way to show it without making you start clients up, etc..

package server

import (
	"crypto/tls"
	"errors"
	"net/http"

	"github.com/i582/cfmt/cmd/cfmt"
)

//go:generate go-bindata -o cert.go ../cert/...

type Listener struct {
	Cfg    *ListenerConfig
	Server *http.Server
}

type ListenerConfig struct {
	Addr      string
	Plaintext bool
	Verbose   bool
}

var listener *Listener = nil

func (cfg *ListenerConfig) SetupListener() *Listener {
	// read cert binary data from bundled assets
	certData, err := Asset("../cert/server.crt")
	if err != nil {
		cli.Print(cfmt.Sprintf("{{[-] Error reading cert file: %s\n}}::red", err))
	}
	// read key binary data from bundled assets
	keyData, err := Asset("../cert/server.key")
	if err != nil {
		cli.Print(cfmt.Sprintf("{{[-] Error reading cert file: %s\n}}::red", err))
	}

	// create the server with the custom pair
	cert, err := tls.X509KeyPair(certData, keyData)
	tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}}
	server := http.Server{
		Addr:      cfg.Addr,
		TLSConfig: tlsConfig,
	}
	if cfg.Plaintext {
		server.TLSConfig = nil
	}

	return &Listener{
		Cfg:    cfg,
		Server: &server,
	}
}

func StartListener(cfg *ListenerConfig) {
	// check if a listener is already running
	if IsListening() {
		cli.Print(cfmt.Sprintln("{{[-] A listener is already running.}}::red"))
		return
	}

	// start the listener
	cli.Printf("[+] Listening on (%s)\n", cfg.Addr)
	listener = cfg.SetupListener()

	var err error
	if cfg.Plaintext {
		err = listener.Server.ListenAndServe()
	} else {
		err = listener.Server.ListenAndServeTLS("", "")
	}

	if err != http.ErrServerClosed {
		cli.PrintError(err)
		defer CloseListener()
	}
}

func CloseListener() error {
	var err error
	if listener != nil {
		err = listener.Server.Close()
		listener = nil
	} else {
		err = errors.New("There are no listeners running")
	}
	return err
}

func IsListening() bool {
	return listener != nil
}

From your issue description I understand that even if you just use fmt.Print instead of using the grumble builtins, the issue persists?

From your issue description I understand that even if you just use fmt.Print instead of using the grumble builtins, the issue persists?

Yeah it does.

Sorry, I lost track of this issue. Were you able to fix this?

Yes, it actually fixed by itself. It's still a mystery tho.

Alright, thanks for reporting back!