package com.sleepycat.db.rpcserver;
import com.sleepycat.db.*;
import java.io.*;
import java.util.*;
import org.acplt.oncrpc.OncRpcException;
import org.acplt.oncrpc.server.OncRpcCallInformation;
public class DbServer extends DbDispatcher
{
public static long idleto = 10 * 60 * 1000; public static long defto = 5 * 60 * 1000; public static long maxto = 60 * 60 * 1000; public static String passwd = null;
public static PrintWriter err;
long now, hint; FreeList env_list = new FreeList();
FreeList db_list = new FreeList();
FreeList txn_list = new FreeList();
FreeList cursor_list = new FreeList();
public DbServer() throws IOException, OncRpcException
{
super();
init_lists();
}
public void dispatchOncRpcCall(OncRpcCallInformation call, int program,
int version, int procedure) throws OncRpcException, IOException
{
long newnow = System.currentTimeMillis();
now = newnow;
try {
super.dispatchOncRpcCall(call, program, version, procedure);
} catch(Throwable t) {
System.err.println("Caught " + t + " while dispatching RPC call " + procedure);
t.printStackTrace(DbServer.err);
} finally {
doTimeouts();
DbServer.err.flush();
}
}
private void init_lists()
{
env_list.add(null);
db_list.add(null);
txn_list.add(null);
cursor_list.add(null);
}
int addEnv(RpcDbEnv rdbenv)
{
rdbenv.timer.last_access = now;
int id = env_list.add(rdbenv);
return id;
}
int addDb(RpcDb rdb)
{
int id = db_list.add(rdb);
return id;
}
int addTxn(RpcDbTxn rtxn)
{
rtxn.timer.last_access = now;
int id = txn_list.add(rtxn);
return id;
}
int addCursor(RpcDbc rdbc)
{
rdbc.timer.last_access = now;
int id = cursor_list.add(rdbc);
return id;
}
void delEnv(RpcDbEnv rdbenv, boolean dispose)
{
env_list.del(rdbenv);
for(LocalIterator i = db_list.iterator(); i.hasNext(); ) {
RpcDb rdb = (RpcDb)i.next();
if (rdb != null && rdb.rdbenv == rdbenv)
delDb(rdb, true);
}
if (dispose)
rdbenv.dispose();
}
void delDb(RpcDb rdb, boolean dispose)
{
db_list.del(rdb);
for(LocalIterator i = cursor_list.iterator(); i.hasNext(); ) {
RpcDbc rdbc = (RpcDbc)i.next();
if (rdbc != null && rdbc.timer == rdb) {
i.remove();
rdbc.dispose();
}
}
if (dispose)
rdb.dispose();
}
void delTxn(RpcDbTxn rtxn, boolean dispose)
{
txn_list.del(rtxn);
for(LocalIterator i = cursor_list.iterator(); i.hasNext(); ) {
RpcDbc rdbc = (RpcDbc)i.next();
if (rdbc != null && rdbc.timer == rtxn) {
i.remove();
rdbc.dispose();
}
}
for(LocalIterator i = txn_list.iterator(); i.hasNext(); ) {
RpcDbTxn rtxn_child = (RpcDbTxn)i.next();
if (rtxn_child != null && rtxn_child.timer == rtxn) {
i.remove();
rtxn_child.dispose();
}
}
if (dispose)
rtxn.dispose();
}
void delCursor(RpcDbc rdbc, boolean dispose)
{
cursor_list.del(rdbc);
if (dispose)
rdbc.dispose();
}
RpcDbEnv getEnv(int envid)
{
RpcDbEnv rdbenv = (RpcDbEnv)env_list.get(envid);
if (rdbenv != null)
rdbenv.timer.last_access = now;
return rdbenv;
}
RpcDb getDb(int dbid)
{
RpcDb rdb = (RpcDb)db_list.get(dbid);
if (rdb != null)
rdb.rdbenv.timer.last_access = now;
return rdb;
}
RpcDbTxn getTxn(int txnid)
{
RpcDbTxn rtxn = (RpcDbTxn)txn_list.get(txnid);
if (rtxn != null)
rtxn.timer.last_access = rtxn.rdbenv.timer.last_access = now;
return rtxn;
}
RpcDbc getCursor(int dbcid)
{
RpcDbc rdbc = (RpcDbc)cursor_list.get(dbcid);
if (rdbc != null)
rdbc.last_access = rdbc.timer.last_access = rdbc.rdbenv.timer.last_access = now;
return rdbc;
}
void doTimeouts()
{
if (now < hint) {
return;
}
hint = now + DbServer.maxto;
for(LocalIterator i = cursor_list.iterator(); i.hasNext(); ) {
RpcDbc rdbc = (RpcDbc)i.next();
if (rdbc == null)
continue;
long end_time = rdbc.timer.last_access + rdbc.rdbenv.timeout;
if (end_time < now) {
DbServer.err.println("Cleaning up " + rdbc);
delCursor(rdbc, true);
} else if (end_time < hint)
hint = end_time;
}
for(LocalIterator i = txn_list.iterator(); i.hasNext(); ) {
RpcDbTxn rtxn = (RpcDbTxn)i.next();
if (rtxn == null)
continue;
long end_time = rtxn.timer.last_access + rtxn.rdbenv.timeout;
if (end_time < now) {
DbServer.err.println("Cleaning up " + rtxn);
delTxn(rtxn, true);
} else if (end_time < hint)
hint = end_time;
}
for(LocalIterator i = env_list.iterator(); i.hasNext(); ) {
RpcDbEnv rdbenv = (RpcDbEnv)i.next();
if (rdbenv == null)
continue;
long end_time = rdbenv.timer.last_access + rdbenv.idletime;
if (end_time < now) {
DbServer.err.println("Cleaning up " + rdbenv);
delEnv(rdbenv, true);
}
}
if (hint == now + DbServer.maxto)
hint = 0;
}
static final int EINVAL = 22;
static final int DB_SERVER_FLAGMASK = Db.DB_LOCKDOWN |
Db.DB_PRIVATE | Db.DB_RECOVER | Db.DB_RECOVER_FATAL |
Db.DB_SYSTEM_MEM | Db.DB_USE_ENVIRON |
Db.DB_USE_ENVIRON_ROOT;
static final int DB_SERVER_ENVFLAGS = Db.DB_INIT_CDB |
Db.DB_INIT_LOCK | Db.DB_INIT_LOG | Db.DB_INIT_MPOOL |
Db.DB_INIT_TXN | Db.DB_JOINENV;
static final int DB_SERVER_DBFLAGS = Db.DB_DIRTY_READ |
Db.DB_NOMMAP | Db.DB_RDONLY;
static final int DB_SERVER_DBNOSHARE = Db.DB_EXCL | Db.DB_TRUNCATE;
static Vector homes = new Vector();
static void add_home(String home) {
File f = new File(home);
try { home = f.getCanonicalPath(); } catch(IOException e) {}
homes.addElement(home);
}
static boolean check_home(String home) {
if (home == null)
return false;
File f = new File(home);
try { home = f.getCanonicalPath(); } catch(IOException e) {}
return homes.contains(home);
}
public static void main(String[] args)
{
System.out.println("Starting DbServer...");
for (int i = 0; i < args.length; i++) {
if (args[i].charAt(0) != '-')
usage();
switch (args[i].charAt(1)) {
case 'h':
add_home(args[++i]);
break;
case 'I':
idleto = Long.parseLong(args[++i]) * 1000L;
break;
case 'P':
passwd = args[++i];
break;
case 't':
defto = Long.parseLong(args[++i]) * 1000L;
break;
case 'T':
maxto = Long.parseLong(args[++i]) * 1000L;
break;
case 'V':
break;
case 'v':
break;
default:
usage();
}
}
try {
DbServer.err = new PrintWriter(new FileOutputStream("JavaRPCServer.trace", true));
DbServer server = new DbServer();
server.run();
} catch (Throwable e) {
System.out.println("DbServer exception:");
e.printStackTrace(DbServer.err);
} finally {
if (DbServer.err != null)
DbServer.err.close();
}
System.out.println("DbServer stopped.");
}
static void usage()
{
System.err.println("usage: java com.sleepycat.db.rpcserver.DbServer \\");
System.err.println("[-Vv] [-h home] [-P passwd] [-I idletimeout] [-L logfile] [-t def_timeout] [-T maxtimeout]");
System.exit(1);
}
}