2018-11-30 14:38:22 +08:00
|
|
|
#include "stdafx.h"
|
|
|
|
//#include "stamp.h"
|
|
|
|
|
|
|
|
static int __fibers_count = 2;
|
|
|
|
static int __fibers_max = 2;
|
|
|
|
static int __oper_count = 100;
|
|
|
|
//static struct timeval __begin, __end;
|
|
|
|
static ACL_FIBER **__workers = NULL;
|
|
|
|
static ACL_CHANNEL *__chan_exit = NULL;
|
|
|
|
|
|
|
|
static acl::redis_client_cluster __redis_cluster;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
ACL_CHANNEL *chan;
|
|
|
|
int id;
|
|
|
|
bool busy;
|
|
|
|
acl::string cmd;
|
|
|
|
} MYCHAN;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
MYCHAN *chans;
|
|
|
|
size_t size;
|
|
|
|
size_t off;
|
|
|
|
} MYCHANS;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
acl::string cmd;
|
|
|
|
acl::string key;
|
|
|
|
acl::string val;
|
|
|
|
bool success;
|
|
|
|
} PKT;
|
|
|
|
|
|
|
|
static bool redis_set(ACL_FIBER& fiber, ACL_CHANNEL &chan, PKT& pkt)
|
|
|
|
{
|
|
|
|
acl::redis cmd(&__redis_cluster);
|
|
|
|
|
|
|
|
pkt.success = false;
|
|
|
|
|
|
|
|
if (pkt.key.empty())
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: key empty!\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(&fiber));
|
|
|
|
pkt.val = "key empty";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (pkt.val.empty())
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: val empty\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(&fiber));
|
|
|
|
pkt.val = "val empty";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd.set(pkt.key, pkt.val) == false)
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: set error, key: %s, val: %s\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(&fiber),
|
|
|
|
pkt.key.c_str(), pkt.val.c_str());
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pkt.success = true;
|
|
|
|
if (acl_channel_sendp(&chan, &pkt) < 0)
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: acl_channel_sendp error, key %s\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(&fiber),
|
|
|
|
pkt.key.c_str());
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool redis_get(ACL_FIBER& fiber, ACL_CHANNEL &chan, PKT &pkt)
|
|
|
|
{
|
|
|
|
acl::redis cmd(&__redis_cluster);
|
|
|
|
|
|
|
|
pkt.success = false;
|
|
|
|
|
|
|
|
if (pkt.key.empty())
|
|
|
|
{
|
|
|
|
printf("fiber-%d: key empty!\r\n", acl_fiber_id(&fiber));
|
|
|
|
pkt.val = "key empty";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd.get(pkt.key, pkt.val) == false)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: get error, key: %s\r\n",
|
|
|
|
acl_fiber_id(&fiber), pkt.key.c_str());
|
|
|
|
pkt.val = "get error";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pkt.success = true;
|
|
|
|
if (acl_channel_sendp(&chan, &pkt) < 0)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: acl_channel_sendp error, key: %s\r\n",
|
|
|
|
acl_fiber_id(&fiber), pkt.key.c_str());
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool redis_del(ACL_FIBER& fiber, ACL_CHANNEL &chan, PKT &pkt)
|
|
|
|
{
|
|
|
|
acl::redis cmd(&__redis_cluster);
|
|
|
|
|
|
|
|
pkt.success = false;
|
|
|
|
|
|
|
|
if (pkt.key.empty())
|
|
|
|
{
|
|
|
|
printf("fiber-%d: key empty!\r\n", acl_fiber_id(&fiber));
|
|
|
|
pkt.val = "key empty";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd.del_one(pkt.key) < 0)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: del_one error, key: %s\r\n",
|
|
|
|
acl_fiber_id(&fiber), pkt.key.c_str());
|
|
|
|
pkt.val = "del error";
|
|
|
|
acl_channel_sendp(&chan, &pkt);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pkt.success = true;
|
|
|
|
if (acl_channel_sendp(&chan, &pkt) < 0)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: acl_channel_sendp error, key: %s\r\n",
|
|
|
|
acl_fiber_id(&fiber), pkt.key.c_str());
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fiber_worker(ACL_FIBER *fiber, void *ctx)
|
|
|
|
{
|
|
|
|
ACL_CHANNEL *chan = ((MYCHAN *) ctx)->chan;
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
PKT* pkt = (PKT *) acl_channel_recvp(chan);
|
|
|
|
|
|
|
|
if (pkt == NULL)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: acl_channel_recvp NULL\r\n",
|
|
|
|
acl_fiber_id(fiber));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pkt->cmd.equal("set", false))
|
|
|
|
{
|
|
|
|
if (redis_set(*fiber, *chan, *pkt) == false)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: redis_set error\r\n",
|
|
|
|
acl_fiber_id(fiber));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pkt->cmd.equal("get", false))
|
|
|
|
{
|
|
|
|
if (redis_get(*fiber, *chan, *pkt) == false)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: redis_get error\r\n",
|
|
|
|
acl_fiber_id(fiber));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pkt->cmd.equal("del", false))
|
|
|
|
{
|
|
|
|
if (redis_del(*fiber, *chan, *pkt) == false)
|
|
|
|
{
|
|
|
|
printf("fiber-%d: redis_del error\r\n",
|
|
|
|
acl_fiber_id(fiber));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printf("unknown cmd: %s\r\n", pkt->cmd.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __display = 0;
|
|
|
|
|
|
|
|
static void fiber_result(ACL_FIBER *fiber, void *ctx)
|
|
|
|
{
|
|
|
|
MYCHANS *mychans = (MYCHANS *) ctx;
|
|
|
|
MYCHAN *mychan = &mychans->chans[mychans->off++];
|
|
|
|
ACL_CHANNEL *chan = mychan->chan;
|
|
|
|
PKT pkt;
|
|
|
|
|
|
|
|
if (mychans->off == mychans->size)
|
|
|
|
mychans->off = 0;
|
|
|
|
|
|
|
|
pkt.cmd = mychan->cmd;
|
|
|
|
|
|
|
|
for (int i = 0; i < __oper_count; i++)
|
|
|
|
{
|
|
|
|
pkt.key.format("key-%d-%d", acl_fiber_id(fiber), i);
|
|
|
|
pkt.val.format("val-%d-%d", acl_fiber_id(fiber), i);
|
|
|
|
|
|
|
|
if (acl_channel_sendp(chan, &pkt) < 0)
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: acl_channel_sendp error, key = %s\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(fiber),
|
|
|
|
pkt.key.c_str());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
PKT* res = (PKT *) acl_channel_recvp(chan);
|
|
|
|
if (res == NULL)
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: acl_channel_recvp error, key = %s\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(fiber),
|
|
|
|
pkt.key.c_str());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//assert(res == &pkt);
|
|
|
|
|
|
|
|
if (!res->success)
|
|
|
|
{
|
|
|
|
printf("%s(%d): fiber-%d: cmd = %s, key = %s, failed\r\n",
|
|
|
|
__FUNCTION__, __LINE__, acl_fiber_id(fiber),
|
|
|
|
pkt.cmd.c_str(), pkt.key.c_str());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (++__display >= 10)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pkt.cmd.equal("get", false))
|
|
|
|
printf("fiber-%d: cmd = %s, key = %s, val = %s\r\n",
|
|
|
|
acl_fiber_id(fiber), pkt.cmd.c_str(),
|
|
|
|
pkt.key.c_str(), res->val.c_str());
|
|
|
|
else
|
|
|
|
printf("fiber-%d: cmd = %s, key = %s\r\n",
|
|
|
|
acl_fiber_id(fiber), pkt.cmd.c_str(),
|
|
|
|
pkt.key.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (--__fibers_count == 0)
|
|
|
|
{
|
|
|
|
printf("---All fibers are over!---\r\n");
|
|
|
|
unsigned long n = 100;
|
|
|
|
acl_channel_sendul(__chan_exit, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fiber_wait(ACL_FIBER *, void *ctx)
|
|
|
|
{
|
|
|
|
ACL_CHANNEL *chan = (ACL_CHANNEL *) ctx;
|
|
|
|
unsigned long n = acl_channel_recvul(chan);
|
|
|
|
|
|
|
|
printf("----fiber-%d: get n: %lu---\r\n", acl_fiber_self(), n);
|
|
|
|
|
|
|
|
for (int i = 0; __workers[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
printf("kill fiber-%d\r\n", acl_fiber_id(__workers[i]));
|
|
|
|
acl_fiber_kill(__workers[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("---- fiber schedul stopping now ----\r\n");
|
|
|
|
acl_fiber_schedule_stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void usage(const char *procname)
|
|
|
|
{
|
|
|
|
printf("usage: %s -h [help]\r\n"
|
|
|
|
" -s redis_addr\r\n"
|
|
|
|
" -a command[set|get|del]\r\n"
|
|
|
|
" -n operation_count\r\n"
|
|
|
|
" -c fibers count\r\n"
|
|
|
|
" -w workers count\r\n"
|
|
|
|
" -t connect timoeut\r\n"
|
|
|
|
" -r rw_timeout\r\n", procname);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int ch, conn_timeout = 0, rw_timeout = 0, nworkers = 10;
|
|
|
|
acl::string addr("127.0.0.1:6379"), cmd("set");
|
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "hs:n:c:r:t:w:a:")) > 0) {
|
|
|
|
switch (ch) {
|
|
|
|
case 'h':
|
|
|
|
usage(argv[0]);
|
|
|
|
return 0;
|
|
|
|
case 'a':
|
|
|
|
cmd = optarg;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
nworkers = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
addr = optarg;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
__oper_count = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
__fibers_max = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
rw_timeout = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
conn_timeout = atoi(optarg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
acl::acl_cpp_init();
|
|
|
|
|
|
|
|
__redis_cluster.set(addr.c_str(), 0, conn_timeout, rw_timeout);
|
|
|
|
|
|
|
|
//gettimeofday(&__begin, NULL);
|
|
|
|
|
|
|
|
if (nworkers > __fibers_max)
|
|
|
|
nworkers = __fibers_max;
|
|
|
|
|
|
|
|
nworkers = __fibers_max;
|
|
|
|
|
|
|
|
MYCHANS mychans;
|
|
|
|
mychans.size = nworkers;
|
|
|
|
mychans.off = 0;
|
|
|
|
mychans.chans = new MYCHAN[nworkers];
|
|
|
|
|
|
|
|
for (int i = 0; i < nworkers; i++)
|
|
|
|
{
|
|
|
|
mychans.chans[i].chan = acl_channel_create(sizeof(void*), 1000);
|
|
|
|
mychans.chans[i].cmd = cmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
__workers = new ACL_FIBER*[nworkers + 1];
|
|
|
|
for (int i = 0; i < nworkers; i++)
|
|
|
|
__workers[i] =
|
|
|
|
acl_fiber_create(fiber_worker, &mychans.chans[i], 32000);
|
|
|
|
|
|
|
|
__workers[nworkers] = NULL;
|
|
|
|
|
|
|
|
__fibers_count = nworkers;
|
|
|
|
|
|
|
|
for (int i = 0; i < __fibers_max; i++)
|
|
|
|
(void) acl_fiber_create(fiber_result, &mychans, 32000);
|
|
|
|
|
|
|
|
__chan_exit = acl_channel_create(sizeof(unsigned long), 1000);
|
|
|
|
acl_fiber_create(fiber_wait, __chan_exit, 32000);
|
|
|
|
|
|
|
|
acl_fiber_schedule();
|
|
|
|
|
|
|
|
for (int i = 0; i < nworkers; i++)
|
|
|
|
acl_channel_free(mychans.chans[i].chan);
|
|
|
|
|
|
|
|
delete [] mychans.chans;
|
|
|
|
acl_channel_free(__chan_exit);
|
|
|
|
|
|
|
|
delete [] __workers;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|