Evo C++ Library v0.5.1
Full Server Example

This gives a full server example, including:

See: Asynchronous I/O

Example
#include <evo/string.h>
#include <evo/maphash.h>
#include <evo/logger.h>
#include <evo/process.h>
using namespace evo;
// Basic memcache server
struct Shared : SimpleSharedBase<> {
StrHash map;
};
Shared& shared;
Handler(Global& global, Shared& shared) : shared(shared) {
}
StoreResult on_store(DeferredContext& context, StoreParams& params, SubString& value, Command command, uint64 cas_id) {
switch(command) {
case cSET:
shared.map[params.key] = value;
break;
default:
send_error("Not supported");
return rtHANDLED;
}
return Memcached::srSTORED;
}
ResponseType on_get(DeferredContext& context, const SubString& key, GetAdvParams* adv_params) {
const String* val = shared.map.find(key);
if (val != NULL)
send_value(key, *val);
return rtHANDLED;
}
};
int main(int argc, const char* argv[]) {
const ulong RD_TIMEOUT_MS = 5000;
const ulong WR_TIMEOUT_MS = 1000;
// Command-line
StrHash args;
String tmpstr;
{
List<SubString> log_level_choices;
for (LogLevelEnum::Iter iter; iter; ++iter)
log_level_choices.add(iter.value_str());
CommandLine cmdline("Test memcached server");
cmdline.addver("Test Memcached Server 1.0");
cmdline.addopt("-p, --port", "Server port number to use")
.default_value("11211")
.numeric()
cmdline.addopt("-l, --log", "Log file to use")
.default_value("server.log");
cmdline.addopt("-L, --loglevel", tmpstr.set("Log level to use ${default}, one of:\n ").join(log_level_choices, ','))
.default_value("info")
.addchoices(log_level_choices);
if (!cmdline.parse(args, argc, argv))
return 0;
}
// Init logger, use local time in log
Logger<> logger;
logger.set_local_time(true);
logger.set_level(LogLevelEnum::get_enum(lookupsub(args, "loglevel")));
// Listen on socket early and open log, stop on error such as "port in use" or permissions issue
Socket listener;
const ushort port = lookupsub(args, "port").getnum<ushort>();
try {
listener.listen_ip(port);
logger.open(lookupsub(args, "log"));
} EVO_CATCH(return 1);
// Init server
Server server;
server.set_logger(&logger);
server.set_timeout(RD_TIMEOUT_MS, WR_TIMEOUT_MS);
// Install shutdown signal handler using helper for servers
Signal::MainServer<Server> signal_main(server);
// Uncomment to daemonize (run in background) -- Linux/Unix only
//daemonize(DAEMONIZE_USE_STDERR);
// Run server -- logger now used, error before this point goes to stderr
logger.start_thread();
EVO_LOG_INFO(logger, tmpstr.set() << "Startup: Listening on port " << port);
server.run(listener);
EVO_LOG_INFO(logger, "Shutdown");
return 0;
}