Pull can take a long time to sanity-check revisions (especially on
initial pull to a fresh db), and doesn't provide any feedback during
this. This patch lets packet_consumer and children run a callback when
a revision is written out. Netsync then uses this to add a ticker for
revisions written. Is there a better way to do this?

Since this makes the "count" ticker too long for an 80-char terminal,
it also changes the way tick_write_count displays to be like
monotone:   certs |    keys
monotone:    8456 |      21

monotone: bytes in | bytes out | certs in | revs checked | revs in
monotone:    25.6M |    731.5k |     8456 |         2073 |    2784

.
Comments, suggestions? Is this (ticker) something we want to change?

Tim
# 
# patch "netsync.cc"
#  from [60652355c67df5803337e5deb857a8dbb279ffa1]
#    to [e1f885ae4739699f950e7d311e5d4bd8815ade54]
# 
# patch "packet.cc"
#  from [478a95c883062f409c2d9558dd3177e9d5e6ac2c]
#    to [90a102794d4dc3b6943b502026bfb74c4ab69fab]
# 
# patch "packet.hh"
#  from [f5f36ee1eb04d53b1d407fe6f5ea1b24d9c4a847]
#    to [3ecd9f0de0e37c56a105cfc6bfd8a5fdb84032c7]
# 
# patch "ui.cc"
#  from [b06e19535d68d00f01c8ab33848e79f1942c9532]
#    to [c2e8c87e5b0de5106ab35fbcc356b069474c6994]
# 
--- netsync.cc
+++ netsync.cc
@@ -12,6 +12,7 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
 
 #include "app_state.hh"
 #include "cert.hh"
@@ -233,6 +234,7 @@
   auto_ptr<ticker> cert_out_ticker;
   auto_ptr<ticker> revision_in_ticker;
   auto_ptr<ticker> revision_out_ticker;
+  auto_ptr<ticker> revision_checked_ticker;
 
   map< std::pair<utf8, netcmd_item_type>, 
        boost::shared_ptr<merkle_table> > merkle_tables;
@@ -260,6 +262,8 @@
           Netxx::Timeout const & to);
 
   virtual ~session() {}
+  
+  void rev_written_callback();
 
   id mk_nonce();
   void mark_recent_io();
@@ -433,6 +437,7 @@
   cert_out_ticker(NULL),
   revision_in_ticker(NULL),
   revision_out_ticker(NULL),
+  revision_checked_ticker(NULL),
   analyzed_ancestry(false),
   saved_nonce(""),
   received_goodbye(false),
@@ -447,6 +452,9 @@
       this->collection = idx(collections, 0);
     }
     
+  dbw.set_on_revision_written(boost::bind(&session::rev_written_callback,
+                                          this));
+  
   // we will panic here if the user doesn't like urandom and we can't give
   // them a real entropy-driven random.  
   bool request_blocking_rng = false;
@@ -478,6 +486,11 @@
     }
 }
 
+void session::rev_written_callback()
+{
+  if(revision_checked_ticker.get()) ++(*revision_checked_ticker);
+}
+
 id 
 session::mk_nonce()
 {
@@ -2887,6 +2900,7 @@
   sess.byte_out_ticker.reset(new ticker("bytes out", "<", 1024, true));
   if (role == sink_role)
     {
+      sess.revision_checked_ticker.reset(new ticker("revs written", "w", 1));
       sess.cert_in_ticker.reset(new ticker("certs in", "c", 3));
       sess.revision_in_ticker.reset(new ticker("revs in", "r", 1));
     }
@@ -2898,6 +2912,7 @@
   else
     {
       I(role == source_and_sink_role);
+      sess.revision_checked_ticker.reset(new ticker("revs written", "w", 1));
       sess.revision_in_ticker.reset(new ticker("revs in", "r", 1));
       sess.revision_out_ticker.reset(new ticker("revs out", "R", 1));
     }
--- packet.cc
+++ packet.cc
@@ -428,6 +428,13 @@
   I(all_prerequisites_satisfied());
 }
 
+
+void packet_consumer::set_on_revision_written(boost::function0<void> const & x)
+{
+  on_revision_written=x;
+}
+
+
 struct packet_db_writer::impl
 {
   app_state & app;
@@ -859,6 +866,7 @@
       if (dp->all_prerequisites_satisfied())
         {
           pimpl->app.db.put_revision(ident, dat);
+          if(on_revision_written) on_revision_written();
           pimpl->accepted_revision(ident, *this);
         }
     }
@@ -990,6 +998,11 @@
 
 #define DOIT(x) pimpl->do_packet(boost::shared_ptr<delayed_packet>(new x));
 
