rhmessaging commits: r1829 - store/trunk/cpp/etc.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2008-04-01 17:52:56 -0400 (Tue, 01 Apr 2008)
New Revision: 1829
Modified:
store/trunk/cpp/etc/rhmd
Log:
better way to run as qpidd; use pid to kill single instance
Modified: store/trunk/cpp/etc/rhmd
===================================================================
--- store/trunk/cpp/etc/rhmd 2008-04-01 20:18:44 UTC (rev 1828)
+++ store/trunk/cpp/etc/rhmd 2008-04-01 21:52:56 UTC (rev 1829)
@@ -19,6 +19,7 @@
prog=qpidd
lockfile=/var/lock/subsys/rhmd
+pidfile=/var/run/rhmd.pid
# Source function library.
. /etc/rc.d/init.d/functions
@@ -31,20 +32,25 @@
start() {
echo -n $"Starting RHM daemon: "
- daemon --check $prog "runuser -s /bin/sh qpidd -c \"$prog --daemon --config=/etc/rhmd.conf\""
+ daemon --pidfile $pidfile --check $prog --user qpidd $prog --daemon --config=/etc/rhmd.conf
RETVAL=$?
if [ $RETVAL = 0 ] ; then success ; else failure ; fi
echo
[ $RETVAL = 0 ] && touch $lockfile
+ if [ $RETVAL = 0 ]; then
+ touch $pidfile
+ chown qpidd.qpidd $pidfile
+ runuser -s /bin/sh qpidd -c "qpidd -c > $pidfile"
+ fi
return $RETVAL
}
stop() {
echo -n $"Stopping RHM daemon: "
- killproc $prog
+ killproc -p ${pidfile} $prog
RETVAL=$?
echo
- [ $RETVAL = 0 ] && rm -f $lockfile
+ [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
reload() {
16 years, 10 months
rhmessaging commits: r1827 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-04-01 15:04:26 -0400 (Tue, 01 Apr 2008)
New Revision: 1827
Modified:
store/trunk/cpp/lib/JournalImpl.cpp
Log:
Ummm, fixed a, er, memory leak, that went un-noticed from the tck fix.
Modified: store/trunk/cpp/lib/JournalImpl.cpp
===================================================================
--- store/trunk/cpp/lib/JournalImpl.cpp 2008-04-01 18:40:50 UTC (rev 1826)
+++ store/trunk/cpp/lib/JournalImpl.cpp 2008-04-01 19:04:26 UTC (rev 1827)
@@ -98,6 +98,11 @@
::free(_datap);
_datap = 0;
}
+ if (journalTimerPtr)
+ {
+ delete journalTimerPtr;
+ journalTimerPtr = 0;
+ }
::pthread_mutex_destroy(&_getf_mutex);
}
16 years, 10 months
rhmessaging commits: r1826 - mgmt/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 14:40:50 -0400 (Tue, 01 Apr 2008)
New Revision: 1826
Modified:
mgmt/cumin/python/cumin/system.py
mgmt/cumin/python/cumin/system.strings
mgmt/cumin/python/cumin/widgets.py
mgmt/cumin/python/cumin/widgets.strings
Log:
Introduce a class, CuminDetails, for pulling out all the metadata for
properties and actions and displaying them in a generic fashion.
As a start, add this tab to the system view.
Modified: mgmt/cumin/python/cumin/system.py
===================================================================
--- mgmt/cumin/python/cumin/system.py 2008-04-01 18:39:54 UTC (rev 1825)
+++ mgmt/cumin/python/cumin/system.py 2008-04-01 18:40:50 UTC (rev 1826)
@@ -67,7 +67,7 @@
self.tabs = TabbedModeSet(app, "tabs")
self.add_child(self.tabs)
- self.tabs.add_tab(self.SystemStatsTab(app, "stats"))
+ self.tabs.add_tab(CuminDetails(app, "details"))
def render_title(self, session, system):
return "System '%s'" % system.sysId
@@ -96,7 +96,3 @@
def render_data_url(self, session, system):
return "model.xml"
-
- class SystemStatsTab(Widget):
- def render_title(self, session, *args):
- return "Statistics"
Modified: mgmt/cumin/python/cumin/system.strings
===================================================================
--- mgmt/cumin/python/cumin/system.strings 2008-04-01 18:39:54 UTC (rev 1825)
+++ mgmt/cumin/python/cumin/system.strings 2008-04-01 18:40:50 UTC (rev 1826)
@@ -35,3 +35,5 @@
<tr><th>Created – Deleted</th><td>{created_deleted}</td></tr>
<tr><th>Updated</th><td>{updated}</td></tr>
</table>
+
+{tabs}
Modified: mgmt/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/cumin/python/cumin/widgets.py 2008-04-01 18:39:54 UTC (rev 1825)
+++ mgmt/cumin/python/cumin/widgets.py 2008-04-01 18:40:50 UTC (rev 1826)
@@ -240,6 +240,27 @@
cls = self.app.model.get_class_by_object(object)
return [(x.get_title(session), x.value(object))
for x in cls.properties]
+
+class CuminActions(ActionSet):
+ def get_args(self, session):
+ return self.frame.get_args(session)
+
+ def do_get_items(self, session, object):
+ cls = self.app.model.get_class_by_object(object)
+ return [("", x.get_title(session)) for x in cls.actions]
+
+class CuminDetails(Widget):
+ def __init__(self, app, name):
+ super(CuminDetails, self).__init__(app, name)
+
+ props = CuminProperties(app, "properties")
+ self.add_child(props)
+
+ actions = CuminActions(app, "actions")
+ self.add_child(actions)
+
+ def render_title(self, session):
+ return "Details"
class StateSwitch(ItemSet):
def __init__(self, app, name):
Modified: mgmt/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/cumin/python/cumin/widgets.strings 2008-04-01 18:39:54 UTC (rev 1825)
+++ mgmt/cumin/python/cumin/widgets.strings 2008-04-01 18:40:50 UTC (rev 1826)
@@ -118,6 +118,28 @@
<!-- <div>{status_info}</div> -->
</div>
+[CuminDetails.css]
+table.CuminDetails {
+ width: 100%;
+}
+
+table.CuminDetails td {
+ width: 50%;
+ padding: 0.5em;
+}
+
+[CuminDetails.html]
+<table class="CuminDetails">
+ <tr>
+ <th>Properties</th>
+ <th>Actions</th>
+ </tr>
+ <tr>
+ <td>{properties}</td>
+ <td>{actions}</td>
+ </tr>
+</table>
+
[StateSwitch.html]
<ul class="radiotabs">
{items}
16 years, 10 months
rhmessaging commits: r1825 - mgmt/cumin/python/wooly.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 14:39:54 -0400 (Tue, 01 Apr 2008)
New Revision: 1825
Modified:
mgmt/cumin/python/wooly/widgets.strings
Log:
Add some styling for properties.
Modified: mgmt/cumin/python/wooly/widgets.strings
===================================================================
--- mgmt/cumin/python/wooly/widgets.strings 2008-04-01 18:18:44 UTC (rev 1824)
+++ mgmt/cumin/python/wooly/widgets.strings 2008-04-01 18:39:54 UTC (rev 1825)
@@ -131,11 +131,20 @@
[Paginator.page_html]
<li><a {class_attr} href="{href}">{content}</a></li>
+[PropertySet.css]
+table.PropertySet tr.prop th, table.PropertySet tr.prop td {
+ padding: 0.25em 1em 0.25em 0;
+}
+
+table.PropertySet th {
+ font-size: 0.9em;
+}
+
[PropertySet.html]
-<table>{items}</table>
+<table class="PropertySet">{items}</table>
[PropertySet.property_html]
-<tr><th>{title}</th><td>{value}</td></tr>
+<tr class="prop"><th>{title}</th><td>{value}</td></tr>
[ActionSet.html]
<ul>{items}</ul>
16 years, 10 months
rhmessaging commits: r1824 - in store/trunk/cpp/lib: jrnl and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-04-01 14:18:44 -0400 (Tue, 01 Apr 2008)
New Revision: 1824
Modified:
store/trunk/cpp/lib/BdbMessageStore.cpp
store/trunk/cpp/lib/JournalImpl.cpp
store/trunk/cpp/lib/JournalImpl.h
store/trunk/cpp/lib/jrnl/enums.hpp
store/trunk/cpp/lib/jrnl/jcfg.hpp
store/trunk/cpp/lib/jrnl/jcntl.cpp
store/trunk/cpp/lib/jrnl/jcntl.hpp
store/trunk/cpp/lib/jrnl/rcvdat.hpp
Log:
Added logging to journal. Logging is sent to qpid logging when used from class JournalImpl. Also extended upper limit on journal file size from 64MiB to 2GiB. Max files per journal remains unchnaged at 64.
Modified: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -130,22 +130,23 @@
numJrnlFiles = JRNL_MIN_NUM_FILES;
QPID_LOG(warning, "parameter num-jfiles (" << opts->numJrnlFiles << ") below allowable minimum (" << numJrnlFiles << "); changing this parameter to minimum value.");
}
- else if (numJrnlFiles > 64)
+ else if (numJrnlFiles > JRNL_MAX_NUM_FILES)
{
- numJrnlFiles = 64;
+ numJrnlFiles = JRNL_MAX_NUM_FILES;
QPID_LOG(warning, "parameter num-jfiles (" << opts->numJrnlFiles << ") above allowable maximum (" << numJrnlFiles << "); changing this parameter to maximum value.");
}
u_int32_t jrnlFsizePgs = opts->jrnlFsizePgs;
u_int32_t jrnlMinFsizePgs = JRNL_MIN_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
+ u_int32_t jrnlMaxFsizePgs = JRNL_MAX_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
if (jrnlFsizePgs < jrnlMinFsizePgs)
{
jrnlFsizePgs = jrnlMinFsizePgs;
QPID_LOG(warning, "parameter jfile-size-pgs (" << opts->jrnlFsizePgs << ") below allowable minimum (" << jrnlFsizePgs << "); changing this parameter to minimum value.");
}
- else if (jrnlFsizePgs > 1024) // (pgs) = 64MiB max file size
+ else if (jrnlFsizePgs > jrnlMaxFsizePgs)
{
- jrnlFsizePgs = 1024;
+ jrnlFsizePgs = jrnlMaxFsizePgs;
QPID_LOG(warning, "parameter jfile-size-pgs (" << opts->jrnlFsizePgs << ") above allowable maximum (" << jrnlFsizePgs << "); changing this parameter to maximum value.");
}
Modified: store/trunk/cpp/lib/JournalImpl.cpp
===================================================================
--- store/trunk/cpp/lib/JournalImpl.cpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/JournalImpl.cpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -28,6 +28,7 @@
#include "jrnl/slock.hpp"
#include "StoreException.h"
#include <qpid/sys/Monitor.h>
+#include <qpid/log/Statement.h>
using namespace rhm::bdbstore;
using namespace rhm::journal;
@@ -65,10 +66,25 @@
assert (journalTimerPtr != 0);
journalTimerPtr->start();
journalTimerPtr->add(inactivityFireEventPtr);
+
+ log(LOG_NOTICE, "Instantiation");
+ std::ostringstream oss1;
+ oss1 << "Journal directory = \"" << journalDirectory << "\"";
+ log(LOG_INFO, oss1.str());
+ std::ostringstream oss2;
+ oss2 << "Base file name = \"" << journalBaseFilename << "\"";
+ log(LOG_DEBUG, oss2.str());
+ std::ostringstream oss3;
+ oss3 << "Number of journal files = " << num_jfiles;
+ log(LOG_DEBUG, oss3.str());
+ std::ostringstream oss4;
+ oss4 << "Journal file size (sblks) = " << jfsize_sblks;
+ log(LOG_DEBUG, oss4.str());
}
JournalImpl::~JournalImpl()
{
+ log(LOG_DEBUG, "Destroyed");
if (_init_flag && !_stop_flag){
try { stop(true); }
catch (const jexception& e) { std::cerr << e << std::endl; }
@@ -86,10 +102,21 @@
}
void
-JournalImpl::recover(const journal::rd_aio_cb rd_cb, const wr_aio_cb wr_cb,
+JournalImpl::initialize(const journal::rd_aio_cb rd_cb, const journal::wr_aio_cb wr_cb)
+{
+ log(LOG_DEBUG, "Initialize");
+ jcntl::initialize(rd_cb, wr_cb);
+ log(LOG_DEBUG, "Initialization complete");
+}
+
+void
+JournalImpl::recover(const journal::rd_aio_cb rd_cb, const journal::wr_aio_cb wr_cb,
boost::ptr_list<bdbstore::PreparedTransaction>& prep_tx_list, u_int64_t& highest_rid,
u_int64_t queue_id)
{
+ std::ostringstream oss1;
+ oss1 << "Recover, queue_id = 0x" << std::hex << queue_id;
+ log(LOG_DEBUG, oss1.str());
// Create list of prepared xids
std::vector<std::string> prep_xid_list;
for (bdbstore::PreparedTransaction::list::iterator i = prep_tx_list.begin();
@@ -118,6 +145,9 @@
throw;
}
}
+ std::ostringstream oss2;
+ oss2 << "Recover complete; highest rid found = 0x" << std::hex << highest_rid;
+ log(LOG_DEBUG, oss2.str());
}
#define MAX_AIO_SLEEPS 500
@@ -249,6 +279,27 @@
}
void
+JournalImpl::log(journal::log_level ll, const std::string& log_stmt)
+{
+ log(ll, log_stmt.c_str());
+}
+
+void
+JournalImpl::log(journal::log_level ll, const char* const log_stmt)
+{
+ switch (ll)
+ {
+ case LOG_TRACE: QPID_LOG(trace, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_DEBUG: QPID_LOG(debug, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_INFO: QPID_LOG(info, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_NOTICE: QPID_LOG(notice, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_WARN: QPID_LOG(warning, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_ERROR: QPID_LOG(error, "Journal \"" << _jid << "\": " << log_stmt); break;
+ case LOG_CRITICAL: QPID_LOG(critical, "Journal \"" << _jid << "\": " << log_stmt); break;
+ }
+}
+
+void
JournalImpl::getEventsFire()
{
slock s(&_getf_mutex);
Modified: store/trunk/cpp/lib/JournalImpl.h
===================================================================
--- store/trunk/cpp/lib/JournalImpl.h 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/JournalImpl.h 2008-04-01 18:18:44 UTC (rev 1824)
@@ -95,6 +95,7 @@
inline void initialize() { jcntl::initialize(0, &aio_wr_callback); }
+ void initialize(const journal::rd_aio_cb rd_cb, const journal::wr_aio_cb wr_cb);
void recover(const journal::rd_aio_cb rd_cb, const journal::wr_aio_cb wr_cb,
boost::ptr_list<bdbstore::PreparedTransaction>& prep_tx_list,
u_int64_t& highest_rid, u_int64_t queue_id);
@@ -135,6 +136,10 @@
void stop(bool block_till_aio_cmpl = false);
+ // Logging
+ void log(journal::log_level level, const std::string& log_stmt);
+ void log(journal::log_level level, const char* const log_stmt);
+
// Overrides for get_events timer
const journal::iores flush(const bool block_till_aio_cmpl = false);
Modified: store/trunk/cpp/lib/jrnl/enums.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/enums.hpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/jrnl/enums.hpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -74,6 +74,34 @@
return "<iores unknown>";
}
+ enum _log_level
+ {
+ LOG_TRACE = 0,
+ LOG_DEBUG,
+ LOG_INFO,
+ LOG_NOTICE,
+ LOG_WARN,
+ LOG_ERROR,
+ LOG_CRITICAL
+ };
+ typedef _log_level log_level;
+
+ static inline const char* log_level_str(log_level ll)
+ {
+ switch (ll)
+ {
+ case LOG_TRACE: return "TRACE";
+ case LOG_DEBUG: return "DEBUG";
+ case LOG_INFO: return "INFO";
+ case LOG_NOTICE: return "NOTICE";
+ case LOG_WARN: return "WARN";
+ case LOG_ERROR: return "ERROR";
+ case LOG_CRITICAL: return "CRITICAL";
+ }
+ return "<log level unknown>";
+ }
+
+
} // namespace journal
} // namespace rhm
Modified: store/trunk/cpp/lib/jrnl/jcfg.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcfg.hpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/jrnl/jcfg.hpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -60,7 +60,9 @@
#define JRNL_DBLK_SIZE 128 ///< Data block size in bytes (CANNOT BE LESS THAN 32!)
#define JRNL_SBLK_SIZE 4 ///< Disk softblock size in multiples of JRNL_DBLK_SIZE
#define JRNL_MIN_FILE_SIZE 128 ///< Min. jrnl file size in sblks (excl. file_hdr)
+#define JRNL_MAX_FILE_SIZE 4194304 ///< Max. jrnl file size in sblks (excl. file_hdr)
#define JRNL_MIN_NUM_FILES 4 ///< Min. number of journal files
+#define JRNL_MAX_NUM_FILES 64 ///< Max. number of journal files
#define JRNL_ENQ_THRESHOLD 80 ///< Percent full when enqueue connection will be closed
// NOTE: JRNL_RMGR_PAGE_SIZE must be a multiple of JRNL_WMGR_PAGE_SIZE.
Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -153,8 +153,7 @@
if (_rcvdat._full)
throw jexception(jerrno::JERR_JCNTL_RECOVERJFULL, "jcntl", "recover");
- // Debug info; should be sent to log file
- // std::cout << _rcvdat.to_string(_jid) << std::endl << std::flush;
+ this->log(LOG_DEBUG, _rcvdat.to_string(_jid));
// TODO - place this in a finalize() fn? - see ~jcntl() & initialize()...
if (_datafh)
@@ -405,6 +404,21 @@
}
void
+jcntl::log(log_level ll, const std::string& log_stmt)
+{
+ log(ll, log_stmt.c_str());
+}
+
+void
+jcntl::log(log_level ll, const char* const log_stmt)
+{
+ if (ll > LOG_INFO)
+ {
+ std::cout << log_level_str(ll) << ": Journal \"" << _jid << "\": " << log_stmt << std::endl;
+ }
+}
+
+void
jcntl::chk_wr_frot()
{
if (_wrfc.index() == _rrfc.index())
@@ -476,8 +490,10 @@
_wmgr.get_events(pmgr::UNUSED);
if (cnt++ > MAX_AIO_CMPL_SLEEPS)
{
- // TODO: Log this!
- std::cout << "**** JERR_JCNTL_AIOCMPLWAIT *** " << _wmgr.status_str() << std::endl;
+ std::ostringstream oss;
+ oss << "get_events() returned JERR_JCNTL_AIOCMPLWAIT; wmgr_status: ";
+ oss << _wmgr.status_str();
+ this->log(LOG_CRITICAL, oss.str());
throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "handle_aio_wait");
}
::usleep(AIO_CMPL_SLEEP);
@@ -491,8 +507,10 @@
_wmgr.get_events(pmgr::UNUSED);
if (cnt++ > MAX_AIO_CMPL_SLEEPS)
{
- // TODO: Log this!
- std::cout << "**** JERR_JCNTL_AIOCMPLWAIT *** " << _wmgr.status_str() << std::endl;
+ std::ostringstream oss;
+ oss << "get_events() returned JERR_JCNTL_AIOCMPLWAIT; wmgr_status: ";
+ oss << _wmgr.status_str();
+ this->log(LOG_CRITICAL, oss.str());
throw jexception(jerrno::JERR_JCNTL_AIOCMPLWAIT, "jcntl", "handle_aio_wait");
}
::usleep(AIO_CMPL_SLEEP);
@@ -515,17 +533,21 @@
// use the jinf data.
if (_num_jfiles != ji.num_jfiles())
{
+ std::ostringstream oss;
+ oss << "Recovery found " << ji.num_jfiles() <<
+ " files (different from --num-jfiles value of " << _num_jfiles << ").";
+ this->log(LOG_WARN, oss.str());
_num_jfiles = ji.num_jfiles();
_rcvdat._enq_cnt_list.resize(_num_jfiles);
- std::cout << "WARNING: Recovery found " << _num_jfiles <<
- " files (different from --num-jfiles parameter value)." << std::endl;
}
if (_jfsize_sblks != ji.jfsize_sblks())
{
+ std::ostringstream oss;
+ oss << "Recovery found file size = " << (ji.jfsize_sblks() / JRNL_RMGR_PAGE_SIZE) <<
+ " (different from --jfile-size-pgs value of " <<
+ (_jfsize_sblks / JRNL_RMGR_PAGE_SIZE) << ").";
+ this->log(LOG_WARN, oss.str());
_jfsize_sblks = ji.jfsize_sblks();
- std::cout << "WARNING: Recovery found file size = " <<
- (_jfsize_sblks / JRNL_RMGR_PAGE_SIZE) <<
- " (different from --jfile-size-pgs parameter value)." << std::endl;
}
try
@@ -831,11 +853,13 @@
unsigned sblk_offs = file_pos % (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE);
if (sblk_offs)
{
- // TODO: Connect the following with logger:
- std::cout << std::hex << "INFO: " << _jid << ": Bad record alignment found at fid=0x" <<
- fid << " offs=0x" << file_pos << " (likely journal overwrite boundary); " <<
- (JRNL_SBLK_SIZE - (sblk_offs/JRNL_DBLK_SIZE)) <<
- " filler record(s) required." << std::endl;
+ {
+ std::ostringstream oss;
+ oss << std::hex << "Bad record alignment found at fid=0x" << fid;
+ oss << " offs=0x" << file_pos << " (likely journal overwrite boundary); " << std::dec;
+ oss << (JRNL_SBLK_SIZE - (sblk_offs/JRNL_DBLK_SIZE)) << " filler record(s) required.";
+ this->log(LOG_WARN, oss.str());
+ }
const u_int32_t xmagic = RHM_JDAT_EMPTY_MAGIC;
std::ostringstream oss;
oss << _jdir.dirname() << "/" << _base_filename << ".";
@@ -857,14 +881,14 @@
{
ofsp.write((const char*)buff, JRNL_DBLK_SIZE);
assert(!ofsp.fail());
- // TODO: Connect the following with logger:
- std::cout << "INFO: * Wrote filler record at offs=0x" << file_pos << std::endl;
+ std::ostringstream oss;
+ oss << "Wrote filler record at offs=0x" << std::hex << file_pos << std::dec;
+ this->log(LOG_NOTICE, oss.str());
file_pos = ofsp.tellp();
}
ofsp.close();
::free(buff);
- // TODO: Connect the following with logger:
- std::cout << "INFO: Bad record alignment fixed." << std::endl;
+ this->log(LOG_INFO, "Bad record alignment fixed.");
}
}
Modified: store/trunk/cpp/lib/jrnl/jcntl.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.hpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/jrnl/jcntl.hpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -586,6 +586,10 @@
inline const u_int32_t jfsize_sblks() const { return _jfsize_sblks; }
+ // Logging
+ virtual void log(log_level level, const std::string& log_stmt);
+ virtual void log(log_level level, const char* const log_stmt);
+
// these are _rmgr to _wmgr interactions, remove when _rmgr contains ref to _wmgr:
void chk_wr_frot();
inline const u_int32_t unflushed_dblks() { return _wmgr.unflushed_dblks(); }
Modified: store/trunk/cpp/lib/jrnl/rcvdat.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rcvdat.hpp 2008-04-01 18:00:57 UTC (rev 1823)
+++ store/trunk/cpp/lib/jrnl/rcvdat.hpp 2008-04-01 18:18:44 UTC (rev 1824)
@@ -87,7 +87,7 @@
std::string to_string(std::string& jid)
{
std::ostringstream oss;
- oss << "Jorunal file analysis (jid=\"" << jid << "\"):" << std::endl;
+ oss << "Recover file analysis (jid=\"" << jid << "\"):" << std::endl;
oss << " Overwrite indicator (_owi) = " << (_owi ? "TRUE" : "FALSE") << std::endl;
oss << " First rotation (_frot) = " << (_frot ? "TRUE" : "FALSE") << std::endl;
oss << " Journal empty (_empty) = " << (_empty ? "TRUE" : "FALSE") << std::endl;
16 years, 10 months
rhmessaging commits: r1823 - store/trunk/cpp/etc.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2008-04-01 14:00:57 -0400 (Tue, 01 Apr 2008)
New Revision: 1823
Modified:
store/trunk/cpp/etc/rhmd
Log:
BZ 430049: rhmd init script loads sysconfig for qpidd; also, make rhmd run under user qpidd, not root
Modified: store/trunk/cpp/etc/rhmd
===================================================================
--- store/trunk/cpp/etc/rhmd 2008-04-01 17:27:14 UTC (rev 1822)
+++ store/trunk/cpp/etc/rhmd 2008-04-01 18:00:57 UTC (rev 1823)
@@ -23,15 +23,15 @@
# Source function library.
. /etc/rc.d/init.d/functions
-if [ -f /etc/sysconfig/$prog ] ; then
- . /etc/sysconfig/$prog
+if [ -f /etc/sysconfig/rhmd ] ; then
+ . /etc/sysconfig/rhmd
fi
RETVAL=0
start() {
echo -n $"Starting RHM daemon: "
- $prog --daemon --config=/etc/rhmd.conf
+ daemon --check $prog "runuser -s /bin/sh qpidd -c \"$prog --daemon --config=/etc/rhmd.conf\""
RETVAL=$?
if [ $RETVAL = 0 ] ; then success ; else failure ; fi
echo
16 years, 10 months
rhmessaging commits: r1822 - mgmt/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 13:27:14 -0400 (Tue, 01 Apr 2008)
New Revision: 1822
Modified:
mgmt/cumin/python/cumin/model.py
Log:
Introduce two base classes for cumin metadata: LocalClass and
RemoteClass. The former is for classes such as BrokerRegistration
which are purely cumin-local. The latter is for all the managment
types in the cloud.
Modified: mgmt/cumin/python/cumin/model.py
===================================================================
--- mgmt/cumin/python/cumin/model.py 2008-04-01 17:11:41 UTC (rev 1821)
+++ mgmt/cumin/python/cumin/model.py 2008-04-01 17:27:14 UTC (rev 1822)
@@ -276,36 +276,15 @@
% (self.name, value, rate))
class CuminClass(object):
- def __init__(self, model, name, mint_class, mint_stats_class):
+ def __init__(self, model, name, mint_class):
self.model = model
self.name = name
self.mint_class = mint_class
- self.mint_stats_class = mint_stats_class
self.properties = list()
self.stats = list()
self.actions = list()
- prop = CuminProperty(self, "idOriginal")
- prop.title = "Management ID"
- prop.categories = ("basic",)
-
- prop = CuminProperty(self, "creationTime")
- prop.title = "Creation Time"
- prop.categories = ("basic",)
-
- prop = CuminProperty(self, "deletionTime")
- prop.title = "Deletion Time"
- prop.categories = ("basic",)
-
- prop = CuminProperty(self, "recTime")
- prop.title = "Last Updated"
- prop.categories = ("basic",)
-
- self.Add(self, "add")
- self.Edit(self, "edit")
- self.Remove(self, "remove")
-
self.model.add_class(self)
def add_property(self, prop):
@@ -353,6 +332,36 @@
writer.write("</%s>" % self.name)
+class RemoteClass(CuminClass):
+ def __init__(self, model, name, mint_class, mint_stats_class):
+ super(RemoteClass, self).__init__(model, name, mint_class)
+
+ self.mint_stats_class = mint_stats_class
+
+ prop = CuminProperty(self, "idOriginal")
+ prop.title = "Management ID"
+ prop.categories = ("basic",)
+
+ prop = CuminProperty(self, "creationTime")
+ prop.title = "Creation Time"
+ prop.categories = ("basic",)
+
+ prop = CuminProperty(self, "deletionTime")
+ prop.title = "Deletion Time"
+ prop.categories = ("basic",)
+
+ prop = CuminProperty(self, "recTime")
+ prop.title = "Last Updated"
+ prop.categories = ("basic",)
+
+class LocalClass(CuminClass):
+ def __init__(self, model, name, mint_class):
+ super(LocalClass, self).__init__(model, name, mint_class)
+
+ self.Add(self, "add")
+ self.Edit(self, "edit")
+ self.Remove(self, "remove")
+
class Add(CuminAction):
def get_title(self, session):
return "Add"
@@ -395,7 +404,7 @@
except Exception, e:
completion(e.message or "failed")
-class CuminSystem(CuminClass):
+class CuminSystem(RemoteClass):
def __init__(self, model):
super(CuminSystem, self).__init__(model, "system", System, SystemStats)
@@ -417,7 +426,7 @@
prop = CuminProperty(self, "machine")
prop.title = "Architecture"
-class CuminBroker(CuminClass):
+class CuminBroker(RemoteClass):
def __init__(self, model):
super(CuminBroker, self).__init__(model, "broker", Broker, BrokerStats)
@@ -425,7 +434,7 @@
frame = self.model.app.main_page.show_main(session)
return frame.show_broker(session, broker)
-class CuminQueue(CuminClass):
+class CuminQueue(RemoteClass):
def __init__(self, model):
super(CuminQueue, self).__init__(model, "queue", Queue, QueueStats)
@@ -612,7 +621,7 @@
def do_invoke(self, object, args, completion):
object.purge(self.model.data, completion)
-class CuminExchange(CuminClass):
+class CuminExchange(RemoteClass):
def __init__(self, model):
super(CuminExchange, self).__init__(model, "exchange",
Exchange, ExchangeStats)
@@ -662,7 +671,7 @@
def get_title(self, session):
return "Exchange"
-class CuminBinding(CuminClass):
+class CuminBinding(RemoteClass):
def __init__(self, model):
super(CuminBinding, self).__init__(model, "binding",
Binding, BindingStats)
@@ -678,7 +687,7 @@
def get_object_name(self, binding):
return ""
-class CuminClient(CuminClass):
+class CuminClient(RemoteClass):
def __init__(self, model):
super(CuminClient, self).__init__(model, "client", Client, ClientStats)
@@ -721,7 +730,7 @@
def do_invoke(self, object, args, completion):
object.close(self.model.data, completion)
-class CuminSession(CuminClass):
+class CuminSession(RemoteClass):
def __init__(self, model):
super(CuminSession, self).__init__(model, "session",
Session, SessionStats)
@@ -775,7 +784,7 @@
def do_invoke(self, object, args, completion):
object.solicitAck(self.model.data, completion)
-class CuminLink(CuminClass):
+class CuminLink(RemoteClass):
def __init__(self, model):
super(CuminLink, self).__init__(model, "link", Link, LinkStats)
@@ -806,18 +815,18 @@
def get_title(self, session):
return "Broker Link"
-class CuminBrokerRegistration(CuminClass):
+class CuminBrokerRegistration(LocalClass):
def __init__(self, model):
super(CuminBrokerRegistration, self).__init__ \
- (model, "broker_registration", BrokerRegistration, None)
+ (model, "broker_registration", BrokerRegistration)
def get_title(self, session):
return "Broker Registration"
-class CuminBrokerGroup(CuminClass):
+class CuminBrokerGroup(LocalClass):
def __init__(self, model):
super(CuminBrokerGroup, self).__init__ \
- (model, "broker_group", BrokerGroup, None)
+ (model, "broker_group", BrokerGroup)
def show(self, session, group):
frame = self.model.app.main_page.show_main(session)
16 years, 10 months
rhmessaging commits: r1821 - mgmt/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 13:11:41 -0400 (Tue, 01 Apr 2008)
New Revision: 1821
Modified:
mgmt/cumin/python/cumin/model.py
mgmt/cumin/python/cumin/widgets.py
Log:
Add categories and a get_title method to CuminProperty.
Add all system properties to CuminSystem.
Modified: mgmt/cumin/python/cumin/model.py
===================================================================
--- mgmt/cumin/python/cumin/model.py 2008-04-01 15:50:22 UTC (rev 1820)
+++ mgmt/cumin/python/cumin/model.py 2008-04-01 17:11:41 UTC (rev 1821)
@@ -83,12 +83,28 @@
self.model = cls.model
self.cumin_class = cls
self.name = name
+ self.title = None
+ self.categories = ()
self.cumin_class.add_property(self)
- def get(self, object):
- return getattr(object, self.name, None)
+ def get_title(self, session):
+ if self.title:
+ return self.title
+ else:
+ return self.name
+ def value(self, object):
+ value = getattr(object, self.name, None)
+
+ if isinstance(value, datetime):
+ value = fmt_datetime(value)
+
+ if value is None:
+ value = fmt_none()
+
+ return value
+
class CuminAction(object):
def __init__(self, cls, name):
self.model = cls.model
@@ -270,11 +286,22 @@
self.stats = list()
self.actions = list()
- CuminProperty(self, "idOriginal")
- CuminProperty(self, "recTime")
- CuminProperty(self, "creationTime")
- CuminProperty(self, "deletionTime")
+ prop = CuminProperty(self, "idOriginal")
+ prop.title = "Management ID"
+ prop.categories = ("basic",)
+ prop = CuminProperty(self, "creationTime")
+ prop.title = "Creation Time"
+ prop.categories = ("basic",)
+
+ prop = CuminProperty(self, "deletionTime")
+ prop.title = "Deletion Time"
+ prop.categories = ("basic",)
+
+ prop = CuminProperty(self, "recTime")
+ prop.title = "Last Updated"
+ prop.categories = ("basic",)
+
self.Add(self, "add")
self.Edit(self, "edit")
self.Remove(self, "remove")
@@ -372,6 +399,24 @@
def __init__(self, model):
super(CuminSystem, self).__init__(model, "system", System, SystemStats)
+ prop = CuminProperty(self, "sysId")
+ prop.title = "System ID"
+
+ prop = CuminProperty(self, "nodeName")
+ prop.title = "Address"
+
+ prop = CuminProperty(self, "osName")
+ prop.title = "Kernel"
+
+ prop = CuminProperty(self, "release")
+ prop.title = "Kernel Release"
+
+ prop = CuminProperty(self, "version")
+ prop.title = "Kernel Version"
+
+ prop = CuminProperty(self, "machine")
+ prop.title = "Architecture"
+
class CuminBroker(CuminClass):
def __init__(self, model):
super(CuminBroker, self).__init__(model, "broker", Broker, BrokerStats)
Modified: mgmt/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/cumin/python/cumin/widgets.py 2008-04-01 15:50:22 UTC (rev 1820)
+++ mgmt/cumin/python/cumin/widgets.py 2008-04-01 17:11:41 UTC (rev 1821)
@@ -231,6 +231,15 @@
return "%i error%s, %i warning%s" % \
(error_count, ess(error_count),
warning_count, ess(warning_count))
+
+class CuminProperties(PropertySet):
+ def get_args(self, session):
+ return self.frame.get_args(session)
+
+ def do_get_items(self, session, object):
+ cls = self.app.model.get_class_by_object(object)
+ return [(x.get_title(session), x.value(object))
+ for x in cls.properties]
class StateSwitch(ItemSet):
def __init__(self, app, name):
16 years, 10 months
rhmessaging commits: r1820 - mgmt/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 11:50:22 -0400 (Tue, 01 Apr 2008)
New Revision: 1820
Modified:
mgmt/cumin/python/cumin/model.py
Log:
Introduce system ui metadata.
Add CuminProperty and a default set of properties present for every
CuminClass type.
Modified: mgmt/cumin/python/cumin/model.py
===================================================================
--- mgmt/cumin/python/cumin/model.py 2008-04-01 15:47:34 UTC (rev 1819)
+++ mgmt/cumin/python/cumin/model.py 2008-04-01 15:50:22 UTC (rev 1820)
@@ -18,6 +18,7 @@
self.classes = list()
self.invocations = set()
+ CuminSystem(self)
CuminBroker(self)
CuminQueue(self)
CuminExchange(self)
@@ -77,6 +78,17 @@
writer.write("</model>")
+class CuminProperty(object):
+ def __init__(self, cls, name):
+ self.model = cls.model
+ self.cumin_class = cls
+ self.name = name
+
+ self.cumin_class.add_property(self)
+
+ def get(self, object):
+ return getattr(object, self.name, None)
+
class CuminAction(object):
def __init__(self, cls, name):
self.model = cls.model
@@ -253,15 +265,25 @@
self.name = name
self.mint_class = mint_class
self.mint_stats_class = mint_stats_class
-
+
+ self.properties = list()
self.stats = list()
self.actions = list()
+ CuminProperty(self, "idOriginal")
+ CuminProperty(self, "recTime")
+ CuminProperty(self, "creationTime")
+ CuminProperty(self, "deletionTime")
+
self.Add(self, "add")
self.Edit(self, "edit")
self.Remove(self, "remove")
self.model.add_class(self)
+
+ def add_property(self, prop):
+ self.properties.append(prop)
+ setattr(self, prop.name, prop)
def add_stat(self, stat):
self.stats.append(stat)
@@ -346,6 +368,10 @@
except Exception, e:
completion(e.message or "failed")
+class CuminSystem(CuminClass):
+ def __init__(self, model):
+ super(CuminSystem, self).__init__(model, "system", System, SystemStats)
+
class CuminBroker(CuminClass):
def __init__(self, model):
super(CuminBroker, self).__init__(model, "broker", Broker, BrokerStats)
16 years, 10 months
rhmessaging commits: r1819 - mgmt/cumin/python/wooly.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-04-01 11:47:34 -0400 (Tue, 01 Apr 2008)
New Revision: 1819
Modified:
mgmt/cumin/python/wooly/widgets.py
mgmt/cumin/python/wooly/widgets.strings
Log:
Introduces a new kind of ItemSet, RenderingItemSet, which uses an
ItemRenderer to generate each item's output. The default
implementation uses a template, as before.
Eventually RenderingItemSet will replace ItemSet altogether.
Modify Paginator to use the new item set class.
Introduce PropertySet and ActionSet.
Modified: mgmt/cumin/python/wooly/widgets.py
===================================================================
--- mgmt/cumin/python/wooly/widgets.py 2008-04-01 15:44:42 UTC (rev 1818)
+++ mgmt/cumin/python/wooly/widgets.py 2008-04-01 15:47:34 UTC (rev 1819)
@@ -183,6 +183,61 @@
return None
+class RenderingItemSet(Widget):
+ def __init__(self, app, name, item_renderer):
+ super(RenderingItemSet, self).__init__(app, name)
+
+ self.item_renderer = item_renderer
+
+ self.items = Attribute(app, "items")
+ self.add_attribute(self.items)
+
+ def get_item_count(self, session, *args):
+ return len(self.get_items(session, *args))
+
+ def get_items(self, session, *args):
+ items = self.items.get(session)
+
+ if items is None:
+ items = self.do_get_items(session, *args)
+
+ if items is None:
+ items = ()
+
+ return items
+
+ def do_get_items(self, session, *args):
+ pass
+
+ def render_items(self, session, *args):
+ items = self.get_items(session, *args)
+ writer = Writer()
+
+ for item in items:
+ self.item_renderer.render(writer, session, item)
+
+ return writer.to_string()
+
+class ItemRenderer(object):
+ def __init__(self, widget):
+ self.widget = widget
+
+ def render_content(self, session, item):
+ return item
+
+ def render(self, writer, session, item):
+ return self.render_content(session, item)
+
+class TemplateRenderer(ItemRenderer):
+ def __init__(self, widget, template_key):
+ super(TemplateRenderer, self).__init__(widget)
+
+ text = self.widget.get_string(template_key)
+ self.__tmpl = ObjectBoundTemplate(self, text)
+
+ def render(self, writer, session, item):
+ self.__tmpl.render(writer, session, item)
+
class ItemTree(ItemSet):
def get_items(self, session, *args):
"""Get the root items"""
@@ -195,41 +250,42 @@
writer = Writer()
for child in self.get_child_items(session, *args):
- self.item_tmpl.render(writer, session, child)
+ self.item_renderer.render(writer, session, child)
return writer.to_string()
-class Paginator(ItemSet):
+class Paginator(RenderingItemSet):
def __init__(self, app, name):
- super(Paginator, self).__init__(app, name)
+ renderer = self.PageLink(self, "page_html")
+ super(Paginator, self).__init__(app, name, renderer)
- self.__page = IntegerParameter(app, "page")
- self.__page.default = 0
- self.add_parameter(self.__page)
+ self.page_index = IntegerParameter(app, "page")
+ self.page_index.default = 0
+ self.add_parameter(self.page_index)
- self.__pageset = IntegerParameter(app, "pageset")
- self.__pageset.default = 0
- self.add_parameter(self.__pageset)
+ self.pageset_index = IntegerParameter(app, "pageset")
+ self.pageset_index.default = 0
+ self.add_parameter(self.pageset_index)
- self.__count = Attribute(app, "count")
- self.add_attribute(self.__count)
+ self.page_count = Attribute(app, "count")
+ self.add_attribute(self.page_count)
self.page_size = 15
self.pageset_size = 5
def get_bounds(self, session):
- page = self.__page.get(session)
+ page = self.page_index.get(session)
return self.page_size * page, self.page_size * (page + 1)
def get_pageset_bounds(self, session):
- pageset = self.__pageset.get(session)
+ pageset = self.pageset_index.get(session)
return self.pageset_size * pageset, self.pageset_size * (pageset + 1)
def set_count(self, session, count):
- return self.__count.set(session, count)
+ return self.page_count.set(session, count)
def get_count(self, session):
- return self.__count.get(session)
+ return self.page_count.get(session)
def get_page_count(self, session):
count = self.get_count(session)
@@ -244,7 +300,7 @@
(href, class_ and " class=\"%s\" " % class_ or " ", content)
def render_prev_page_link(self, session, *args):
- page = self.__page.get(session)
+ page = self.page_index.get(session)
if page < 1:
html = self.__link(session.marshal(), "<", "pagenav disabled")
@@ -253,15 +309,16 @@
pageset_start = self.get_pageset_bounds(session)[0]
branch = session.branch()
- self.__page.set(branch, page)
+ self.page_index.set(branch, page)
if page < pageset_start:
- self.__pageset.set(branch, self.__pageset.get(session) - 1)
+ nindex = self.pageset_index.get(session) - 1
+ self.pageset_index.set(branch, nindex)
html = self.__link(branch.marshal(), "<", "pagenav")
return html
def render_next_page_link(self, session, *args):
- page = self.__page.get(session)
+ page = self.page_index.get(session)
if page >= self.get_page_count(session) - 1:
html = self.__link(session.marshal(), ">", "pagenav disabled")
@@ -270,53 +327,83 @@
pageset_end = self.get_pageset_bounds(session)[1]
branch = session.branch()
- self.__page.set(branch, page)
+ self.page_index.set(branch, page)
if page >= pageset_end: # XXX should be >? bounds func is funny
- self.__pageset.set(branch, self.__pageset.get(session) + 1)
+ nindex = self.pageset_index.get(session) + 1
+ self.pageset_index.set(branch, nindex)
html = self.__link(branch.marshal(), ">", "pagenav")
return html
def render_prev_pageset_link(self, session, *args):
- pageset = self.__pageset.get(session)
+ pageset = self.pageset_index.get(session)
if pageset < 1:
html = self.__link(session.marshal(), "<<", "pagenav disabled")
else:
branch = session.branch()
- self.__pageset.set(branch, pageset - 1)
+ self.pageset_index.set(branch, pageset - 1)
html = self.__link(branch.marshal(), "<<", "pagenav")
return html
def render_next_pageset_link(self, session, *args):
- pageset = self.__pageset.get(session)
+ pageset = self.pageset_index.get(session)
if pageset >= self.get_pageset_count(session) - 1:
html = self.__link(session.marshal(), ">>", "pagenav disabled")
else:
branch = session.branch()
- self.__pageset.set(branch, pageset + 1)
+ self.pageset_index.set(branch, pageset + 1)
html = self.__link(branch.marshal(), ">>", "pagenav")
return html
def do_get_items(self, session, *args):
- count = self.__count.get(session)
+ count = self.page_count.get(session)
start, end = self.get_pageset_bounds(session)
page_count = self.get_page_count(session)
return range(start, min(end, page_count))
- def render_item_class_attr(self, session, page):
- if self.__page.get(session) == page:
- return " class=\"selected\""
-
- def render_item_href(self, session, page):
- branch = session.branch()
- self.__page.set(branch, page)
- return branch.marshal()
+ class PageLink(TemplateRenderer):
+ def render_class_attr(self, session, page):
+ if self.widget.page_index.get(session) == page:
+ return " class=\"selected\""
+
+ def render_href(self, session, page):
+ branch = session.branch()
+ self.widget.page_index.set(branch, page)
+ return branch.marshal()
- def render_item_content(self, session, page):
- return page + 1
+ def render_content(self, session, page):
+ return page + 1
+
+class PropertySet(RenderingItemSet):
+ def __init__(self, app, name, item_renderer=None):
+ super(PropertySet, self).__init__(app, name, item_renderer)
+
+ if self.item_renderer is None:
+ self.item_renderer = PropertyRenderer(self, "property_html")
+
+class PropertyRenderer(TemplateRenderer):
+ def render_title(self, session, prop):
+ return prop[0]
+
+ def render_value(self, session, prop):
+ return prop[1]
+
+class ActionSet(RenderingItemSet):
+ def __init__(self, app, name, item_renderer=None):
+ super(ActionSet, self).__init__(app, name, item_renderer)
+
+ if self.item_renderer is None:
+ self.item_renderer = ActionRenderer(self, "action_html")
+
+class ActionRenderer(TemplateRenderer):
+ def render_href(self, session, action):
+ return action[0]
+
+ def render_content(self, session, action):
+ return action[1]
Modified: mgmt/cumin/python/wooly/widgets.strings
===================================================================
--- mgmt/cumin/python/wooly/widgets.strings 2008-04-01 15:44:42 UTC (rev 1818)
+++ mgmt/cumin/python/wooly/widgets.strings 2008-04-01 15:47:34 UTC (rev 1819)
@@ -128,5 +128,17 @@
<li>{prev_pageset_link}</li><li>{prev_page_link}</li>{items}<li>{next_page_link}</li><li>{next_pageset_link}</li>
</ul>
-[Paginator.item_html]
-<li><a {item_class_attr} href="{item_href}">{item_content}</a></li>
+[Paginator.page_html]
+<li><a {class_attr} href="{href}">{content}</a></li>
+
+[PropertySet.html]
+<table>{items}</table>
+
+[PropertySet.property_html]
+<tr><th>{title}</th><td>{value}</td></tr>
+
+[ActionSet.html]
+<ul>{items}</ul>
+
+[ActionSet.action_html]
+<li><a href="{href}">{content}</a></li>
16 years, 10 months