всевозможный код
IDL интерфейс сервера:
#ifndef GF_LOGGING_SERVICE_IDL
#define GF_LOGGING_SERVICE_IDL
#include
#pragma prefix "goodoo.ru"
module GoodooFacilities
{
typedef CosNaming::Name Key;
typedef CosLifeCycle::Criteria Criteria;
typedef long TimeStamp;
enum EventSeverity
{
SEVERITY_SHOWSTOPPER,
SEVERITY_ERROR,
SEVERITY_WARNING,
SEVERITY_INFO,
SEVERITY_DEBUG,
SEVERITY_TRACE
};
interface Event
{
readonly attribute TimeStamp eventTime;
attribute EventSeverity severity;
readonly attribute string message;
void handle();
};
exception InvalidEventKey
{
Key eventKey;
};
interface EventLoggingService
{
oneway void logAnyEvent(in Key eventKey, in Criteria eventCriteria);
oneway void logEvent(in Event aEvent);
};
};
#endif
тестируемые функции:
на стороне CORBA-сервера (тупо срем в cerr):
void GoodooFacilities_EventLoggingService_i::logAnyEvent (
const ::GoodooFacilities::Key & eventKey,
const ::GoodooFacilities::Criteria & eventCriteria
)
ACE_THROW_SPEC ((
CORBA::SystemException
))
{
// Add your implementation here
// eventCriteria.
cerr << "Got event! :)" << endl;
long keysNo = eventKey.length();
cerr << "Key: " << endl;
for (int i = 0; i < keysNo; i++) {
cerr << "[" << i << "]: " << eventKey[i].id.in() << " = " << eventKey[i].kind.in() << endl;
}
keysNo = eventCriteria.length();
cerr << "Criteria:" << endl;
for (int i = 0; i < keysNo; i++) {
string criteriaName( eventCriteria[i].name );
cerr << "[" << i << "] " << criteriaName << " = " ;
const char* buff;
CORBA::Long longValue;
CORBA::Double doubleValue;
if ( eventCriteria[i].value >>= buff ) {
cerr << buff;
} else if ( eventCriteria[i].value >>= longValue ) {
cerr << longValue;
} else if ( eventCriteria[i].value >>= doubleValue ) {
cerr << doubleValue;
}
cerr << endl;
}
}
XS
bool logEvent(HV* key, HV* criteria)
{
try {
long keyNo = hv_iterinit(key);
GoodooFacilities::Key eventKey(keyNo);
eventKey.length(keyNo);
HE* hashEntry = hv_iternext( key );
for (int i = 0; i < keyNo; i++) {
long keyLength = 0;
string hashKey = hv_iterkey(hashEntry, &keyLength);
string hashValue;
SV* hashValueSV = hv_iterval(key, hashEntry);
if ( SvOK(hashValueSV) && SvPOK(hashValueSV) ) {
hashValue = SvPV(hashValueSV, PL_na);
} else {
cerr << "Event key hash entry [" << i << "] ({" << hashKey << "})has invalid value type" << endl;
}
// cerr << "Event key hash entry [" << i << "]: " << hashKey << " = " << hashValue << endl;
eventKey[i].id = CORBA::string_dup( hashKey.c_str() );
eventKey[i].kind = CORBA::string_dup( hashValue.c_str() );
hashEntry = hv_iternext( key );
}
keyNo = hv_iterinit(criteria);
GoodooFacilities::Criteria eventCriteria(keyNo);
eventCriteria.length(keyNo);
hashEntry = hv_iternext( criteria );
for ( int i = 0; i < keyNo; i++ ) {
long keyLength = 0;
string hashKey = hv_iterkey(hashEntry, &keyLength);
eventCriteria[i].name = CORBA::string_dup( hashKey.c_str() );
SV* hashValueSV = hv_iterval(key, hashEntry);
if ( SvOK(hashValueSV) ) {
if ( SvPOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is a string" << endl;
eventCriteria[i].value <<= CORBA::string_dup( SvPV(hashValueSV, PL_na) );
} else if ( SvIOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is an integer" << endl;
long value = SvIV(hashValueSV);
eventCriteria[i].value <<= static_cast(value);
} else if ( SvNOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is a double" << endl;
double value = SvNV(hashValueSV);
eventCriteria[i].value <<= static_cast(value);
}
}
//eventCriteria[i].value <<= CORBA::string_dup("авотхуй");
hashEntry = hv_iternext( criteria );
}
logging_service->logAnyEvent(eventKey, eventCriteria);
}
catch( CORBA::Exception &ex ) {
cerr << "CORBA exception caught!" << endl;
return false;
}
return true;
}
Код бенчмарка:
use Benchmark qw(:all :hireswallclock);
use GoodooFacilities::LoggingService;
my $ior = 'corbaloc::localhost:12345/LoggingService';
GoodooFacilities::LoggingService::initialize($ior)
my $count = 100000;
diag("starting benchmark");
my $t = timeit( $count, sub { logEvent( { Event => 'Message', Namespace => 'Metro2033' },
{ message => 'blablabla', severity => 0, PI => 3.14 } ) } );
diag("benchmark finished");
diag( "$count loops of event sending took: ". timestr($t));
GoodooFacilities::LoggingService::cleanup();
Условия
вызовы локальные, через stub/skeleton, без DII. завтра протестирую по сети.
OS - Debian 2.6.18-3-686
ORB - ACE+TAO 5.4.7-12
perl 5.8.8
Сервер - однопоточный в консоли. Клиент тоже :)
Результаты 5 прогонов бенчмарка
# 100000 loops of event sending took: 34.5186 wallclock secs ( 4.58 usr + 0.30 sys = 4.88 CPU) @ 20491.80/s (n=100000)
# 100000 loops of event sending took: 99.3214 wallclock secs ( 5.10 usr + 0.24 sys = 5.34 CPU) @ 18726.59/s (n=100000)
# 100000 loops of event sending took: 37.9359 wallclock secs ( 4.76 usr + 0.23 sys = 4.99 CPU) @ 20040.08/s (n=100000)
# 100000 loops of event sending took: 36.3202 wallclock secs ( 4.67 usr + 0.21 sys = 4.88 CPU) @ 20491.80/s (n=100000)
# 100000 loops of event sending took: 34.793 wallclock secs ( 4.71 usr + 0.25 sys = 4.96 CPU) @ 20161.29/s (n=100000)
Итого среднее число сообщений, отправляемых в секунду, из 5-ти прогонов составляет 20161.29.
я доволен :)