+void packet_db_valve::set_on_revision_written(boost::function0<void> const & x)
+{
+  on_revision_written=x;
+  pimpl->writer.set_on_revision_written(x);
+}
 void
 packet_db_valve::consume_file_data(file_id const & ident, 
                                    file_data const & dat)
--- packet.hh
+++ packet.hh
@@ -9,6 +9,8 @@
 #include <iosfwd>
 #include <memory>
 
+#include <boost/function.hpp>
+
 #include "app_state.hh"
 #include "ui.hh"
 #include "vocab.hh"
@@ -34,6 +36,12 @@
 
 struct packet_consumer
 {
+protected:
+  boost::function0<void> on_revision_written;
+public:
+  
+  virtual void set_on_revision_written(boost::function0<void> const & x);
+  
   virtual ~packet_consumer() {}
   virtual void consume_file_data(file_id const & ident, 
                                  file_data const & dat) = 0;
@@ -154,6 +162,7 @@
   packet_db_valve(app_state & app,
                   bool take_keys = false);
   virtual ~packet_db_valve();
+  virtual void set_on_revision_written(boost::function0<void> const & x);
   virtual void consume_file_data(file_id const & ident, 
                                  file_data const & dat);
   virtual void consume_file_delta(file_id const & id_old, 
--- ui.cc
+++ ui.cc
@@ -80,15 +80,36 @@
 
 void tick_write_count::write_ticks()
 {
-  string tickline = "\rmonotone:";
+  string tickline1, tickline2;
+  bool first_tick = true;
+
+  tickline1 = "monotone: ";
+  tickline2 = "\rmonotone:";
+  
+  unsigned int width;
+  unsigned int minwidth = 7;
   for (map<string,ticker *>::const_iterator i = ui.tickers.begin();
        i != ui.tickers.end(); ++i)
     {
-      string suffix;
-      ostringstream disptick;
+      width = 1 + i->second->name.size();
+      if (!first_tick)
+        {
+          tickline1 += " | ";
+          tickline2 += " |";
+        }
+      first_tick = false;
+      if(i->second->name.size() < minwidth)
+        {
+          tickline1.append(minwidth - i->second->name.size(),' ');
+          width += minwidth - i->second->name.size();
+        }
+      tickline1 += i->second->name;
+      
+      string count;
       if (i->second->kilocount && i->second->ticks >= 10000)
         { // automatic unit conversion is enabled
           float div;
+          string suffix;
           if (i->second->ticks >= 1048576) {
           // ticks >=1MB, use Mb
             div = 1048576;
@@ -98,34 +119,49 @@
             div = 1024;
             suffix = "k";
           }
-          disptick << std::fixed << std::setprecision(1) <<
-              (i->second->ticks / div);
-        } else {
-          // no automatic unit conversion.
-          disptick << i->second->ticks;
+          count = (F("%.1f%s") % (i->second->ticks / div) % suffix).str();
         }
-      tickline +=
-        string(" [")
-        + i->first + ": " + disptick.str()
-        + suffix
-        + "]";
+      else
+        {
+          count = (F("%d") % i->second->ticks).str();
+        }
+        
+      if(count.size() < width)
+        {
+          tickline2.append(width-count.size(),' ');
+        }
+      else if(count.size() > width)
+        {
+          count = count.substr(count.size() - width);
+        }
+      tickline2 += count;
     }
-  tickline += ui.tick_trailer;
 
-  size_t curr_sz = tickline.size();
+  tickline1 += ui.tick_trailer;
+  
+  size_t curr_sz = tickline2.size();
   if (curr_sz < last_tick_len)
-    tickline += string(last_tick_len - curr_sz, ' ');
+    tickline2.append(last_tick_len - curr_sz, ' ');
   last_tick_len = curr_sz;
 
   unsigned int tw = terminal_width();
-  if (tw && tickline.size() > tw)
+  if(!ui.last_write_was_a_tick)
     {
+      if (tw && tickline1.size() > tw)
+        {
+          // first character in tickline is "\r", which does not take up any
+          // width, so we add 1 to compensate.
+          tickline1.resize(tw + 1);
+        }
+      clog << tickline1 << "\n";
+    }
+  if (tw && tickline2.size() > tw)
+    {
       // first character in tickline is "\r", which does not take up any
       // width, so we add 1 to compensate.
-      tickline.resize(tw + 1);
+      tickline2.resize(tw + 1);
     }
-
-  clog << tickline;
+  clog << tickline2;
   clog.flush();
 }
 
_______________________________________________
Monotone-devel mailing list
Monotone-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/monotone-devel

Reply via email to