summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2009-05-25 23:29:18 +0200
committerantirez <antirez@gmail.com>2009-05-25 23:29:18 +0200
commit285add5558c8d6cd6f6e659fbfcbc06af165218f (patch)
treefe0d3cea6ccd13097cbce185a39e6611cc44cf33
parenta0f643ea4c574d7f393a325f8f6e7c6c2e1c476f (diff)
downloadredis-285add5558c8d6cd6f6e659fbfcbc06af165218f.tar.gz
maxclients implemented, see redis.conf for details
-rw-r--r--redis.c19
-rw-r--r--redis.conf10
2 files changed, 28 insertions, 1 deletions
diff --git a/redis.c b/redis.c
index 2d8b5d3e0..1d2d2ae39 100644
--- a/redis.c
+++ b/redis.c
@@ -245,6 +245,7 @@ struct redisServer {
int masterport;
redisClient *master; /* client that is master for this slave */
int replstate;
+ unsigned int maxclients;
/* Sort parameters - qsort_r() is only available under BSD so we
* have to take this state global, in order to pass it to sortCompare() */
int sort_desc;
@@ -862,6 +863,7 @@ static void initServerConfig() {
server.dbfilename = "dump.rdb";
server.requirepass = NULL;
server.shareobjects = 0;
+ server.maxclients = 0;
ResetServerSaveParams();
appendServerSaveParams(60*60,1); /* save after 1 hour and 1 change */
@@ -1020,6 +1022,8 @@ static void loadServerConfig(char *filename) {
if (server.dbnum < 1) {
err = "Invalid number of databases"; goto loaderr;
}
+ } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
+ server.maxclients = atoi(argv[1]);
} else if (!strcasecmp(argv[0],"slaveof") && argc == 3) {
server.masterhost = sdsnew(argv[1]);
server.masterport = atoi(argv[2]);
@@ -1500,6 +1504,7 @@ static void addReplySds(redisClient *c, sds s) {
static void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cport, cfd;
char cip[128];
+ redisClient *c;
REDIS_NOTUSED(el);
REDIS_NOTUSED(mask);
REDIS_NOTUSED(privdata);
@@ -1510,11 +1515,23 @@ static void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
return;
}
redisLog(REDIS_DEBUG,"Accepted %s:%d", cip, cport);
- if (createClient(cfd) == NULL) {
+ if ((c = createClient(cfd)) == NULL) {
redisLog(REDIS_WARNING,"Error allocating resoures for the client");
close(cfd); /* May be already closed, just ingore errors */
return;
}
+ /* If maxclient directive is set and this is one client more... close the
+ * connection. Note that we create the client instead to check before
+ * for this condition, since now the socket is already set in nonblocking
+ * mode and we can send an error for free using the Kernel I/O */
+ if (server.maxclients && listLength(server.clients) > server.maxclients) {
+ char *err = "-ERR max number of clients reached\r\n";
+
+ /* That's a best effort error message, don't check write errors */
+ write(c->fd,err,strlen(err));
+ freeClient(c);
+ return;
+ }
server.stat_numconnections++;
}
diff --git a/redis.conf b/redis.conf
index e8c6cd828..09f926d7b 100644
--- a/redis.conf
+++ b/redis.conf
@@ -78,6 +78,16 @@ databases 16
# requirepass foobared
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default there
+# is no limit, and it's up to the number of file descriptors the Redis process
+# is able to open. The special value '0' means no limts.
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+
+# maxclients 128
+
############################### ADVANCED CONFIG ###############################
# Glue small output buffers together in order to send small replies in a