t_cromp_server.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : test_cromp_server                                                 *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #include "crompish_pax.h"
00016 
00017 #include <basis/byte_array.h>
00018 #include <basis/function.h>
00019 #include <basis/istring.h>
00020 #include <basis/log_base.h>
00021 #include <basis/portable.h>
00022 #include <cromp/cromp_server.h>
00023 #include <mechanisms/time_stamp.h>
00024 #include <octopus/tentacle.h>
00025 #include <opsystem/application_shell.h>
00026 #include <opsystem/command_line.h>
00027 #include <loggers/console_logger.h>
00028 #include <loggers/file_logger.h>
00029 #include <data_struct/static_memory_gremlin.h>
00030 #include <sockets/address.h>
00031 #include <sockets/machine_uid.h>
00032 #include <sockets/tcpip_stack.h>
00033 
00034 #define LOG(a) CLASS_EMERGENCY_LOG(program_wide_logger(), a)
00035 
00036 const int REPORTING_INTERVAL = 28 * SECOND_ms;  // how often to squawk.
00037 
00038 //const int ACCEPTING_THREADS = 5;
00039 const int ACCEPTING_THREADS = 1;
00040 
00041 // specifies whether to support lazy evaluation by tentacles.
00042 //const bool SUPPORT_BACKGROUNDING = true;
00043 const bool SUPPORT_BACKGROUNDING = false;
00044 
00045 // determines whether the octopus will do immediate evaluation or not.
00046 //const bool IMMEDIATE_EVALUATION = true;
00047 const bool IMMEDIATE_EVALUATION = false;
00048 
00050 
00051 // forward.
00052 class cromp_server_tester;
00053 
00054 class our_cromp_server : public cromp_server
00055 {
00056 public:
00057   our_cromp_server(cromp_server_tester &parent, const internet_address &addr)
00058   : cromp_server(addr, ACCEPTING_THREADS, IMMEDIATE_EVALUATION),
00059     _parent(parent) {}
00060 
00061   ~our_cromp_server() {}
00062 
00063   IMPLEMENT_CLASS_NAME("our_cromp_server");
00064 
00065 private:
00066   cromp_server_tester &_parent;
00067 };
00068 
00070 
00071 class cromp_server_tester : public application_shell
00072 {
00073 public:
00074   bool _saw_clients;  // true if we ever got a connection.
00075 
00076   cromp_server_tester();
00077   ~cromp_server_tester();
00078 
00079   virtual int execute();
00080 
00081   IMPLEMENT_CLASS_NAME("cromp_server_tester");
00082 
00083 private:
00084   our_cromp_server *_uplink;
00085     // provides the connection and transmission services.
00086   bool _leave_when_no_clients;  // true if we should just do one run.
00087   bool _encryption;  // true if we should do an encrypted connection.
00088 };
00089 
00091 
00092 class real_bubbles_tentacle : public bubbles_tentacle
00093 {
00094 public:
00095   real_bubbles_tentacle(cromp_server_tester &parent, bool backgrounding)
00096       : bubbles_tentacle(backgrounding), _parent(parent) {}
00097 
00098   virtual outcome consume(infoton &to_chow, const octopus_request_id &item_id,
00099       byte_array &transformed)
00100   {
00101     transformed.reset();
00102     _parent._saw_clients = true;  // we saw someone.
00103 //LOG("got to our cromp's bubble tentacle.");
00104     bubble *inf = dynamic_cast<bubble *>(&to_chow);
00105     if (!inf) return NO_HANDLER;
00106 //LOG("caching product!  success getting unpacked etc.");
00107     bubble *junk = (bubble *)inf->clone();
00108     store_product(junk, item_id);
00109     return OKAY;
00110   }
00111 
00112 private:
00113   cromp_server_tester &_parent;
00114 };
00115 
00117 
00118 cromp_server_tester::cromp_server_tester()
00119 : application_shell("cromp_server_tester"),
00120   _saw_clients(false),
00121   _uplink(NIL),
00122   _leave_when_no_clients(false),
00123   _encryption(false)
00124 {
00125   FUNCDEF("constructor");
00126   SET_DEFAULT_COMBO_LOGGER;
00127   LOG("");
00128   LOG("");
00129 
00130   command_line args(__argc, __argv);
00131   // check for a port on the command line.
00132   istring port_text;
00133   int port = 5678;
00134   if (args.get_value("port", port_text, false)) {
00135     LOG(istring("using port: ") + port_text);
00136     port = port_text.convert(5678);
00137   }
00138   int posn = 0;
00139   if (args.find("exit", posn)) {
00140     LOG("seeing the 'exit without clients' flag set.");
00141     _leave_when_no_clients = true;
00142   }
00143 
00144 //hmmm:normalize host so this can take either name or IP.
00145 
00146   internet_address addr;
00147 
00148   // check for a hostname on the command line.
00149   istring hostname("local");
00150   istring host_temp;
00151   if (args.get_value("host", host_temp, false)) {
00152     LOG(istring("using host: ") + host_temp);
00153     hostname = host_temp;
00154   }
00155   strcpy(addr.hostname, hostname.s());
00156 
00157 //LOG(istring("here's the command line:") + log_base::platform_ending() + args.text_form());
00158 
00159   int indy = 0;
00160   if (args.find("encrypt", indy) || (args.find('e', indy)) ) {
00161     // they're saying that we should encrypt the communication.
00162     LOG("turning on encryption.");
00163     _encryption = true;
00164   }
00165 
00166 //  tcpip_stack stack;
00167 //  machine_uid host = stack.this_host(machine_uid::TCPIP_LOCATION);
00168   addr.port = port;
00169 //  host.native().stuff(internet_address::ADDRESS_SIZE, addr.ip_address);
00170   LOG("starting cromp_server");
00171   _uplink = new our_cromp_server(*this, addr);
00172   _uplink->add_tentacle(new real_bubbles_tentacle(*this, SUPPORT_BACKGROUNDING));
00173   _uplink->enable_servers(_encryption);
00174 }
00175 
00176 cromp_server_tester::~cromp_server_tester()
00177 {
00178   WHACK(_uplink);
00179 }
00180 
00181 int cromp_server_tester::execute()
00182 {
00183   FUNCDEF("execute");
00184 
00185   time_stamp next_report(REPORTING_INTERVAL);
00186 
00187   while (true) {
00188     // make sure we didn't see our exit condition.
00189     if (!_uplink->clients() && _leave_when_no_clients && _saw_clients) {
00190       LOG("exiting now");
00191       break;
00192     }
00193 
00194     if (time_stamp() > next_report) {
00195       int client_count = _uplink->clients();
00196       const char *verb = "are";
00197       if (client_count == 1) verb = "is";
00198       const char *ending = "s";
00199       if (client_count == 1) ending = "";
00200       LOG(isprintf("There %s %d client%s.", verb, client_count, ending));
00201       next_report.reset(REPORTING_INTERVAL);
00202     }
00203 
00204     portable::sleep_ms(100); 
00205   }
00206   return 0;
00207 }
00208 
00210 
00211 HOOPLE_MAIN(cromp_server_tester, )
00212 

Generated on Fri Nov 21 04:30:00 2008 for HOOPLE Libraries by  doxygen 1.5.1