Re: about monitoring the input stream - Mailing list pgsql-jdbc

From Albert Cardona
Subject Re: about monitoring the input stream
Date
Msg-id 200609161208.43680.acardona@ini.phys.ethz.ch
Whole thread Raw
In response to about monitoring the input stream  (Albert Cardona <acardona@ini.phys.ethz.ch>)
Responses Re: about monitoring the input stream  (Dave Cramer <pg@fastcrypt.com>)
List pgsql-jdbc
Mark,

The relevant parts of the code for monitoring the PGStream are attached below.

This code is part of TrakEM2, an ImageJ/postgresql -based application (GPL
applies) for managing an arbitrarily large set of images, segmented profiles
and metadata in general, for the purpose of extracting 3D models and a
hierarchical structure of objects present in the sample represented by the
images. See all details here:
http://www.ini.unizh.ch/~acardona/trakem2.html

The code below belongs to the current svn snapshot, which won't be available
until the end of this month.


/** Extract from private inner class Monitor. GPL applies, see the
TrakEM2-src.zip file, class ini.trakem2.persistence.DBLoader, at
http://www.ini.unizh.ch/~acardona/trakem2.html */

        public Monitor(Connection con) {
                connection = con;
                LoggingInputStream lis = null;
                try {
                        AbstractJdbc2Connection a2 =
(AbstractJdbc2Connection)connection;
                        Class c2 =
connection.getClass().getSuperclass().getSuperclass();
                        java.lang.reflect.Field f_proto =
c2.getDeclaredField("protoConnection");
                        f_proto.setAccessible(true);
                        // protoConnection is a ProtocolConnection interface,
implemented in core.v3.ProtocolConnectionImpl !
                        //ProtocolConnectionImpl pci =
(ProtocolConnectionImpl)m_proto.get(c2); // class is private to the package,
can't cast!
                        Object pci = f_proto.get(a2);
                        // finally, get the PGStream
                        java.lang.reflect.Field f_pgstream =
pci.getClass().getDeclaredField("pgStream");
                        f_pgstream.setAccessible(true);
                                            
                        PGStream pgstream = (PGStream)f_pgstream.get(pci);
                        // now the InputStream
                        java.lang.reflect.Field f_i =
pgstream.getClass().getDeclaredField("pg_input");
                        f_i.setAccessible(true);
                        InputStream stream = (InputStream)f_i.get(pgstream);
                        lis = new LoggingInputStream(stream);
                        f_i.set(pgstream, lis); // TADA! Many thanks to the
PGSQL JDBC mailing list for this last tip on not just monitoring the PGStream
as I was doing, but on replacing the inputstream altogether with a logging
copy! ("CountingInputStream", they called it).

                } catch (Exception e) {
                        new IJError(e);
                }
                this.lis = lis;
                makeWindow();
        }

/** ===================== */

/** The class below exists as ini.trakem2.io.LoggingInputStream in TrakEM2.
The GPL applies, see the TrakEM2-src.zip downloadable at
http://www.ini.unizh.ch/~acardona/trakem2.html */

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.IOException;


/** A class to monitor an input stream for speed and total byte download. */
public class LoggingInputStream extends BufferedInputStream {

        private long last;
        private long n = 0;
        private long accum_time = 0;
        private long accum_bytes = 0;

        public LoggingInputStream(InputStream in) {
                super(in);
                last = System.currentTimeMillis();
        }

        public int read() throws IOException {
                int m = super.read();
                n += m;
                return m;
        }

        public int read(byte[] b) throws IOException {
                int m = super.read(b);
                n += m;
                return m;
        }

        public int read(byte[] b, int off, int len) throws IOException {
                int m = super.read(b, off, len);
                n += m;
                return m;
        }

        /** Put the accumulated count to zero. */
        public void resetInfo() { // to work perfect, this would need a
synchronized clause, but no such perfection is needed, and there are
perfomance issues.
                accum_bytes = n = 0;
                last = System.currentTimeMillis();
                accum_time = 0;
        }

        /** Returns info as
        * [0] = current time in ms
        * [1] = elapsed time in ms since last call to getInfo(long[])
        * [2] = n_bytes_read since last call to getInfo(long[])
        * [3] = accumulated time in ms since last call to resetInfo()
        * [4] = accumulated bytes since last call to resetInfo()
        *
        * So current speed = info[2]/info[1] Kb/s
        */
        public void getInfo(long[] info) {
                long now = System.currentTimeMillis();
                accum_time += now - last;
                accum_bytes += n;
                info[0] = now;
                info[1] = now - last; // elapsed time
                info[2] = n;
                info[3] = accum_time; // total time since last call to
resetInfo()
                info[4] = accum_bytes; // total bytes since last call to
resetInfo()
                // reset cycle vars:
                n = 0;
                last = now;
        }
}


--
Albert Cardona
Molecular Cell Developmental Biology
University of California Los Angeles
Tel +1 310 2067376
Programming: http://www.ini.unizh.ch/~acardona/trakem2.html
Research: http://www.mcdb.ucla.edu/Research/Hartenstein/
Web design: http://www.pixelets.com



pgsql-jdbc by date:

Previous
From: Markus Schaber
Date:
Subject: Re: idle in transaction
Next
From: Dave Cramer
Date:
Subject: Re: about monitoring the input stream