00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package com.sleepycat.db.rpcserver;
00011
00012 import com.sleepycat.db.*;
00013 import com.sleepycat.db.internal.DbConstants;
00014 import java.io.*;
00015 import java.util.*;
00016 import org.acplt.oncrpc.OncRpcException;
00017 import org.acplt.oncrpc.server.OncRpcCallInformation;
00018
00022 public class Server extends Dispatcher {
00023 public static long idleto = 10 * 60 * 1000;
00024 public static long defto = 5 * 60 * 1000;
00025 public static long maxto = 60 * 60 * 1000;
00026 public static String passwd = null;
00027 public static OutputStream errstream;
00028 public static PrintWriter err;
00029
00030 long now, hint;
00031 FreeList env_list = new FreeList();
00032 FreeList db_list = new FreeList();
00033 FreeList txn_list = new FreeList();
00034 FreeList cursor_list = new FreeList();
00035
00036 public Server() throws IOException, OncRpcException {
00037 super();
00038 init_lists();
00039 }
00040
00041 public void dispatchOncRpcCall(OncRpcCallInformation call, int program,
00042 int version, int procedure) throws OncRpcException, IOException {
00043 long newnow = System.currentTimeMillis();
00044
00045 now = newnow;
00046 try {
00047 super.dispatchOncRpcCall(call, program, version, procedure);
00048 doTimeouts();
00049 } catch (Throwable t) {
00050 System.err.println("Caught " + t + " while dispatching RPC call " + procedure);
00051 t.printStackTrace(Server.err);
00052 } finally {
00053 Server.err.flush();
00054 }
00055 }
00056
00057
00058 private void init_lists() {
00059
00060 env_list.add(null);
00061 db_list.add(null);
00062 txn_list.add(null);
00063 cursor_list.add(null);
00064 }
00065
00066 int addEnv(RpcDbEnv rdbenv) {
00067 rdbenv.timer.last_access = now;
00068 int id = env_list.add(rdbenv);
00069 return id;
00070 }
00071
00072 int addDatabase(RpcDb rdb) {
00073 int id = db_list.add(rdb);
00074 return id;
00075 }
00076
00077 int addTxn(RpcDbTxn rtxn) {
00078 rtxn.timer.last_access = now;
00079 int id = txn_list.add(rtxn);
00080 return id;
00081 }
00082
00083 int addCursor(RpcDbc rdbc) {
00084 rdbc.timer.last_access = now;
00085 int id = cursor_list.add(rdbc);
00086 return id;
00087 }
00088
00089 void delEnv(RpcDbEnv rdbenv, boolean dispose) {
00090 env_list.del(rdbenv);
00091
00092
00093 for (LocalIterator i = db_list.iterator(); i.hasNext();) {
00094 RpcDb rdb = (RpcDb)i.next();
00095 if (rdb != null && rdb.rdbenv == rdbenv)
00096 delDatabase(rdb, true);
00097 }
00098
00099 if (dispose)
00100 rdbenv.dispose();
00101 }
00102
00103 void delDatabase(RpcDb rdb, boolean dispose) {
00104 db_list.del(rdb);
00105
00106 for (LocalIterator i = cursor_list.iterator(); i.hasNext();) {
00107 RpcDbc rdbc = (RpcDbc)i.next();
00108 if (rdbc != null && rdbc.timer == rdb) {
00109 i.remove();
00110 rdbc.dispose();
00111 }
00112 }
00113
00114 if (dispose)
00115 rdb.dispose();
00116 }
00117
00118 void delTxn(RpcDbTxn rtxn, boolean dispose) {
00119 txn_list.del(rtxn);
00120
00121 for (LocalIterator i = cursor_list.iterator(); i.hasNext();) {
00122 RpcDbc rdbc = (RpcDbc)i.next();
00123 if (rdbc != null && rdbc.timer == rtxn) {
00124 i.remove();
00125 rdbc.dispose();
00126 }
00127 }
00128
00129 for (LocalIterator i = txn_list.iterator(); i.hasNext();) {
00130 RpcDbTxn rtxn_child = (RpcDbTxn)i.next();
00131 if (rtxn_child != null && rtxn_child.timer == rtxn) {
00132 i.remove();
00133 rtxn_child.dispose();
00134 }
00135 }
00136
00137 if (dispose)
00138 rtxn.dispose();
00139 }
00140
00141 void delCursor(RpcDbc rdbc, boolean dispose) {
00142 cursor_list.del(rdbc);
00143 if (dispose)
00144 rdbc.dispose();
00145 }
00146
00147 RpcDbEnv getEnv(int envid) {
00148 RpcDbEnv rdbenv = (RpcDbEnv)env_list.get(envid);
00149 if (rdbenv != null)
00150 rdbenv.timer.last_access = now;
00151 return rdbenv;
00152 }
00153
00154 RpcDb getDatabase(int dbid) {
00155 RpcDb rdb = (RpcDb)db_list.get(dbid);
00156 if (rdb != null)
00157 rdb.rdbenv.timer.last_access = now;
00158 return rdb;
00159 }
00160
00161 RpcDbTxn getTxn(int txnid) {
00162 RpcDbTxn rtxn = (RpcDbTxn)txn_list.get(txnid);
00163 if (rtxn != null)
00164 rtxn.timer.last_access = rtxn.rdbenv.timer.last_access = now;
00165 return rtxn;
00166 }
00167
00168 RpcDbc getCursor(int dbcid) {
00169 RpcDbc rdbc = (RpcDbc)cursor_list.get(dbcid);
00170 if (rdbc != null)
00171 rdbc.last_access = rdbc.timer.last_access = rdbc.rdbenv.timer.last_access = now;
00172 return rdbc;
00173 }
00174
00175 void doTimeouts() {
00176 if (now < hint) {
00177
00178 return;
00179 }
00180
00181
00182 hint = now + Server.maxto;
00183
00184 for (LocalIterator i = cursor_list.iterator(); i.hasNext();) {
00185 RpcDbc rdbc = (RpcDbc)i.next();
00186 if (rdbc == null)
00187 continue;
00188
00189 long end_time = rdbc.timer.last_access + rdbc.rdbenv.timeout;
00190
00191 if (end_time < now) {
00192 Server.err.println("Cleaning up " + rdbc);
00193 delCursor(rdbc, true);
00194 } else if (end_time < hint)
00195 hint = end_time;
00196 }
00197
00198 for (LocalIterator i = txn_list.iterator(); i.hasNext();) {
00199 RpcDbTxn rtxn = (RpcDbTxn)i.next();
00200 if (rtxn == null)
00201 continue;
00202
00203 long end_time = rtxn.timer.last_access + rtxn.rdbenv.timeout;
00204
00205 if (end_time < now) {
00206 Server.err.println("Cleaning up " + rtxn);
00207 delTxn(rtxn, true);
00208 } else if (end_time < hint)
00209 hint = end_time;
00210 }
00211
00212 for (LocalIterator i = env_list.iterator(); i.hasNext();) {
00213 RpcDbEnv rdbenv = (RpcDbEnv)i.next();
00214 if (rdbenv == null)
00215 continue;
00216
00217 long end_time = rdbenv.timer.last_access + rdbenv.idletime;
00218
00219 if (end_time < now) {
00220 Server.err.println("Cleaning up " + rdbenv);
00221 delEnv(rdbenv, true);
00222 }
00223 }
00224
00225
00226 if (hint == now + Server.maxto)
00227 hint = 0;
00228
00229
00230 }
00231
00232
00233 static final int ENOENT = 2;
00234 static final int EACCES = 13;
00235 static final int EEXIST = 17;
00236 static final int EINVAL = 22;
00237 static final int DB_SERVER_FLAGMASK = DbConstants.DB_LOCKDOWN |
00238 DbConstants.DB_PRIVATE | DbConstants.DB_RECOVER | DbConstants.DB_RECOVER_FATAL |
00239 DbConstants.DB_SYSTEM_MEM | DbConstants.DB_USE_ENVIRON |
00240 DbConstants.DB_USE_ENVIRON_ROOT;
00241 static final int DB_SERVER_ENVFLAGS = DbConstants.DB_INIT_CDB |
00242 DbConstants.DB_INIT_LOCK | DbConstants.DB_INIT_LOG | DbConstants.DB_INIT_MPOOL |
00243 DbConstants.DB_INIT_TXN | DbConstants.DB_JOINENV;
00244 static final int DB_SERVER_DBFLAGS = DbConstants.DB_READ_UNCOMMITTED |
00245 DbConstants.DB_NOMMAP | DbConstants.DB_RDONLY;
00246 static final int DB_SERVER_DBNOSHARE = DbConstants.DB_EXCL | DbConstants.DB_TRUNCATE;
00247 static final int DB_MODIFIER_MASK = 0xff000000;
00248
00249 static Vector homes = new Vector();
00250
00251 static void add_home(String home) {
00252 File f = new File(home);
00253 try {
00254 home = f.getCanonicalPath();
00255 } catch (IOException e) {
00256
00257 }
00258 homes.addElement(home);
00259 }
00260
00261 static boolean check_home(String home) {
00262 if (home == null)
00263 return false;
00264 File f = new File(home);
00265 try {
00266 home = f.getCanonicalPath();
00267 } catch (IOException e) {
00268
00269 }
00270 return homes.contains(home);
00271 }
00272
00273 public static void main(String[] args) {
00274 System.out.println("Starting Server...");
00275 for (int i = 0; i < args.length; i++) {
00276 if (args[i].charAt(0) != '-')
00277 usage();
00278
00279 switch (args[i].charAt(1)) {
00280 case 'h':
00281 add_home(args[++i]);
00282 break;
00283 case 'I':
00284 idleto = Long.parseLong(args[++i]) * 1000L;
00285 break;
00286 case 'P':
00287 passwd = args[++i];
00288 break;
00289 case 't':
00290 defto = Long.parseLong(args[++i]) * 1000L;
00291 break;
00292 case 'T':
00293 maxto = Long.parseLong(args[++i]) * 1000L;
00294 break;
00295 case 'V':
00296
00297 break;
00298 case 'v':
00299
00300 break;
00301 default:
00302 usage();
00303 }
00304 }
00305
00306 try {
00307
00308 Server.errstream = new FileOutputStream("JavaRPCServer.trace", true);
00309 Server.err = new PrintWriter(Server.errstream);
00310 Server server = new Server();
00311 server.run();
00312 } catch (Throwable e) {
00313 System.err.println("Server exception:");
00314 e.printStackTrace(Server.err);
00315 } finally {
00316 if (Server.err != null)
00317 Server.err.close();
00318 }
00319
00320 System.out.println("Server stopped.");
00321 }
00322
00323 static void usage() {
00324 System.err.println("usage: java com.sleepycat.db.rpcserver.Server \\");
00325 System.err.println("[-Vv] [-h home] [-P passwd] [-I idletimeout] [-L logfile] [-t def_timeout] [-T maxtimeout]");
00326 System.exit(1);
00327 }
00328 }