-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When used in multiple thread, all the progress bars are in one line #11
Comments
Could you please clarify? Are you using a progressbar for each thread, and those threads are running in parallel? |
Yes, correctly. I use multiple threads and one thread one progress bar. |
This is not currently doable right now. Will probably be fixed in a later version. |
Yeah, this would be a quite useful feature for the project. |
This involves the manipulation of cursor position in the terminal window which is a bit hard. Will probably be fixed in a later version (1.0?) |
any update on this feature? |
It is on the horizon but recently I've got no time to implement this. |
As an option you can output multiple threads in one line, i.e.: Can elaborate on details of elapsed/estimated time. |
@ctongfei Is an instance of |
@dodalovic It is thread safe after version |
@ctongfei I already tried to use this in a multi threaded environment and its working for me. It thread is independent of the other and creates its own instant of the progress bar and I haven't had any issues. I was wondering though if it was possible to get the progress bar to print on 1 line rather than it keeps appending to the logger. |
@o2themar The planned solution is to have a multi-line progressbar, where each line prints the progress of one thread. This is hard to implement --- sorry for not supporting this. I'll consider implementing this when I'm not busy, or you could start a PR! |
The problem with current implementation is simple actually
out.print('\r'); // before update
out.print(str); What print('\r') does is that it moves the cursor to the beginning of the line. And then the line is rewritten. Based on ANSI/VT100 Terminal Control Escape Sequences to implement multiline progressbar you would have to be moving the cursor up and down to rewrite the corresponding line in the output. Something like (over simplified obviously): import org.jline.terminal.TerminalBuilder
class TerminalPrinter(initialText: String) {
private val position = currentCursorPosition()
init {
if (System.console() == null) throw RuntimeException("non-interactive console")
System.err.print('\r')
System.err.println(initialText)
}
suspend fun rewrite(str: String) {
delay(1000)
val count = currentCursorPosition() - position
moveCursorUp(count)
replaceLine(str)
moveCursorDown(count)
}
private fun moveCursorUp(count: Int) {
System.err.print("\u001b[${count}A")
}
private fun moveCursorDown(count: Int) {
System.err.print("\u001b[${count}B")
}
private fun replaceLine(str: String) {
System.err.print('\r')
System.err.print(str)
System.err.print('\r')
}
private fun currentCursorPosition(): Int {
val terminal = TerminalBuilder.builder()
.jna(true)
.system(true)
.build()
terminal.use {
terminal.enterRawMode()
System.err.print("\u001b[6n")
val reader = terminal.reader()
reader.use {
val buf = CharArray(7)
System.`in`.bufferedReader().read(buf)
val position = buf
.dropWhile { it != '[' }
.drop(1)
.takeWhile { it != ';' }
.joinToString("")
return position.toInt()
}
}
}
}
fun main() = runBlocking {
val a = TerminalPrinter("[a] 1")
val b = TerminalPrinter("[b] 1")
val c = TerminalPrinter("[c] 1")
val d = TerminalPrinter("[d] 1")
System.out.println("some log...")
a.rewrite("[a] 2")
c.rewrite("[c] 2")
b.rewrite("[b] 2")
val e = TerminalPrinter("[e] 1")
d.rewrite("[d] 2")
e.rewrite("[e] 2")
System.out.println("more log...")
a.rewrite("[a] 3")
e.rewrite("[e] 3")
b.rewrite("[b] 3")
d.rewrite("[d] 3")
c.rewrite("[c] 3")
} |
@vehovsky, can you send a pull request? |
@vslee Not really, the above example works well on osx (linux as well probably) but not on windows. Moving the cursor just up/down (without asking terminal for cursor position) would probably work on windows as well, but that is just way too naive implementation and would break a minute some other thread wrote anything to console. |
@vehovsky I understand these ANSI control code (and will probably have to be tested under many different envs, and use |
I've prepared some initial implementation. Will create PR (after work) to start discussion about implementation details. |
@vehovsky Does the pull request that you created not require this work around? Or even with the new version I would still need to implement my own consumer? |
@o2themar short answer, no. The pull requests ensures multiple progress bars can be displayed simultaneously, when supported by terminal in which you have started the JVM. When the terminal does not support moving cursor, now it at least ensures all "done" progressbars are displayed correctly. The "active" progressbars are re-writing each others at the line where cursos currently is (last line). So you may want to create another issue for enhancing loggers integration. |
ok thanks @vehovsky I'll go with your suggestion for now about implementing a consumer to support the logging. I was just making sure that the new implantation didn't already cover this and you were suggestion a work around for now. Its not a big deal having to implement a consumer for the logging and I appreciate you sharing the code to help get me started. Thank you for your help in quickly getting a solution. |
Fixed in |
I use a progressbar for each thread, but all the progress bars are shown in one single line.
The text was updated successfully, but these errors were encountered: