diff options
Diffstat (limited to 'storage/bdb/rpc_server/java/DbServer.java')
-rw-r--r-- | storage/bdb/rpc_server/java/DbServer.java | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/storage/bdb/rpc_server/java/DbServer.java b/storage/bdb/rpc_server/java/DbServer.java new file mode 100644 index 00000000000..9b20becbcdc --- /dev/null +++ b/storage/bdb/rpc_server/java/DbServer.java @@ -0,0 +1,301 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2001-2002 + * Sleepycat Software. All rights reserved. + * + * $Id: DbServer.java,v 1.5 2002/08/09 01:56:09 bostic Exp $ + */ + +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; + +/** + * Main entry point for the Java version of the Berkeley DB RPC server + */ +public class DbServer extends DbDispatcher +{ + public static long idleto = 10 * 60 * 1000; // 5 minutes + public static long defto = 5 * 60 * 1000; // 5 minutes + public static long maxto = 60 * 60 * 1000; // 1 hour + public static String passwd = null; + public static PrintWriter err; + + long now, hint; // updated each operation + 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(); + // DbServer.err.println("Dispatching RPC call " + procedure + " after delay of " + (newnow - now)); + now = newnow; + // DbServer.err.flush(); + super.dispatchOncRpcCall(call, program, version, procedure); + + try { + doTimeouts(); + } catch(Throwable t) { + System.err.println("Caught " + t + " during doTimeouts()"); + t.printStackTrace(System.err); + } + } + + // Internal methods to track context + private void init_lists() + { + // We do this so that getEnv/Db/etc(0) == null + 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) + { + // cursors and transactions will already have been cleaned up + for(LocalIterator i = db_list.iterator(); i.hasNext(); ) { + RpcDb rdb = (RpcDb)i.next(); + if (rdb != null && rdb.rdbenv == rdbenv) + delDb(rdb); + } + + env_list.del(rdbenv); + rdbenv.dispose(); + } + + void delDb(RpcDb rdb) + { + db_list.del(rdb); + rdb.dispose(); + + for(LocalIterator i = cursor_list.iterator(); i.hasNext(); ) { + RpcDbc rdbc = (RpcDbc)i.next(); + if (rdbc != null && rdbc.timer == rdb) + i.remove(); + } + } + + void delTxn(RpcDbTxn rtxn) + { + txn_list.del(rtxn); + rtxn.dispose(); + + for(LocalIterator i = cursor_list.iterator(); i.hasNext(); ) { + RpcDbc rdbc = (RpcDbc)i.next(); + if (rdbc != null && rdbc.timer == rtxn) + i.remove(); + } + + for(LocalIterator i = txn_list.iterator(); i.hasNext(); ) { + RpcDbTxn rtxn_child = (RpcDbTxn)i.next(); + if (rtxn_child != null && rtxn_child.timer == rtxn) + i.remove(); + } + } + + void delCursor(RpcDbc rdbc) + { + cursor_list.del(rdbc); + 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) { + // DbServer.err.println("Skipping cleaner sweep - now = " + now + ", hint = " + hint); + return; + } + + // DbServer.err.println("Starting a cleaner sweep"); + 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; + // DbServer.err.println("Examining " + rdbc + ", time left = " + (end_time - now)); + if (end_time < now) { + DbServer.err.println("Cleaning up " + rdbc); + delCursor(rdbc); + } 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; + // DbServer.err.println("Examining " + rtxn + ", time left = " + (end_time - now)); + if (end_time < now) { + DbServer.err.println("Cleaning up " + rtxn); + delTxn(rtxn); + } 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; + // DbServer.err.println("Examining " + rdbenv + ", time left = " + (end_time - now)); + if (end_time < now) { + DbServer.err.println("Cleaning up " + rdbenv); + delEnv(rdbenv); + } + } + + // if we didn't find anything, reset the hint + if (hint == now + DbServer.maxto) + hint = 0; + + // DbServer.err.println("Finishing a cleaner sweep"); + } + + // Some constants that aren't available elsewhere + 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; + + 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': + ++i; // 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': + // version; + break; + case 'v': + // verbose + 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); + } +} |