40 lines
1.0 KiB
Python
40 lines
1.0 KiB
Python
"""
|
|
Progress lines: enough to see that a long run is alive and where it is, not so
|
|
many that printing them slows it down.
|
|
|
|
Every line is flushed, so progress shows up as it happens even when the output
|
|
is piped or tee'd into a log.
|
|
"""
|
|
|
|
import time
|
|
|
|
PREFIX = "[dataconvert]"
|
|
|
|
|
|
def say(message):
|
|
print(f"{PREFIX} {message}", flush=True)
|
|
|
|
|
|
def seconds(start):
|
|
return f"{time.monotonic() - start:.0f}s"
|
|
|
|
|
|
class Ticker:
|
|
"""How far a long loop has got, at most once every `every` seconds."""
|
|
|
|
# How often the loop asks. Checking the clock on every row would itself be
|
|
# a measurable cost on a million-row table.
|
|
CHECK = 2000
|
|
|
|
def __init__(self, label, total, every=10.0):
|
|
self.label = label
|
|
self.total = total
|
|
self.every = every
|
|
self.started = self.last = time.monotonic()
|
|
|
|
def tick(self, done):
|
|
now = time.monotonic()
|
|
if now - self.last >= self.every:
|
|
self.last = now
|
|
say(f" {self.label}: {done} of {self.total} rows ({now - self.started:.0f}s)")
|