2019-02-15 14:11:05 -05:00
/*
* Copyright ( c ) 2009 - 2012 , Salvatore Sanfilippo < antirez at gmail dot com >
2019-02-21 00:17:07 -05:00
* Copyright ( c ) 2019 John Sully < john at eqalpha dot com >
2019-02-15 14:11:05 -05:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE .
*/
# include "server.h"
# include "atomicvar.h"
2020-06-22 11:44:11 +02:00
# include "cluster.h"
2019-03-28 06:38:16 +00:00
# include <sys/socket.h>
2019-02-15 14:11:05 -05:00
# include <sys/uio.h>
# include <math.h>
# include <ctype.h>
2019-02-18 23:52:21 -05:00
# include <vector>
2019-02-20 23:30:21 -05:00
# include <mutex>
2019-06-16 16:30:32 -04:00
# include "aelocker.h"
2019-02-15 14:11:05 -05:00
static void setProtocolError ( const char * errstr , client * c ) ;
2021-05-19 02:59:48 +00:00
std : : atomic < int > ProcessingEventsWhileBlocked { 0 } ; /* See processEventsWhileBlocked(). */
2019-02-18 22:25:35 -05:00
2019-02-15 14:11:05 -05:00
/* Return the size consumed from the allocator, for the specified SDS string,
* including internal fragmentation . This function is used in order to compute
* the client output buffer size . */
size_t sdsZmallocSize ( sds s ) {
void * sh = sdsAllocPtr ( s ) ;
return zmalloc_size ( sh ) ;
}
/* Return the amount of memory used by the sds string at object->ptr
2020-10-05 11:15:36 +03:00
* for a string object . This includes internal fragmentation . */
2019-02-15 14:11:05 -05:00
size_t getStringObjectSdsUsedMemory ( robj * o ) {
serverAssertWithInfo ( NULL , o , o - > type = = OBJ_STRING ) ;
switch ( o - > encoding ) {
case OBJ_ENCODING_RAW : return sdsZmallocSize ( ( sds ) ptrFromObj ( o ) ) ;
2020-09-19 21:44:59 +00:00
case OBJ_ENCODING_EMBSTR : return zmalloc_size ( allocPtrFromObj ( o ) ) - sizeof ( robj ) ;
2019-02-15 14:11:05 -05:00
default : return 0 ; /* Just integer encoding for now. */
}
}
2020-10-05 11:15:36 +03:00
/* Return the length of a string object.
* This does NOT includes internal fragmentation or sds unused space . */
size_t getStringObjectLen ( robj * o ) {
serverAssertWithInfo ( NULL , o , o - > type = = OBJ_STRING ) ;
switch ( o - > encoding ) {
2021-01-25 16:07:08 +00:00
case OBJ_ENCODING_RAW : return sdslen ( szFromObj ( o ) ) ;
case OBJ_ENCODING_EMBSTR : return sdslen ( szFromObj ( o ) ) ;
2020-10-05 11:15:36 +03:00
default : return 0 ; /* Just integer encoding for now. */
}
}
2019-02-15 14:11:05 -05:00
/* Client.reply list dup and free methods. */
void * dupClientReplyValue ( void * o ) {
clientReplyBlock * old = ( clientReplyBlock * ) o ;
clientReplyBlock * buf = ( clientReplyBlock * ) zmalloc ( sizeof ( clientReplyBlock ) + old - > size , MALLOC_LOCAL ) ;
memcpy ( buf , o , sizeof ( clientReplyBlock ) + old - > size ) ;
return buf ;
}
2019-04-16 23:16:03 -04:00
void freeClientReplyValue ( const void * o ) {
2019-02-15 14:11:05 -05:00
zfree ( o ) ;
}
int listMatchObjects ( void * a , void * b ) {
return equalStringObjects ( ( robj * ) a , ( robj * ) b ) ;
}
/* This function links the client to the global linked list of clients.
* unlinkClient ( ) does the opposite , among other things . */
void linkClient ( client * c ) {
2020-05-24 01:58:33 -04:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-04-21 14:01:10 -04:00
listAddNodeTail ( g_pserver - > clients , c ) ;
2019-02-15 14:11:05 -05:00
/* Note that we remember the linked list node where the client is stored,
* this way removing the client in unlinkClient ( ) will not require
* a linear scan , but just a constant time operation . */
2019-04-21 14:01:10 -04:00
c - > client_list_node = listLast ( g_pserver - > clients ) ;
2020-01-27 02:55:48 -05:00
if ( c - > conn ! = nullptr ) atomicIncr ( g_pserver - > rgthreadvar [ c - > iel ] . cclients , 1 ) ;
2019-02-15 14:11:05 -05:00
uint64_t id = htonu64 ( c - > id ) ;
2019-04-21 14:01:10 -04:00
raxInsert ( g_pserver - > clients_index , ( unsigned char * ) & id , sizeof ( id ) , c , NULL ) ;
2019-02-15 14:11:05 -05:00
}
2020-11-05 10:51:26 +02:00
/* Initialize client authentication state.
*/
static void clientSetDefaultAuth ( client * c ) {
/* If the default user does not require authentication, the user is
* directly authenticated . */
c - > user = DefaultUser ;
c - > authenticated = ( c - > user - > flags & USER_FLAG_NOPASS ) & &
! ( c - > user - > flags & USER_FLAG_DISABLED ) ;
}
2020-01-27 02:55:48 -05:00
client * createClient ( connection * conn , int iel ) {
2019-02-15 14:11:05 -05:00
client * c = ( client * ) zmalloc ( sizeof ( client ) , MALLOC_LOCAL ) ;
2020-01-28 17:54:00 -05:00
serverAssert ( conn = = nullptr | | ( iel = = ( serverTL - g_pserver - > rgthreadvar ) ) ) ;
2019-02-15 14:11:05 -05:00
2019-02-20 01:20:26 -05:00
c - > iel = iel ;
2019-09-12 10:56:54 +03:00
/* passing NULL as conn it is possible to create a non connected client.
2019-02-15 14:11:05 -05:00
* This is useful since all the commands needs to be executed
* in the context of a client . When commands are executed in other
* contexts ( for instance a Lua script ) we need a non connected client . */
2019-09-12 10:56:54 +03:00
if ( conn ) {
2019-11-20 17:00:40 -05:00
serverAssert ( iel = = ( serverTL - g_pserver - > rgthreadvar ) ) ;
2019-09-12 10:56:54 +03:00
connNonBlock ( conn ) ;
connEnableTcpNoDelay ( conn ) ;
2019-04-21 13:20:45 -04:00
if ( cserver . tcpkeepalive )
2020-01-27 02:55:48 -05:00
connKeepAlive ( conn , cserver . tcpkeepalive ) ;
2020-01-27 19:59:04 -05:00
connSetReadHandler ( conn , readQueryFromClient , true ) ;
2019-09-12 10:56:54 +03:00
connSetPrivateData ( conn , c ) ;
2019-02-15 14:11:05 -05:00
}
selectDb ( c , 0 ) ;
uint64_t client_id ;
2019-05-11 02:20:34 -04:00
client_id = g_pserver - > next_client_id . fetch_add ( 1 ) ;
2019-02-15 14:11:05 -05:00
c - > iel = iel ;
2019-10-22 21:34:51 -04:00
fastlock_init ( & c - > lock , " client " ) ;
2019-02-15 14:11:05 -05:00
c - > id = client_id ;
c - > resp = 2 ;
2019-09-12 10:56:54 +03:00
c - > conn = conn ;
2019-02-15 14:11:05 -05:00
c - > name = NULL ;
c - > bufpos = 0 ;
c - > qb_pos = 0 ;
c - > querybuf = sdsempty ( ) ;
c - > pending_querybuf = sdsempty ( ) ;
c - > querybuf_peak = 0 ;
c - > reqtype = 0 ;
c - > argc = 0 ;
c - > argv = NULL ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
2020-11-10 13:50:03 -08:00
c - > original_argc = 0 ;
c - > original_argv = NULL ;
2019-02-15 14:11:05 -05:00
c - > cmd = c - > lastcmd = NULL ;
c - > multibulklen = 0 ;
c - > bulklen = - 1 ;
c - > sentlen = 0 ;
2019-02-18 22:25:35 -05:00
c - > sentlenAsync = 0 ;
2019-02-15 14:11:05 -05:00
c - > flags = 0 ;
2019-02-20 23:30:21 -05:00
c - > fPendingAsyncWrite = FALSE ;
2020-05-29 17:44:55 -04:00
c - > fPendingAsyncWriteHandler = FALSE ;
2019-04-21 14:01:10 -04:00
c - > ctime = c - > lastinteraction = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
/* If the default user does not require authentication, the user is
* directly authenticated . */
2020-11-05 10:51:26 +02:00
clientSetDefaultAuth ( c ) ;
2019-02-15 14:11:05 -05:00
c - > replstate = REPL_STATE_NONE ;
c - > repl_put_online_on_ack = 0 ;
c - > reploff = 0 ;
c - > read_reploff = 0 ;
c - > repl_ack_off = 0 ;
c - > repl_ack_time = 0 ;
2021-04-15 16:18:51 +02:00
c - > repl_last_partial_write = 0 ;
2019-02-15 14:11:05 -05:00
c - > slave_listening_port = 0 ;
2021-02-21 11:22:36 +02:00
c - > slave_addr = NULL ;
2019-02-15 14:11:05 -05:00
c - > slave_capa = SLAVE_CAPA_NONE ;
c - > reply = listCreate ( ) ;
c - > reply_bytes = 0 ;
c - > obuf_soft_limit_reached_time = 0 ;
listSetFreeMethod ( c - > reply , freeClientReplyValue ) ;
listSetDupMethod ( c - > reply , dupClientReplyValue ) ;
c - > btype = BLOCKED_NONE ;
c - > bpop . timeout = 0 ;
c - > bpop . keys = dictCreate ( & objectKeyHeapPointerValueDictType , NULL ) ;
c - > bpop . target = NULL ;
c - > bpop . xread_group = NULL ;
c - > bpop . xread_consumer = NULL ;
c - > bpop . xread_group_noack = 0 ;
c - > bpop . numreplicas = 0 ;
c - > bpop . reploffset = 0 ;
c - > woff = 0 ;
c - > watched_keys = listCreate ( ) ;
c - > pubsub_channels = dictCreate ( & objectKeyPointerValueDictType , NULL ) ;
c - > pubsub_patterns = listCreate ( ) ;
c - > peerid = NULL ;
2020-10-28 21:13:44 +02:00
c - > sockname = NULL ;
2019-02-15 14:11:05 -05:00
c - > client_list_node = NULL ;
2020-10-15 23:10:17 +00:00
c - > replyAsync = NULL ;
2021-01-07 23:36:54 -08:00
c - > paused_list_node = NULL ;
2019-06-29 20:08:41 -04:00
c - > client_tracking_redirection = 0 ;
2019-08-26 20:18:52 -04:00
c - > casyncOpsPending = 0 ;
2020-03-04 17:09:12 -05:00
c - > master_error = 0 ;
2019-03-24 15:39:10 -04:00
memset ( c - > uuid , 0 , UUID_BINARY_LEN ) ;
2019-02-18 22:25:35 -05:00
2020-02-11 17:26:27 +01:00
c - > client_tracking_prefixes = NULL ;
2020-04-07 12:07:09 +02:00
c - > client_cron_last_memory_usage = 0 ;
c - > client_cron_last_memory_type = CLIENT_TYPE_NORMAL ;
2019-02-26 01:23:11 +00:00
c - > auth_callback = NULL ;
c - > auth_callback_privdata = NULL ;
c - > auth_module = NULL ;
2019-02-15 14:11:05 -05:00
listSetFreeMethod ( c - > pubsub_patterns , decrRefCountVoid ) ;
listSetMatchMethod ( c - > pubsub_patterns , listMatchObjects ) ;
2019-09-12 10:56:54 +03:00
if ( conn ) linkClient ( c ) ;
2019-02-15 14:11:05 -05:00
initClientMultiState ( c ) ;
2019-02-20 01:20:26 -05:00
AssertCorrectThread ( c ) ;
2019-02-15 14:11:05 -05:00
return c ;
}
Squash merging 125 typo/grammar/comment/doc PRs (#7773)
List of squashed commits or PRs
===============================
commit 66801ea
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Jan 13 00:54:31 2020 -0500
typo fix in acl.c
commit 46f55db
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun Sep 6 18:24:11 2020 +0300
Updates a couple of comments
Specifically:
* RM_AutoMemory completed instead of pointing to docs
* Updated link to custom type doc
commit 61a2aa0
Author: xindoo <xindoo@qq.com>
Date: Tue Sep 1 19:24:59 2020 +0800
Correct errors in code comments
commit a5871d1
Author: yz1509 <pro-756@qq.com>
Date: Tue Sep 1 18:36:06 2020 +0800
fix typos in module.c
commit 41eede7
Author: bookug <bookug@qq.com>
Date: Sat Aug 15 01:11:33 2020 +0800
docs: fix typos in comments
commit c303c84
Author: lazy-snail <ws.niu@outlook.com>
Date: Fri Aug 7 11:15:44 2020 +0800
fix spelling in redis.conf
commit 1eb76bf
Author: zhujian <zhujianxyz@gmail.com>
Date: Thu Aug 6 15:22:10 2020 +0800
add a missing 'n' in comment
commit 1530ec2
Author: Daniel Dai <764122422@qq.com>
Date: Mon Jul 27 00:46:35 2020 -0400
fix spelling in tracking.c
commit e517b31
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:32 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit c300eff
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:23 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit 4c058a8
Author: 陈浩鹏 <chenhaopeng@heytea.com>
Date: Thu Jun 25 19:00:56 2020 +0800
Grammar fix and clarification
commit 5fcaa81
Author: bodong.ybd <bodong.ybd@alibaba-inc.com>
Date: Fri Jun 19 10:09:00 2020 +0800
Fix typos
commit 4caca9a
Author: Pruthvi P <pruthvi@ixigo.com>
Date: Fri May 22 00:33:22 2020 +0530
Fix typo eviciton => eviction
commit b2a25f6
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Sun May 17 12:39:59 2020 -0400
Fix a typo.
commit 12842ae
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun May 3 17:16:59 2020 -0400
fix spelling in redis conf
commit ddba07c
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Sat May 2 23:25:34 2020 +0100
Correct a "conflicts" spelling error.
commit 8fc7bf2
Author: Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Date: Thu Apr 30 10:25:27 2020 +0900
docs: fix EXPIRE_FAST_CYCLE_DURATION to ACTIVE_EXPIRE_CYCLE_FAST_DURATION
commit 9b2b67a
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Fri Apr 24 11:46:22 2020 -0400
Fix a typo.
commit 0746f10
Author: devilinrust <63737265+devilinrust@users.noreply.github.com>
Date: Thu Apr 16 00:17:53 2020 +0200
Fix typos in server.c
commit 92b588d
Author: benjessop12 <56115861+benjessop12@users.noreply.github.com>
Date: Mon Apr 13 13:43:55 2020 +0100
Fix spelling mistake in lazyfree.c
commit 1da37aa
Merge: 2d4ba28 c90b2a4
Author: hwware <wen.hui.ware@gmail.com>
Date: Thu Mar 5 22:41:31 2020 -0500
Merge remote-tracking branch 'upstream/unstable' into expiretypofix
commit 2d4ba28
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Mar 2 00:09:40 2020 -0500
fix typo in expire.c
commit 1a746f7
Author: SennoYuki <minakami1yuki@gmail.com>
Date: Thu Feb 27 16:54:32 2020 +0800
fix typo
commit 8599b1a
Author: dongheejeong <donghee950403@gmail.com>
Date: Sun Feb 16 20:31:43 2020 +0000
Fix typo in server.c
commit f38d4e8
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun Feb 2 22:58:38 2020 -0500
fix typo in evict.c
commit fe143fc
Author: Leo Murillo <leonardo.murillo@gmail.com>
Date: Sun Feb 2 01:57:22 2020 -0600
Fix a few typos in redis.conf
commit 1ab4d21
Author: viraja1 <anchan.viraj@gmail.com>
Date: Fri Dec 27 17:15:58 2019 +0530
Fix typo in Latency API docstring
commit ca1f70e
Author: gosth <danxuedexing@qq.com>
Date: Wed Dec 18 15:18:02 2019 +0800
fix typo in sort.c
commit a57c06b
Author: ZYunH <zyunhjob@163.com>
Date: Mon Dec 16 22:28:46 2019 +0800
fix-zset-typo
commit b8c92b5
Author: git-hulk <hulk.website@gmail.com>
Date: Mon Dec 16 15:51:42 2019 +0800
FIX: typo in cluster.c, onformation->information
commit 9dd981c
Author: wujm2007 <jim.wujm@gmail.com>
Date: Mon Dec 16 09:37:52 2019 +0800
Fix typo
commit e132d7a
Author: Sebastien Williams-Wynn <s.williamswynn.mail@gmail.com>
Date: Fri Nov 15 00:14:07 2019 +0000
Minor typo change
commit 47f44d5
Author: happynote3966 <01ssrmikururudevice01@gmail.com>
Date: Mon Nov 11 22:08:48 2019 +0900
fix comment typo in redis-cli.c
commit b8bdb0d
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 18:00:17 2019 +0800
Fix a spelling mistake of comments in defragDictBucketCallback
commit 0def46a
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 13:09:27 2019 +0800
fix some spelling mistakes of comments in defrag.c
commit f3596fd
Author: Phil Rajchgot <tophil@outlook.com>
Date: Sun Oct 13 02:02:32 2019 -0400
Typo and grammar fixes
Redis and its documentation are great -- just wanted to submit a few corrections in the spirit of Hacktoberfest. Thanks for all your work on this project. I use it all the time and it works beautifully.
commit 2b928cd
Author: KangZhiDong <worldkzd@gmail.com>
Date: Sun Sep 1 07:03:11 2019 +0800
fix typos
commit 33aea14
Author: Axlgrep <axlgrep@gmail.com>
Date: Tue Aug 27 11:02:18 2019 +0800
Fixed eviction spelling issues
commit e282a80
Author: Simen Flatby <simen@oms.no>
Date: Tue Aug 20 15:25:51 2019 +0200
Update comments to reflect prop name
In the comments the prop is referenced as replica-validity-factor,
but it is really named cluster-replica-validity-factor.
commit 74d1f9a
Author: Jim Green <jimgreen2013@qq.com>
Date: Tue Aug 20 20:00:31 2019 +0800
fix comment error, the code is ok
commit eea1407
Author: Liao Tonglang <liaotonglang@gmail.com>
Date: Fri May 31 10:16:18 2019 +0800
typo fix
fix cna't to can't
commit 0da553c
Author: KAWACHI Takashi <tkawachi@gmail.com>
Date: Wed Jul 17 00:38:16 2019 +0900
Fix typo
commit 7fc8fb6
Author: Michael Prokop <mika@grml.org>
Date: Tue May 28 17:58:42 2019 +0200
Typo fixes
s/familar/familiar/
s/compatiblity/compatibility/
s/ ot / to /
s/itsef/itself/
commit 5f46c9d
Author: zhumoing <34539422+zhumoing@users.noreply.github.com>
Date: Tue May 21 21:16:50 2019 +0800
typo-fixes
typo-fixes
commit 321dfe1
Author: wxisme <850885154@qq.com>
Date: Sat Mar 16 15:10:55 2019 +0800
typo fix
commit b4fb131
Merge: 267e0e6 4842305
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Fri Feb 8 22:55:45 2019 +0200
Merge branch 'unstable' of antirez/redis into unstable
commit 267e0e6
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Wed Jan 30 21:26:04 2019 +0200
Minor typo fix
commit 30544e7
Author: inshal96 <39904558+inshal96@users.noreply.github.com>
Date: Fri Jan 4 16:54:50 2019 +0500
remove an extra 'a' in the comments
commit 337969d
Author: BrotherGao <yangdongheng11@gmail.com>
Date: Sat Dec 29 12:37:29 2018 +0800
fix typo in redis.conf
commit 9f4b121
Merge: 423a030 19d0ece
Author: BrotherGao <yangdongheng@xiaomi.com>
Date: Sat Dec 29 11:41:12 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 423a030
Merge: 42b02b7 0423081
Author: 杨东衡 <yangdongheng@xiaomi.com>
Date: Tue Dec 4 23:56:11 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 42b02b7
Merge: 8c7dcff efa96f0
Author: Dongheng Yang <yangdongheng11@gmail.com>
Date: Sun Oct 28 15:54:23 2018 +0800
Merge pull request #1 from antirez/unstable
update local data
commit 714b589
Author: Christian <crifei93@gmail.com>
Date: Fri Dec 28 01:17:26 2018 +0100
fix typo "resulution"
commit e23259d
Author: garenchan <1412950785@qq.com>
Date: Wed Dec 26 09:58:35 2018 +0800
fix typo: segfauls -> segfault
commit a9359f8
Author: xjp <jianping_xie@aliyun.com>
Date: Tue Dec 18 17:31:44 2018 +0800
Fixed REDISMODULE_H spell bug
commit a12c3e4
Author: jdiaz <jrd.palacios@gmail.com>
Date: Sat Dec 15 23:39:52 2018 -0600
Fixes hyperloglog hash function comment block description
commit 770eb11
Author: 林上耀 <1210tom@163.com>
Date: Sun Nov 25 17:16:10 2018 +0800
fix typo
commit fd97fbb
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Fri Nov 23 17:14:01 2018 +0100
Correct "unsupported" typo.
commit a85522d
Author: Jungnam Lee <jungnam.lee@oracle.com>
Date: Thu Nov 8 23:01:29 2018 +0900
fix typo in test comments
commit ade8007
Author: Arun Kumar <palerdot@users.noreply.github.com>
Date: Tue Oct 23 16:56:35 2018 +0530
Fixed grammatical typo
Fixed typo for word 'dictionary'
commit 869ee39
Author: Hamid Alaei <hamid.a85@gmail.com>
Date: Sun Aug 12 16:40:02 2018 +0430
fix documentations: (ThreadSafeContextStart/Stop -> ThreadSafeContextLock/Unlock), minor typo
commit f89d158
Author: Mayank Jain <mayankjain255@gmail.com>
Date: Tue Jul 31 23:01:21 2018 +0530
Updated README.md with some spelling corrections.
Made correction in spelling of some misspelled words.
commit 892198e
Author: dsomeshwar <someshwar.dhayalan@gmail.com>
Date: Sat Jul 21 23:23:04 2018 +0530
typo fix
commit 8a4d780
Author: Itamar Haber <itamar@redislabs.com>
Date: Mon Apr 30 02:06:52 2018 +0300
Fixes some typos
commit e3acef6
Author: Noah Rosamilia <ivoahivoah@gmail.com>
Date: Sat Mar 3 23:41:21 2018 -0500
Fix typo in /deps/README.md
commit 04442fb
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:32:42 2018 +0800
Fix typo in readSyncBulkPayload() comment.
commit 9f36880
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:20:37 2018 +0800
replication.c comment: run_id -> replid.
commit f866b4a
Author: Francesco 'makevoid' Canessa <makevoid@gmail.com>
Date: Thu Feb 22 22:01:56 2018 +0000
fix comment typo in server.c
commit 0ebc69b
Author: 줍 <jubee0124@gmail.com>
Date: Mon Feb 12 16:38:48 2018 +0900
Fix typo in redis.conf
Fix `five behaviors` to `eight behaviors` in [this sentence ](antirez/redis@unstable/redis.conf#L564)
commit b50a620
Author: martinbroadhurst <martinbroadhurst@users.noreply.github.com>
Date: Thu Dec 28 12:07:30 2017 +0000
Fix typo in valgrind.sup
commit 7d8f349
Author: Peter Boughton <peter@sorcerersisle.com>
Date: Mon Nov 27 19:52:19 2017 +0000
Update CONTRIBUTING; refer doc updates to redis-doc repo.
commit 02dec7e
Author: Klauswk <klauswk1@hotmail.com>
Date: Tue Oct 24 16:18:38 2017 -0200
Fix typo in comment
commit e1efbc8
Author: chenshi <baiwfg2@gmail.com>
Date: Tue Oct 3 18:26:30 2017 +0800
Correct two spelling errors of comments
commit 93327d8
Author: spacewander <spacewanderlzx@gmail.com>
Date: Wed Sep 13 16:47:24 2017 +0800
Update the comment for OBJ_ENCODING_EMBSTR_SIZE_LIMIT's value
The value of OBJ_ENCODING_EMBSTR_SIZE_LIMIT is 44 now instead of 39.
commit 63d361f
Author: spacewander <spacewanderlzx@gmail.com>
Date: Tue Sep 12 15:06:42 2017 +0800
Fix <prevlen> related doc in ziplist.c
According to the definition of ZIP_BIG_PREVLEN and other related code,
the guard of single byte <prevlen> should be 254 instead of 255.
commit ebe228d
Author: hanael80 <hanael80@gmail.com>
Date: Tue Aug 15 09:09:40 2017 +0900
Fix typo
commit 6b696e6
Author: Matt Robenolt <matt@ydekproductions.com>
Date: Mon Aug 14 14:50:47 2017 -0700
Fix typo in LATENCY DOCTOR output
commit a2ec6ae
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 15 14:15:16 2017 +0800
Fix a typo: form => from
commit 3ab7699
Author: caosiyang <caosiyang@qiyi.com>
Date: Thu Aug 10 18:40:33 2017 +0800
Fix a typo: replicationFeedSlavesFromMaster() => replicationFeedSlavesFromMasterStream()
commit 72d43ef
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 8 15:57:25 2017 +0800
fix a typo: servewr => server
commit 707c958
Author: Bo Cai <charpty@gmail.com>
Date: Wed Jul 26 21:49:42 2017 +0800
redis-cli.c typo: conut -> count.
Signed-off-by: Bo Cai <charpty@gmail.com>
commit b9385b2
Author: JackDrogon <jack.xsuperman@gmail.com>
Date: Fri Jun 30 14:22:31 2017 +0800
Fix some spell problems
commit 20d9230
Author: akosel <aaronjkosel@gmail.com>
Date: Sun Jun 4 19:35:13 2017 -0500
Fix typo
commit b167bfc
Author: Krzysiek Witkowicz <krzysiekwitkowicz@gmail.com>
Date: Mon May 22 21:32:27 2017 +0100
Fix #4008 small typo in comment
commit 2b78ac8
Author: Jake Clarkson <jacobwclarkson@gmail.com>
Date: Wed Apr 26 15:49:50 2017 +0100
Correct typo in tests/unit/hyperloglog.tcl
commit b0f1cdb
Author: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Wed Apr 19 14:25:18 2017 -0700
Fix typo
commit a90b0f9
Author: charsyam <charsyam@naver.com>
Date: Thu Mar 16 18:19:53 2017 +0900
fix typos
fix typos
fix typos
commit 8430a79
Author: Richard Hart <richardhart92@gmail.com>
Date: Mon Mar 13 22:17:41 2017 -0400
Fixed log message typo in listenToPort.
commit 481a1c2
Author: Vinod Kumar <kumar003vinod@gmail.com>
Date: Sun Jan 15 23:04:51 2017 +0530
src/db.c: Correct "save" -> "safe" typo
commit 586b4d3
Author: wangshaonan <wshn13@gmail.com>
Date: Wed Dec 21 20:28:27 2016 +0800
Fix typo they->the in helloworld.c
commit c1c4b5e
Author: Jenner <hypxm@qq.com>
Date: Mon Dec 19 16:39:46 2016 +0800
typo error
commit 1ee1a3f
Author: tielei <43289893@qq.com>
Date: Mon Jul 18 13:52:25 2016 +0800
fix some comments
commit 11a41fb
Author: Otto Kekäläinen <otto@seravo.fi>
Date: Sun Jul 3 10:23:55 2016 +0100
Fix spelling in documentation and comments
commit 5fb5d82
Author: francischan <f1ancis621@gmail.com>
Date: Tue Jun 28 00:19:33 2016 +0800
Fix outdated comments about redis.c file.
It should now refer to server.c file.
commit 6b254bc
Author: lmatt-bit <lmatt123n@gmail.com>
Date: Thu Apr 21 21:45:58 2016 +0800
Refine the comment of dictRehashMilliseconds func
SLAVECONF->REPLCONF in comment - by andyli029
commit ee9869f
Author: clark.kang <charsyam@naver.com>
Date: Tue Mar 22 11:09:51 2016 +0900
fix typos
commit f7b3b11
Author: Harisankar H <harisankarh@gmail.com>
Date: Wed Mar 9 11:49:42 2016 +0530
Typo correction: "faield" --> "failed"
Typo correction: "faield" --> "failed"
commit 3fd40fc
Author: Itamar Haber <itamar@redislabs.com>
Date: Thu Feb 25 10:31:51 2016 +0200
Fixes a typo in comments
commit 621c160
Author: Prayag Verma <prayag.verma@gmail.com>
Date: Mon Feb 1 12:36:20 2016 +0530
Fix typo in Readme.md
Spelling mistakes -
`eviciton` > `eviction`
`familar` > `familiar`
commit d7d07d6
Author: WonCheol Lee <toctoc21c@gmail.com>
Date: Wed Dec 30 15:11:34 2015 +0900
Typo fixed
commit a4dade7
Author: Felix Bünemann <buenemann@louis.info>
Date: Mon Dec 28 11:02:55 2015 +0100
[ci skip] Improve supervised upstart config docs
This mentions that "expect stop" is required for supervised upstart
to work correctly. See http://upstart.ubuntu.com/cookbook/#expect-stop
for an explanation.
commit d9caba9
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:30:03 2015 +1100
README: Remove trailing whitespace
commit 72d42e5
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:32 2015 +1100
README: Fix typo. th => the
commit dd6e957
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:20 2015 +1100
README: Fix typo. familar => familiar
commit 3a12b23
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:28:54 2015 +1100
README: Fix typo. eviciton => eviction
commit 2d1d03b
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:21:45 2015 +1100
README: Fix typo. sever => server
commit 3973b06
Author: Itamar Haber <itamar@garantiadata.com>
Date: Sat Dec 19 17:01:20 2015 +0200
Typo fix
commit 4f2e460
Author: Steve Gao <fu@2token.com>
Date: Fri Dec 4 10:22:05 2015 +0800
Update README - fix typos
commit b21667c
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:48:37 2015 +0800
delete redundancy color judge in sdscatcolor
commit 88894c7
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:14:42 2015 +0800
the example output shoule be HelloWorld
commit 2763470
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 17:41:39 2015 +0800
modify error word keyevente
Signed-off-by: binyan <binbin.yan@nokia.com>
commit 0847b3d
Author: Bruno Martins <bscmartins@gmail.com>
Date: Wed Nov 4 11:37:01 2015 +0000
typo
commit bbb9e9e
Author: dawedawe <dawedawe@gmx.de>
Date: Fri Mar 27 00:46:41 2015 +0100
typo: zimap -> zipmap
commit 5ed297e
Author: Axel Advento <badwolf.bloodseeker.rev@gmail.com>
Date: Tue Mar 3 15:58:29 2015 +0800
Fix 'salve' typos to 'slave'
commit edec9d6
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Wed Jun 12 14:12:47 2019 +0200
Update README.md
Co-Authored-By: Qix <Qix-@users.noreply.github.com>
commit 692a7af
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Tue May 28 14:32:04 2019 +0200
grammar
commit d962b0a
Author: Nick Frost <nickfrostatx@gmail.com>
Date: Wed Jul 20 15:17:12 2016 -0700
Minor grammar fix
commit 24fff01aaccaf5956973ada8c50ceb1462e211c6 (typos)
Author: Chad Miller <chadm@squareup.com>
Date: Tue Sep 8 13:46:11 2020 -0400
Fix faulty comment about operation of unlink()
commit 3cd5c1f3326c52aa552ada7ec797c6bb16452355
Author: Kevin <kevin.xgr@gmail.com>
Date: Wed Nov 20 00:13:50 2019 +0800
Fix typo in server.c.
From a83af59 Mon Sep 17 00:00:00 2001
From: wuwo <wuwo@wacai.com>
Date: Fri, 17 Mar 2017 20:37:45 +0800
Subject: [PATCH] falure to failure
From c961896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B7=A6=E6=87=B6?= <veficos@gmail.com>
Date: Sat, 27 May 2017 15:33:04 +0800
Subject: [PATCH] fix typo
From e600ef2 Mon Sep 17 00:00:00 2001
From: "rui.zou" <rui.zou@yunify.com>
Date: Sat, 30 Sep 2017 12:38:15 +0800
Subject: [PATCH] fix a typo
From c7d07fa Mon Sep 17 00:00:00 2001
From: Alexandre Perrin <alex@kaworu.ch>
Date: Thu, 16 Aug 2018 10:35:31 +0200
Subject: [PATCH] deps README.md typo
From b25cb67 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 10:55:37 +0300
Subject: [PATCH 1/2] fix typos in header
From ad28ca6 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 11:02:36 +0300
Subject: [PATCH 2/2] fix typos
commit 34924cdedd8552466fc22c1168d49236cb7ee915
Author: Adrian Lynch <adi_ady_ade@hotmail.com>
Date: Sat Apr 4 21:59:15 2015 +0100
Typos fixed
commit fd2a1e7
Author: Jan <jsteemann@users.noreply.github.com>
Date: Sat Oct 27 19:13:01 2018 +0200
Fix typos
Fix typos
commit e14e47c1a234b53b0e103c5f6a1c61481cbcbb02
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:30:07 2019 -0500
Fix multiple misspellings of "following"
commit 79b948ce2dac6b453fe80995abbcaac04c213d5a
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:24:28 2019 -0500
Fix misspelling of create-cluster
commit 1fffde52666dc99ab35efbd31071a4c008cb5a71
Author: Andy Lester <andy@petdance.com>
Date: Wed Jul 31 17:57:56 2019 -0500
Fix typos
commit 204c9ba9651e9e05fd73936b452b9a30be456cfe
Author: Xiaobo Zhu <xiaobo.zhu@shopee.com>
Date: Tue Aug 13 22:19:25 2019 +0800
fix typos
Squashed commit of the following:
commit 1d9aaf8
Author: danmedani <danmedani@gmail.com>
Date: Sun Aug 2 11:40:26 2015 -0700
README typo fix.
Squashed commit of the following:
commit 32bfa7c
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Jul 6 21:15:08 2015 +0200
Fixed grammer
Squashed commit of the following:
commit b24f69c
Author: Sisir Koppaka <sisir.koppaka@gmail.com>
Date: Mon Mar 2 22:38:45 2015 -0500
utils/hashtable/rehashing.c: Fix typos
Squashed commit of the following:
commit 4e04082
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Mar 23 08:22:21 2015 +0000
Small config file documentation improvements
Squashed commit of the following:
commit acb8773
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:52:48 2015 -0700
Typo and grammar fixes in readme
commit 2eb75b6
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:36:18 2015 -0700
fixed redis.conf comment
Squashed commit of the following:
commit a8249a2
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri Dec 11 11:39:52 2015 +0530
Revise correction of typos.
Squashed commit of the following:
commit 3c02028
Author: zhaojun11 <zhaojun11@jd.com>
Date: Wed Jan 17 19:05:28 2018 +0800
Fix typos include two code typos in cluster.c and latency.c
Squashed commit of the following:
commit 9dba47c
Author: q191201771 <191201771@qq.com>
Date: Sat Jan 4 11:31:04 2020 +0800
fix function listCreate comment in adlist.c
Update src/server.c
commit 2c7c2cb536e78dd211b1ac6f7bda00f0f54faaeb
Author: charpty <charpty@gmail.com>
Date: Tue May 1 23:16:59 2018 +0800
server.c typo: modules system dictionary type comment
Signed-off-by: charpty <charpty@gmail.com>
commit a8395323fb63cb59cb3591cb0f0c8edb7c29a680
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun May 6 00:25:18 2018 +0300
Updates test_helper.tcl's help with undocumented options
Specifically:
* Host
* Port
* Client
commit bde6f9ced15755cd6407b4af7d601b030f36d60b
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 15:19:19 2018 +0800
fix comments in deps files
commit 3172474ba991532ab799ee1873439f3402412331
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 14:33:49 2018 +0800
fix some comments
commit 01b6f2b6858b5cf2ce4ad5092d2c746e755f53f0
Author: Thor Juhasz <thor@juhasz.pro>
Date: Sun Nov 18 14:37:41 2018 +0100
Minor fixes to comments
Found some parts a little unclear on a first read, which prompted me to have a better look at the file and fix some minor things I noticed.
Fixing minor typos and grammar. There are no changes to configuration options.
These changes are only meant to help the user better understand the explanations to the various configuration options
(cherry picked from commit 285ef446b05e09013556e7a490677494a9b4bb3e)
2020-09-10 13:43:38 +03:00
/* This function puts the client in the queue of clients that should write
2019-02-15 14:11:05 -05:00
* their output buffers to the socket . Note that it does not * yet * install
* the write handler , to start clients are put in a queue of clients that need
* to write , so we try to do that before returning in the event loop ( see the
* handleClientsWithPendingWrites ( ) function ) .
* If we fail and there is more data to write , compared to what the socket
* buffers can hold , then we ' ll really install the handler . */
void clientInstallWriteHandler ( client * c ) {
/* Schedule the client to write the output buffers to the socket only
2019-10-13 12:29:20 -04:00
* if not already done and , for slaves , if the replica can actually receive
2019-02-15 14:11:05 -05:00
* writes at this stage . */
if ( ! ( c - > flags & CLIENT_PENDING_WRITE ) & &
( c - > replstate = = REPL_STATE_NONE | |
( c - > replstate = = SLAVE_STATE_ONLINE & & ! c - > repl_put_online_on_ack ) ) )
{
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2019-02-22 21:00:14 -05:00
serverAssert ( c - > lock . fOwnLock ( ) ) ;
2019-02-15 14:11:05 -05:00
/* Here instead of installing the write handler, we just flag the
* client and put it into a list of clients that have something
* to write to the socket . This way before re - entering the event
* loop , we can try to directly write to the client sockets avoiding
* a system call . We ' ll only really install the write handler if
* we ' ll not be able to write the whole reply at once . */
c - > flags | = CLIENT_PENDING_WRITE ;
2019-04-21 14:01:10 -04:00
std : : unique_lock < fastlock > lockf ( g_pserver - > rgthreadvar [ c - > iel ] . lockPendingWrite ) ;
2019-06-16 20:26:03 -04:00
g_pserver - > rgthreadvar [ c - > iel ] . clients_pending_write . push_back ( c ) ;
2019-02-18 22:25:35 -05:00
}
}
void clientInstallAsyncWriteHandler ( client * c ) {
2019-03-07 19:13:01 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-20 23:30:21 -05:00
if ( ! ( c - > fPendingAsyncWrite ) ) {
c - > fPendingAsyncWrite = TRUE ;
2019-02-18 22:25:35 -05:00
listAddNodeHead ( serverTL - > clients_pending_asyncwrite , c ) ;
2019-02-15 14:11:05 -05:00
}
}
/* This function is called every time we are going to transmit new data
* to the client . The behavior is the following :
*
* If the client should receive new data ( normal clients will ) the function
* returns C_OK , and make sure to install the write handler in our event
* loop so that when the socket is writable new data gets written .
*
* If the client should not receive new data , because it is a fake client
* ( used to load AOF in memory ) , a master or because the setup of the write
* handler failed , the function returns C_ERR .
*
* The function may return C_OK without actually installing the write
* event handler in the following cases :
*
* 1 ) The event handler should already be installed since the output buffer
* already contains something .
2019-10-13 12:29:20 -04:00
* 2 ) The client is a replica but not yet online , so we want to just accumulate
2019-02-15 14:11:05 -05:00
* writes in the buffer but not actually sending them yet .
*
* Typically gets called every time a reply is built , before adding more
* data to the clients output buffers . If the function returns C_ERR no
* data should be appended to the output buffers . */
2020-10-24 02:18:03 +00:00
int prepareClientToWrite ( client * c ) {
bool fAsync = ! FCorrectThread ( c ) ; // Not async if we're on the right thread
if ( ! fAsync ) {
2020-01-27 02:55:48 -05:00
serverAssert ( c - > conn = = nullptr | | c - > lock . fOwnLock ( ) ) ;
2019-10-24 23:07:02 -04:00
} else {
serverAssert ( GlobalLocksAcquired ( ) ) ;
}
2019-02-18 22:25:35 -05:00
2020-10-26 02:28:38 +00:00
auto flags = c - > flags . load ( std : : memory_order_relaxed ) ;
if ( flags & CLIENT_FORCE_REPLY ) return C_OK ; // FORCE REPLY means we're doing something else with the buffer.
2019-04-06 00:14:27 -04:00
// do not install a write handler
2019-02-15 14:11:05 -05:00
/* If it's the Lua client we always return ok without installing any
* handler since there is no socket at all . */
2020-10-26 02:28:38 +00:00
if ( flags & ( CLIENT_LUA | CLIENT_MODULE ) ) return C_OK ;
2019-02-15 14:11:05 -05:00
Don't write replies if close the client ASAP (#7202)
Before this commit, we would have continued to add replies to the reply buffer even if client
output buffer limit is reached, so the used memory would keep increasing over the configured limit.
What's more, we shouldn’t write any reply to the client if it is set 'CLIENT_CLOSE_ASAP' flag
because that doesn't conform to its definition and we will close all clients flagged with
'CLIENT_CLOSE_ASAP' in ‘beforeSleep’.
Because of code execution order, before this, we may firstly write to part of the replies to
the socket before disconnecting it, but in fact, we may can’t send the full replies to clients
since OS socket buffer is limited. But this unexpected behavior makes some commands work well,
for instance ACL DELUSER, if the client deletes the current user, we need to send reply to client
and close the connection, but before, we close the client firstly and write the reply to reply
buffer. secondly, we shouldn't do this despite the fact it works well in most cases.
We add a flag 'CLIENT_CLOSE_AFTER_COMMAND' to mark clients, this flag means we will close the
client after executing commands and send all entire replies, so that we can write replies to
reply buffer during executing commands, send replies to clients, and close them later.
We also fix some implicit problems. If client output buffer limit is enforced in 'multi/exec',
all commands will be executed completely in redis and clients will not read any reply instead of
partial replies. Even more, if the client executes 'ACL deluser' the using user in 'multi/exec',
it will not read the replies after 'ACL deluser' just like before executing 'client kill' itself
in 'multi/exec'.
We added some tests for output buffer limit breach during multi-exec and using a pipeline of
many small commands rather than one with big response.
Co-authored-by: Oran Agra <oran@redislabs.com>
(cherry picked from commit 3085577c095a0f3b1261f6dbf016d7701aadab46)
2020-09-24 21:01:41 +08:00
/* If CLIENT_CLOSE_ASAP flag is set, we need not write anything. */
if ( c - > flags & CLIENT_CLOSE_ASAP ) return C_ERR ;
2019-02-15 14:11:05 -05:00
/* CLIENT REPLY OFF / SKIP handling: don't send replies. */
2020-10-26 02:28:38 +00:00
if ( flags & ( CLIENT_REPLY_OFF | CLIENT_REPLY_SKIP ) ) return C_ERR ;
2019-02-15 14:11:05 -05:00
/* Masters don't receive replies, unless CLIENT_MASTER_FORCE_REPLY flag
* is set . */
2020-10-26 02:28:38 +00:00
if ( ( flags & CLIENT_MASTER ) & &
! ( flags & CLIENT_MASTER_FORCE_REPLY ) ) return C_ERR ;
2019-02-15 14:11:05 -05:00
2019-09-12 10:56:54 +03:00
if ( ! c - > conn ) return C_ERR ; /* Fake client for AOF loading. */
2019-02-15 14:11:05 -05:00
/* Schedule the client to write the output buffers to the socket, unless
* it should already be setup to do so ( it has already pending data ) . */
2019-02-22 01:24:16 -05:00
if ( ! fAsync & & ! clientHasPendingReplies ( c ) ) clientInstallWriteHandler ( c ) ;
2019-02-20 23:30:21 -05:00
if ( fAsync & & ! ( c - > fPendingAsyncWrite ) ) clientInstallAsyncWriteHandler ( c ) ;
2019-02-15 14:11:05 -05:00
/* Authorize the caller to queue in the output buffer of this client. */
return C_OK ;
}
/* -----------------------------------------------------------------------------
* Low level functions to add more data to output buffers .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2020-12-08 16:41:20 +02:00
/* Attempts to add the reply to the static buffer in the client struct.
* Returns C_ERR if the buffer is full , or the reply list is not empty ,
* in which case the reply must be added to the reply list . */
2020-10-24 02:18:03 +00:00
int _addReplyToBuffer ( client * c , const char * s , size_t len ) {
2020-10-13 06:35:16 +00:00
if ( c - > flags . load ( std : : memory_order_relaxed ) & CLIENT_CLOSE_AFTER_REPLY ) return C_OK ;
2019-02-15 14:11:05 -05:00
2020-10-24 02:18:03 +00:00
bool fAsync = ! FCorrectThread ( c ) ;
2019-02-18 22:25:35 -05:00
if ( fAsync )
{
2019-03-07 19:13:01 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2020-10-15 23:10:17 +00:00
if ( c - > replyAsync = = nullptr | | ( c - > replyAsync - > size - c - > replyAsync - > used ) < len )
2019-02-18 22:25:35 -05:00
{
2020-10-15 23:10:17 +00:00
if ( c - > replyAsync = = nullptr ) {
size_t newsize = std : : max ( len , ( size_t ) PROTO_ASYNC_REPLY_CHUNK_BYTES ) ;
clientReplyBlock * replyNew = ( clientReplyBlock * ) zmalloc ( sizeof ( clientReplyBlock ) + newsize ) ;
2021-05-19 02:59:48 +00:00
replyNew - > size = zmalloc_usable_size ( replyNew ) - sizeof ( clientReplyBlock ) ;
2020-10-15 23:10:17 +00:00
replyNew - > used = 0 ;
c - > replyAsync = replyNew ;
} else {
size_t newsize = std : : max ( c - > replyAsync - > used + len , c - > replyAsync - > size * 2 ) ;
clientReplyBlock * replyNew = ( clientReplyBlock * ) zmalloc ( sizeof ( clientReplyBlock ) + newsize ) ;
2021-05-19 02:59:48 +00:00
replyNew - > size = zmalloc_usable_size ( replyNew ) - sizeof ( clientReplyBlock ) ;
2020-10-15 23:10:17 +00:00
replyNew - > used = c - > replyAsync - > used ;
memcpy ( replyNew - > buf ( ) , c - > replyAsync - > buf ( ) , c - > replyAsync - > used ) ;
zfree ( c - > replyAsync ) ;
c - > replyAsync = replyNew ;
}
2019-02-18 22:25:35 -05:00
}
2020-10-15 23:10:17 +00:00
memcpy ( c - > replyAsync - > buf ( ) + c - > replyAsync - > used , s , len ) ;
c - > replyAsync - > used + = len ;
2019-02-18 22:25:35 -05:00
}
else
{
size_t available = sizeof ( c - > buf ) - c - > bufpos ;
/* If there already are entries in the reply list, we cannot
* add anything more to the static buffer . */
if ( listLength ( c - > reply ) > 0 ) return C_ERR ;
2019-02-15 14:11:05 -05:00
2019-02-18 22:25:35 -05:00
/* Check that the buffer has enough space available for this string. */
if ( len > available ) return C_ERR ;
2019-02-15 14:11:05 -05:00
2019-02-18 22:25:35 -05:00
memcpy ( c - > buf + c - > bufpos , s , len ) ;
c - > bufpos + = len ;
}
2019-02-15 14:11:05 -05:00
return C_OK ;
}
2020-12-08 16:41:20 +02:00
/* Adds the reply to the reply linked list.
* Note : some edits to this function need to be relayed to AddReplyFromClient . */
2019-02-15 14:11:05 -05:00
void _addReplyProtoToList ( client * c , const char * s , size_t len ) {
2020-10-13 06:35:16 +00:00
if ( c - > flags . load ( std : : memory_order_relaxed ) & CLIENT_CLOSE_AFTER_REPLY ) return ;
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2019-02-15 14:11:05 -05:00
listNode * ln = listLast ( c - > reply ) ;
clientReplyBlock * tail = ( clientReplyBlock * ) ( ln ? listNodeValue ( ln ) : NULL ) ;
Squash merging 125 typo/grammar/comment/doc PRs (#7773)
List of squashed commits or PRs
===============================
commit 66801ea
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Jan 13 00:54:31 2020 -0500
typo fix in acl.c
commit 46f55db
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun Sep 6 18:24:11 2020 +0300
Updates a couple of comments
Specifically:
* RM_AutoMemory completed instead of pointing to docs
* Updated link to custom type doc
commit 61a2aa0
Author: xindoo <xindoo@qq.com>
Date: Tue Sep 1 19:24:59 2020 +0800
Correct errors in code comments
commit a5871d1
Author: yz1509 <pro-756@qq.com>
Date: Tue Sep 1 18:36:06 2020 +0800
fix typos in module.c
commit 41eede7
Author: bookug <bookug@qq.com>
Date: Sat Aug 15 01:11:33 2020 +0800
docs: fix typos in comments
commit c303c84
Author: lazy-snail <ws.niu@outlook.com>
Date: Fri Aug 7 11:15:44 2020 +0800
fix spelling in redis.conf
commit 1eb76bf
Author: zhujian <zhujianxyz@gmail.com>
Date: Thu Aug 6 15:22:10 2020 +0800
add a missing 'n' in comment
commit 1530ec2
Author: Daniel Dai <764122422@qq.com>
Date: Mon Jul 27 00:46:35 2020 -0400
fix spelling in tracking.c
commit e517b31
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:32 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit c300eff
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:23 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit 4c058a8
Author: 陈浩鹏 <chenhaopeng@heytea.com>
Date: Thu Jun 25 19:00:56 2020 +0800
Grammar fix and clarification
commit 5fcaa81
Author: bodong.ybd <bodong.ybd@alibaba-inc.com>
Date: Fri Jun 19 10:09:00 2020 +0800
Fix typos
commit 4caca9a
Author: Pruthvi P <pruthvi@ixigo.com>
Date: Fri May 22 00:33:22 2020 +0530
Fix typo eviciton => eviction
commit b2a25f6
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Sun May 17 12:39:59 2020 -0400
Fix a typo.
commit 12842ae
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun May 3 17:16:59 2020 -0400
fix spelling in redis conf
commit ddba07c
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Sat May 2 23:25:34 2020 +0100
Correct a "conflicts" spelling error.
commit 8fc7bf2
Author: Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Date: Thu Apr 30 10:25:27 2020 +0900
docs: fix EXPIRE_FAST_CYCLE_DURATION to ACTIVE_EXPIRE_CYCLE_FAST_DURATION
commit 9b2b67a
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Fri Apr 24 11:46:22 2020 -0400
Fix a typo.
commit 0746f10
Author: devilinrust <63737265+devilinrust@users.noreply.github.com>
Date: Thu Apr 16 00:17:53 2020 +0200
Fix typos in server.c
commit 92b588d
Author: benjessop12 <56115861+benjessop12@users.noreply.github.com>
Date: Mon Apr 13 13:43:55 2020 +0100
Fix spelling mistake in lazyfree.c
commit 1da37aa
Merge: 2d4ba28 c90b2a4
Author: hwware <wen.hui.ware@gmail.com>
Date: Thu Mar 5 22:41:31 2020 -0500
Merge remote-tracking branch 'upstream/unstable' into expiretypofix
commit 2d4ba28
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Mar 2 00:09:40 2020 -0500
fix typo in expire.c
commit 1a746f7
Author: SennoYuki <minakami1yuki@gmail.com>
Date: Thu Feb 27 16:54:32 2020 +0800
fix typo
commit 8599b1a
Author: dongheejeong <donghee950403@gmail.com>
Date: Sun Feb 16 20:31:43 2020 +0000
Fix typo in server.c
commit f38d4e8
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun Feb 2 22:58:38 2020 -0500
fix typo in evict.c
commit fe143fc
Author: Leo Murillo <leonardo.murillo@gmail.com>
Date: Sun Feb 2 01:57:22 2020 -0600
Fix a few typos in redis.conf
commit 1ab4d21
Author: viraja1 <anchan.viraj@gmail.com>
Date: Fri Dec 27 17:15:58 2019 +0530
Fix typo in Latency API docstring
commit ca1f70e
Author: gosth <danxuedexing@qq.com>
Date: Wed Dec 18 15:18:02 2019 +0800
fix typo in sort.c
commit a57c06b
Author: ZYunH <zyunhjob@163.com>
Date: Mon Dec 16 22:28:46 2019 +0800
fix-zset-typo
commit b8c92b5
Author: git-hulk <hulk.website@gmail.com>
Date: Mon Dec 16 15:51:42 2019 +0800
FIX: typo in cluster.c, onformation->information
commit 9dd981c
Author: wujm2007 <jim.wujm@gmail.com>
Date: Mon Dec 16 09:37:52 2019 +0800
Fix typo
commit e132d7a
Author: Sebastien Williams-Wynn <s.williamswynn.mail@gmail.com>
Date: Fri Nov 15 00:14:07 2019 +0000
Minor typo change
commit 47f44d5
Author: happynote3966 <01ssrmikururudevice01@gmail.com>
Date: Mon Nov 11 22:08:48 2019 +0900
fix comment typo in redis-cli.c
commit b8bdb0d
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 18:00:17 2019 +0800
Fix a spelling mistake of comments in defragDictBucketCallback
commit 0def46a
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 13:09:27 2019 +0800
fix some spelling mistakes of comments in defrag.c
commit f3596fd
Author: Phil Rajchgot <tophil@outlook.com>
Date: Sun Oct 13 02:02:32 2019 -0400
Typo and grammar fixes
Redis and its documentation are great -- just wanted to submit a few corrections in the spirit of Hacktoberfest. Thanks for all your work on this project. I use it all the time and it works beautifully.
commit 2b928cd
Author: KangZhiDong <worldkzd@gmail.com>
Date: Sun Sep 1 07:03:11 2019 +0800
fix typos
commit 33aea14
Author: Axlgrep <axlgrep@gmail.com>
Date: Tue Aug 27 11:02:18 2019 +0800
Fixed eviction spelling issues
commit e282a80
Author: Simen Flatby <simen@oms.no>
Date: Tue Aug 20 15:25:51 2019 +0200
Update comments to reflect prop name
In the comments the prop is referenced as replica-validity-factor,
but it is really named cluster-replica-validity-factor.
commit 74d1f9a
Author: Jim Green <jimgreen2013@qq.com>
Date: Tue Aug 20 20:00:31 2019 +0800
fix comment error, the code is ok
commit eea1407
Author: Liao Tonglang <liaotonglang@gmail.com>
Date: Fri May 31 10:16:18 2019 +0800
typo fix
fix cna't to can't
commit 0da553c
Author: KAWACHI Takashi <tkawachi@gmail.com>
Date: Wed Jul 17 00:38:16 2019 +0900
Fix typo
commit 7fc8fb6
Author: Michael Prokop <mika@grml.org>
Date: Tue May 28 17:58:42 2019 +0200
Typo fixes
s/familar/familiar/
s/compatiblity/compatibility/
s/ ot / to /
s/itsef/itself/
commit 5f46c9d
Author: zhumoing <34539422+zhumoing@users.noreply.github.com>
Date: Tue May 21 21:16:50 2019 +0800
typo-fixes
typo-fixes
commit 321dfe1
Author: wxisme <850885154@qq.com>
Date: Sat Mar 16 15:10:55 2019 +0800
typo fix
commit b4fb131
Merge: 267e0e6 4842305
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Fri Feb 8 22:55:45 2019 +0200
Merge branch 'unstable' of antirez/redis into unstable
commit 267e0e6
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Wed Jan 30 21:26:04 2019 +0200
Minor typo fix
commit 30544e7
Author: inshal96 <39904558+inshal96@users.noreply.github.com>
Date: Fri Jan 4 16:54:50 2019 +0500
remove an extra 'a' in the comments
commit 337969d
Author: BrotherGao <yangdongheng11@gmail.com>
Date: Sat Dec 29 12:37:29 2018 +0800
fix typo in redis.conf
commit 9f4b121
Merge: 423a030 19d0ece
Author: BrotherGao <yangdongheng@xiaomi.com>
Date: Sat Dec 29 11:41:12 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 423a030
Merge: 42b02b7 0423081
Author: 杨东衡 <yangdongheng@xiaomi.com>
Date: Tue Dec 4 23:56:11 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 42b02b7
Merge: 8c7dcff efa96f0
Author: Dongheng Yang <yangdongheng11@gmail.com>
Date: Sun Oct 28 15:54:23 2018 +0800
Merge pull request #1 from antirez/unstable
update local data
commit 714b589
Author: Christian <crifei93@gmail.com>
Date: Fri Dec 28 01:17:26 2018 +0100
fix typo "resulution"
commit e23259d
Author: garenchan <1412950785@qq.com>
Date: Wed Dec 26 09:58:35 2018 +0800
fix typo: segfauls -> segfault
commit a9359f8
Author: xjp <jianping_xie@aliyun.com>
Date: Tue Dec 18 17:31:44 2018 +0800
Fixed REDISMODULE_H spell bug
commit a12c3e4
Author: jdiaz <jrd.palacios@gmail.com>
Date: Sat Dec 15 23:39:52 2018 -0600
Fixes hyperloglog hash function comment block description
commit 770eb11
Author: 林上耀 <1210tom@163.com>
Date: Sun Nov 25 17:16:10 2018 +0800
fix typo
commit fd97fbb
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Fri Nov 23 17:14:01 2018 +0100
Correct "unsupported" typo.
commit a85522d
Author: Jungnam Lee <jungnam.lee@oracle.com>
Date: Thu Nov 8 23:01:29 2018 +0900
fix typo in test comments
commit ade8007
Author: Arun Kumar <palerdot@users.noreply.github.com>
Date: Tue Oct 23 16:56:35 2018 +0530
Fixed grammatical typo
Fixed typo for word 'dictionary'
commit 869ee39
Author: Hamid Alaei <hamid.a85@gmail.com>
Date: Sun Aug 12 16:40:02 2018 +0430
fix documentations: (ThreadSafeContextStart/Stop -> ThreadSafeContextLock/Unlock), minor typo
commit f89d158
Author: Mayank Jain <mayankjain255@gmail.com>
Date: Tue Jul 31 23:01:21 2018 +0530
Updated README.md with some spelling corrections.
Made correction in spelling of some misspelled words.
commit 892198e
Author: dsomeshwar <someshwar.dhayalan@gmail.com>
Date: Sat Jul 21 23:23:04 2018 +0530
typo fix
commit 8a4d780
Author: Itamar Haber <itamar@redislabs.com>
Date: Mon Apr 30 02:06:52 2018 +0300
Fixes some typos
commit e3acef6
Author: Noah Rosamilia <ivoahivoah@gmail.com>
Date: Sat Mar 3 23:41:21 2018 -0500
Fix typo in /deps/README.md
commit 04442fb
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:32:42 2018 +0800
Fix typo in readSyncBulkPayload() comment.
commit 9f36880
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:20:37 2018 +0800
replication.c comment: run_id -> replid.
commit f866b4a
Author: Francesco 'makevoid' Canessa <makevoid@gmail.com>
Date: Thu Feb 22 22:01:56 2018 +0000
fix comment typo in server.c
commit 0ebc69b
Author: 줍 <jubee0124@gmail.com>
Date: Mon Feb 12 16:38:48 2018 +0900
Fix typo in redis.conf
Fix `five behaviors` to `eight behaviors` in [this sentence ](antirez/redis@unstable/redis.conf#L564)
commit b50a620
Author: martinbroadhurst <martinbroadhurst@users.noreply.github.com>
Date: Thu Dec 28 12:07:30 2017 +0000
Fix typo in valgrind.sup
commit 7d8f349
Author: Peter Boughton <peter@sorcerersisle.com>
Date: Mon Nov 27 19:52:19 2017 +0000
Update CONTRIBUTING; refer doc updates to redis-doc repo.
commit 02dec7e
Author: Klauswk <klauswk1@hotmail.com>
Date: Tue Oct 24 16:18:38 2017 -0200
Fix typo in comment
commit e1efbc8
Author: chenshi <baiwfg2@gmail.com>
Date: Tue Oct 3 18:26:30 2017 +0800
Correct two spelling errors of comments
commit 93327d8
Author: spacewander <spacewanderlzx@gmail.com>
Date: Wed Sep 13 16:47:24 2017 +0800
Update the comment for OBJ_ENCODING_EMBSTR_SIZE_LIMIT's value
The value of OBJ_ENCODING_EMBSTR_SIZE_LIMIT is 44 now instead of 39.
commit 63d361f
Author: spacewander <spacewanderlzx@gmail.com>
Date: Tue Sep 12 15:06:42 2017 +0800
Fix <prevlen> related doc in ziplist.c
According to the definition of ZIP_BIG_PREVLEN and other related code,
the guard of single byte <prevlen> should be 254 instead of 255.
commit ebe228d
Author: hanael80 <hanael80@gmail.com>
Date: Tue Aug 15 09:09:40 2017 +0900
Fix typo
commit 6b696e6
Author: Matt Robenolt <matt@ydekproductions.com>
Date: Mon Aug 14 14:50:47 2017 -0700
Fix typo in LATENCY DOCTOR output
commit a2ec6ae
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 15 14:15:16 2017 +0800
Fix a typo: form => from
commit 3ab7699
Author: caosiyang <caosiyang@qiyi.com>
Date: Thu Aug 10 18:40:33 2017 +0800
Fix a typo: replicationFeedSlavesFromMaster() => replicationFeedSlavesFromMasterStream()
commit 72d43ef
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 8 15:57:25 2017 +0800
fix a typo: servewr => server
commit 707c958
Author: Bo Cai <charpty@gmail.com>
Date: Wed Jul 26 21:49:42 2017 +0800
redis-cli.c typo: conut -> count.
Signed-off-by: Bo Cai <charpty@gmail.com>
commit b9385b2
Author: JackDrogon <jack.xsuperman@gmail.com>
Date: Fri Jun 30 14:22:31 2017 +0800
Fix some spell problems
commit 20d9230
Author: akosel <aaronjkosel@gmail.com>
Date: Sun Jun 4 19:35:13 2017 -0500
Fix typo
commit b167bfc
Author: Krzysiek Witkowicz <krzysiekwitkowicz@gmail.com>
Date: Mon May 22 21:32:27 2017 +0100
Fix #4008 small typo in comment
commit 2b78ac8
Author: Jake Clarkson <jacobwclarkson@gmail.com>
Date: Wed Apr 26 15:49:50 2017 +0100
Correct typo in tests/unit/hyperloglog.tcl
commit b0f1cdb
Author: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Wed Apr 19 14:25:18 2017 -0700
Fix typo
commit a90b0f9
Author: charsyam <charsyam@naver.com>
Date: Thu Mar 16 18:19:53 2017 +0900
fix typos
fix typos
fix typos
commit 8430a79
Author: Richard Hart <richardhart92@gmail.com>
Date: Mon Mar 13 22:17:41 2017 -0400
Fixed log message typo in listenToPort.
commit 481a1c2
Author: Vinod Kumar <kumar003vinod@gmail.com>
Date: Sun Jan 15 23:04:51 2017 +0530
src/db.c: Correct "save" -> "safe" typo
commit 586b4d3
Author: wangshaonan <wshn13@gmail.com>
Date: Wed Dec 21 20:28:27 2016 +0800
Fix typo they->the in helloworld.c
commit c1c4b5e
Author: Jenner <hypxm@qq.com>
Date: Mon Dec 19 16:39:46 2016 +0800
typo error
commit 1ee1a3f
Author: tielei <43289893@qq.com>
Date: Mon Jul 18 13:52:25 2016 +0800
fix some comments
commit 11a41fb
Author: Otto Kekäläinen <otto@seravo.fi>
Date: Sun Jul 3 10:23:55 2016 +0100
Fix spelling in documentation and comments
commit 5fb5d82
Author: francischan <f1ancis621@gmail.com>
Date: Tue Jun 28 00:19:33 2016 +0800
Fix outdated comments about redis.c file.
It should now refer to server.c file.
commit 6b254bc
Author: lmatt-bit <lmatt123n@gmail.com>
Date: Thu Apr 21 21:45:58 2016 +0800
Refine the comment of dictRehashMilliseconds func
SLAVECONF->REPLCONF in comment - by andyli029
commit ee9869f
Author: clark.kang <charsyam@naver.com>
Date: Tue Mar 22 11:09:51 2016 +0900
fix typos
commit f7b3b11
Author: Harisankar H <harisankarh@gmail.com>
Date: Wed Mar 9 11:49:42 2016 +0530
Typo correction: "faield" --> "failed"
Typo correction: "faield" --> "failed"
commit 3fd40fc
Author: Itamar Haber <itamar@redislabs.com>
Date: Thu Feb 25 10:31:51 2016 +0200
Fixes a typo in comments
commit 621c160
Author: Prayag Verma <prayag.verma@gmail.com>
Date: Mon Feb 1 12:36:20 2016 +0530
Fix typo in Readme.md
Spelling mistakes -
`eviciton` > `eviction`
`familar` > `familiar`
commit d7d07d6
Author: WonCheol Lee <toctoc21c@gmail.com>
Date: Wed Dec 30 15:11:34 2015 +0900
Typo fixed
commit a4dade7
Author: Felix Bünemann <buenemann@louis.info>
Date: Mon Dec 28 11:02:55 2015 +0100
[ci skip] Improve supervised upstart config docs
This mentions that "expect stop" is required for supervised upstart
to work correctly. See http://upstart.ubuntu.com/cookbook/#expect-stop
for an explanation.
commit d9caba9
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:30:03 2015 +1100
README: Remove trailing whitespace
commit 72d42e5
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:32 2015 +1100
README: Fix typo. th => the
commit dd6e957
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:20 2015 +1100
README: Fix typo. familar => familiar
commit 3a12b23
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:28:54 2015 +1100
README: Fix typo. eviciton => eviction
commit 2d1d03b
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:21:45 2015 +1100
README: Fix typo. sever => server
commit 3973b06
Author: Itamar Haber <itamar@garantiadata.com>
Date: Sat Dec 19 17:01:20 2015 +0200
Typo fix
commit 4f2e460
Author: Steve Gao <fu@2token.com>
Date: Fri Dec 4 10:22:05 2015 +0800
Update README - fix typos
commit b21667c
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:48:37 2015 +0800
delete redundancy color judge in sdscatcolor
commit 88894c7
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:14:42 2015 +0800
the example output shoule be HelloWorld
commit 2763470
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 17:41:39 2015 +0800
modify error word keyevente
Signed-off-by: binyan <binbin.yan@nokia.com>
commit 0847b3d
Author: Bruno Martins <bscmartins@gmail.com>
Date: Wed Nov 4 11:37:01 2015 +0000
typo
commit bbb9e9e
Author: dawedawe <dawedawe@gmx.de>
Date: Fri Mar 27 00:46:41 2015 +0100
typo: zimap -> zipmap
commit 5ed297e
Author: Axel Advento <badwolf.bloodseeker.rev@gmail.com>
Date: Tue Mar 3 15:58:29 2015 +0800
Fix 'salve' typos to 'slave'
commit edec9d6
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Wed Jun 12 14:12:47 2019 +0200
Update README.md
Co-Authored-By: Qix <Qix-@users.noreply.github.com>
commit 692a7af
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Tue May 28 14:32:04 2019 +0200
grammar
commit d962b0a
Author: Nick Frost <nickfrostatx@gmail.com>
Date: Wed Jul 20 15:17:12 2016 -0700
Minor grammar fix
commit 24fff01aaccaf5956973ada8c50ceb1462e211c6 (typos)
Author: Chad Miller <chadm@squareup.com>
Date: Tue Sep 8 13:46:11 2020 -0400
Fix faulty comment about operation of unlink()
commit 3cd5c1f3326c52aa552ada7ec797c6bb16452355
Author: Kevin <kevin.xgr@gmail.com>
Date: Wed Nov 20 00:13:50 2019 +0800
Fix typo in server.c.
From a83af59 Mon Sep 17 00:00:00 2001
From: wuwo <wuwo@wacai.com>
Date: Fri, 17 Mar 2017 20:37:45 +0800
Subject: [PATCH] falure to failure
From c961896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B7=A6=E6=87=B6?= <veficos@gmail.com>
Date: Sat, 27 May 2017 15:33:04 +0800
Subject: [PATCH] fix typo
From e600ef2 Mon Sep 17 00:00:00 2001
From: "rui.zou" <rui.zou@yunify.com>
Date: Sat, 30 Sep 2017 12:38:15 +0800
Subject: [PATCH] fix a typo
From c7d07fa Mon Sep 17 00:00:00 2001
From: Alexandre Perrin <alex@kaworu.ch>
Date: Thu, 16 Aug 2018 10:35:31 +0200
Subject: [PATCH] deps README.md typo
From b25cb67 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 10:55:37 +0300
Subject: [PATCH 1/2] fix typos in header
From ad28ca6 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 11:02:36 +0300
Subject: [PATCH 2/2] fix typos
commit 34924cdedd8552466fc22c1168d49236cb7ee915
Author: Adrian Lynch <adi_ady_ade@hotmail.com>
Date: Sat Apr 4 21:59:15 2015 +0100
Typos fixed
commit fd2a1e7
Author: Jan <jsteemann@users.noreply.github.com>
Date: Sat Oct 27 19:13:01 2018 +0200
Fix typos
Fix typos
commit e14e47c1a234b53b0e103c5f6a1c61481cbcbb02
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:30:07 2019 -0500
Fix multiple misspellings of "following"
commit 79b948ce2dac6b453fe80995abbcaac04c213d5a
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:24:28 2019 -0500
Fix misspelling of create-cluster
commit 1fffde52666dc99ab35efbd31071a4c008cb5a71
Author: Andy Lester <andy@petdance.com>
Date: Wed Jul 31 17:57:56 2019 -0500
Fix typos
commit 204c9ba9651e9e05fd73936b452b9a30be456cfe
Author: Xiaobo Zhu <xiaobo.zhu@shopee.com>
Date: Tue Aug 13 22:19:25 2019 +0800
fix typos
Squashed commit of the following:
commit 1d9aaf8
Author: danmedani <danmedani@gmail.com>
Date: Sun Aug 2 11:40:26 2015 -0700
README typo fix.
Squashed commit of the following:
commit 32bfa7c
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Jul 6 21:15:08 2015 +0200
Fixed grammer
Squashed commit of the following:
commit b24f69c
Author: Sisir Koppaka <sisir.koppaka@gmail.com>
Date: Mon Mar 2 22:38:45 2015 -0500
utils/hashtable/rehashing.c: Fix typos
Squashed commit of the following:
commit 4e04082
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Mar 23 08:22:21 2015 +0000
Small config file documentation improvements
Squashed commit of the following:
commit acb8773
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:52:48 2015 -0700
Typo and grammar fixes in readme
commit 2eb75b6
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:36:18 2015 -0700
fixed redis.conf comment
Squashed commit of the following:
commit a8249a2
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri Dec 11 11:39:52 2015 +0530
Revise correction of typos.
Squashed commit of the following:
commit 3c02028
Author: zhaojun11 <zhaojun11@jd.com>
Date: Wed Jan 17 19:05:28 2018 +0800
Fix typos include two code typos in cluster.c and latency.c
Squashed commit of the following:
commit 9dba47c
Author: q191201771 <191201771@qq.com>
Date: Sat Jan 4 11:31:04 2020 +0800
fix function listCreate comment in adlist.c
Update src/server.c
commit 2c7c2cb536e78dd211b1ac6f7bda00f0f54faaeb
Author: charpty <charpty@gmail.com>
Date: Tue May 1 23:16:59 2018 +0800
server.c typo: modules system dictionary type comment
Signed-off-by: charpty <charpty@gmail.com>
commit a8395323fb63cb59cb3591cb0f0c8edb7c29a680
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun May 6 00:25:18 2018 +0300
Updates test_helper.tcl's help with undocumented options
Specifically:
* Host
* Port
* Client
commit bde6f9ced15755cd6407b4af7d601b030f36d60b
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 15:19:19 2018 +0800
fix comments in deps files
commit 3172474ba991532ab799ee1873439f3402412331
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 14:33:49 2018 +0800
fix some comments
commit 01b6f2b6858b5cf2ce4ad5092d2c746e755f53f0
Author: Thor Juhasz <thor@juhasz.pro>
Date: Sun Nov 18 14:37:41 2018 +0100
Minor fixes to comments
Found some parts a little unclear on a first read, which prompted me to have a better look at the file and fix some minor things I noticed.
Fixing minor typos and grammar. There are no changes to configuration options.
These changes are only meant to help the user better understand the explanations to the various configuration options
(cherry picked from commit 285ef446b05e09013556e7a490677494a9b4bb3e)
2020-09-10 13:43:38 +03:00
/* Note that 'tail' may be NULL even if we have a tail node, because when
2020-05-21 21:45:35 +08:00
* addReplyDeferredLen ( ) is used , it sets a dummy node to NULL just
2019-02-15 14:11:05 -05:00
* fo fill it later , when the size of the bulk length is set . */
/* Append to tail string when possible. */
if ( tail ) {
/* Copy the part we can fit into the tail, and leave the rest for a
* new node */
size_t avail = tail - > size - tail - > used ;
size_t copy = avail > = len ? len : avail ;
2019-02-15 14:11:34 -05:00
memcpy ( tail - > buf ( ) + tail - > used , s , copy ) ;
2019-02-15 14:11:05 -05:00
tail - > used + = copy ;
s + = copy ;
len - = copy ;
}
if ( len ) {
/* Create a new node, make sure it is allocated to at
* least PROTO_REPLY_CHUNK_BYTES */
size_t size = len < PROTO_REPLY_CHUNK_BYTES ? PROTO_REPLY_CHUNK_BYTES : len ;
tail = ( clientReplyBlock * ) zmalloc ( size + sizeof ( clientReplyBlock ) , MALLOC_LOCAL ) ;
/* take over the allocation's internal fragmentation */
2020-10-02 08:19:44 +03:00
tail - > size = zmalloc_usable_size ( tail ) - sizeof ( clientReplyBlock ) ;
2019-02-15 14:11:05 -05:00
tail - > used = len ;
2019-02-15 14:11:34 -05:00
memcpy ( tail - > buf ( ) , s , len ) ;
2019-02-15 14:11:05 -05:00
listAddNodeTail ( c - > reply , tail ) ;
c - > reply_bytes + = tail - > size ;
2021-03-30 23:06:29 +03:00
asyncCloseClientOnOutputBufferLimitReached ( c ) ;
2019-02-15 14:11:05 -05:00
}
}
/* -----------------------------------------------------------------------------
* Higher level functions to queue data on the client output buffer .
* The following functions are the ones that commands implementations will call .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2020-10-24 02:18:03 +00:00
/* Add the object 'obj' string representation to the client output buffer. */
void addReply ( client * c , robj_roptr obj ) {
if ( prepareClientToWrite ( c ) ! = C_OK ) return ;
2019-02-15 14:11:05 -05:00
if ( sdsEncodedObject ( obj ) ) {
2020-10-24 02:18:03 +00:00
if ( _addReplyToBuffer ( c , ( const char * ) ptrFromObj ( obj ) , sdslen ( ( sds ) ptrFromObj ( obj ) ) ) ! = C_OK )
2019-02-15 14:11:05 -05:00
_addReplyProtoToList ( c , ( const char * ) ptrFromObj ( obj ) , sdslen ( ( sds ) ptrFromObj ( obj ) ) ) ;
} else if ( obj - > encoding = = OBJ_ENCODING_INT ) {
/* For integer encoded strings we just convert it into a string
* using our optimized function , and attach the resulting string
* to the output buffer . */
char buf [ 32 ] ;
size_t len = ll2string ( buf , sizeof ( buf ) , ( long ) ptrFromObj ( obj ) ) ;
2020-10-24 02:18:03 +00:00
if ( _addReplyToBuffer ( c , buf , len ) ! = C_OK )
2019-02-15 14:11:05 -05:00
_addReplyProtoToList ( c , buf , len ) ;
} else {
serverPanic ( " Wrong obj->encoding in addReply() " ) ;
}
}
/* Add the SDS 's' string to the client output buffer, as a side effect
* the SDS string is freed . */
2020-10-24 02:18:03 +00:00
void addReplySds ( client * c , sds s ) {
if ( prepareClientToWrite ( c ) ! = C_OK ) {
2019-02-15 14:11:05 -05:00
/* The caller expects the sds to be free'd. */
sdsfree ( s ) ;
return ;
}
2020-10-24 02:18:03 +00:00
if ( _addReplyToBuffer ( c , s , sdslen ( s ) ) ! = C_OK )
2019-02-15 14:11:05 -05:00
_addReplyProtoToList ( c , s , sdslen ( s ) ) ;
sdsfree ( s ) ;
}
/* This low level function just adds whatever protocol you send it to the
* client buffer , trying the static buffer initially , and using the string
* of objects if not possible .
*
* It is efficient because does not create an SDS object nor an Redis object
* if not needed . The object will only be created by calling
* _addReplyProtoToList ( ) if we fail to extend the existing tail object
* in the list of objects . */
2019-02-18 22:25:35 -05:00
void addReplyProto ( client * c , const char * s , size_t len ) {
2020-10-24 02:18:03 +00:00
if ( prepareClientToWrite ( c ) ! = C_OK ) return ;
if ( _addReplyToBuffer ( c , s , len ) ! = C_OK )
_addReplyProtoToList ( c , s , len ) ;
2019-02-18 23:52:21 -05:00
}
2020-11-06 19:24:48 +00:00
void addReplyProtoCString ( client * c , const char * s ) {
addReplyProto ( c , s , strlen ( s ) ) ;
}
2020-03-04 17:09:12 -05:00
std : : string escapeString ( sds str )
{
std : : string newstr ;
size_t len = sdslen ( str ) ;
for ( size_t ich = 0 ; ich < len ; + + ich )
{
char ch = str [ ich ] ;
switch ( ch )
{
case ' \n ' :
newstr + = " \\ n " ;
break ;
case ' \t ' :
newstr + = " \\ t " ;
break ;
case ' \r ' :
newstr + = " \\ r " ;
break ;
default :
newstr + = ch ;
}
}
return newstr ;
}
2019-02-15 14:11:05 -05:00
/* Low level function called by the addReplyError...() functions.
* It emits the protocol for a Redis error , in the form :
*
* - ERRORCODE Error Message < CR > < LF >
*
* If the error code is already passed in the string ' s ' , the error
* code provided is used , otherwise the string " -ERR " for the generic
2020-08-27 12:54:01 +03:00
* error code is automatically added .
* Note that ' s ' must NOT end with \ r \ n . */
2020-10-24 02:18:03 +00:00
void addReplyErrorLength ( client * c , const char * s , size_t len ) {
2019-02-15 14:11:05 -05:00
/* If the string already starts with "-..." then the error code
* is provided by the caller . Otherwise we use " -ERR " . */
2020-10-24 02:18:03 +00:00
if ( ! len | | s [ 0 ] ! = ' - ' ) addReplyProto ( c , " -ERR " , 5 ) ;
addReplyProto ( c , s , len ) ;
addReplyProto ( c , " \r \n " , 2 ) ;
2020-08-27 12:54:01 +03:00
}
2019-02-15 14:11:05 -05:00
2020-08-27 12:54:01 +03:00
/* Do some actions after an error reply was sent (Log if needed, updates stats, etc.) */
2021-01-14 21:40:17 +00:00
void afterErrorReply ( client * c , const char * s , size_t len , int severity = ERR_CRITICAL ) {
2020-12-31 14:53:43 +00:00
/* Increment the global error counter */
2021-05-19 02:59:48 +00:00
g_pserver - > stat_total_error_replies + + ;
2020-12-31 14:53:43 +00:00
/* Increment the error stats
* If the string already starts with " -... " then the error prefix
* is provided by the caller ( we limit the search to 32 chars ) . Otherwise we use " -ERR " . */
if ( s [ 0 ] ! = ' - ' ) {
incrementErrorCount ( " ERR " , 3 ) ;
} else {
2021-05-19 02:59:48 +00:00
const char * spaceloc = ( const char * ) memchr ( s , ' ' , len < 32 ? len : 32 ) ;
2020-12-31 14:53:43 +00:00
if ( spaceloc ) {
const size_t errEndPos = ( size_t ) ( spaceloc - s ) ;
incrementErrorCount ( s + 1 , errEndPos - 1 ) ;
} else {
/* Fallback to ERR if we can't retrieve the error prefix */
incrementErrorCount ( " ERR " , 3 ) ;
}
}
2020-02-06 14:12:08 +05:30
int ctype = getClientType ( c ) ;
2020-03-29 13:08:21 +03:00
if ( ctype = = CLIENT_TYPE_MASTER | | ctype = = CLIENT_TYPE_SLAVE | | c - > id = = CLIENT_ID_AOF ) {
2020-04-14 22:56:19 -04:00
const char * to , * from ;
2020-03-31 17:10:09 +02:00
if ( c - > id = = CLIENT_ID_AOF ) {
to = " AOF-loading-client " ;
from = " server " ;
} else if ( ctype = = CLIENT_TYPE_MASTER ) {
to = " master " ;
from = " replica " ;
} else {
to = " replica " ;
from = " master " ;
}
2020-08-27 12:54:01 +03:00
if ( len > 4096 ) len = 4096 ;
2020-04-14 19:22:44 -04:00
const char * cmdname = c - > lastcmd ? c - > lastcmd - > name : " <unknown> " ;
2021-01-14 21:40:17 +00:00
switch ( severity ) {
case ERR_NOTICE :
serverLog ( LL_NOTICE , " == NOTICE == This %s is rejecting a command "
" from its %s: '%.*s' after processing the command "
" '%s' " , from , to , ( int ) len , s , cmdname ) ;
break ;
case ERR_WARNING :
serverLog ( LL_WARNING , " == WARNING == This %s is rejecting a command "
" from its %s: '%.*s' after processing the command "
" '%s' " , from , to , ( int ) len , s , cmdname ) ;
break ;
case ERR_ERROR :
serverLog ( LL_WARNING , " == ERROR == This %s is sending an error "
" to its %s: '%.*s' after processing the command "
" '%s' " , from , to , ( int ) len , s , cmdname ) ;
break ;
case ERR_CRITICAL :
default :
serverLog ( LL_WARNING , " == CRITICAL == This %s is sending an error "
" to its %s: '%.*s' after processing the command "
" '%s' " , from , to , ( int ) len , s , cmdname ) ;
break ;
}
2020-05-22 15:56:35 -04:00
if ( ctype = = CLIENT_TYPE_MASTER & & g_pserver - > repl_backlog & &
g_pserver - > repl_backlog_histlen > 0 )
2020-05-05 13:40:33 +02:00
{
2020-05-28 10:08:16 +02:00
showLatestBacklog ( ) ;
2020-03-04 17:09:12 -05:00
}
2020-04-14 22:56:19 -04:00
g_pserver - > stat_unexpected_error_replies + + ;
2019-02-15 14:11:05 -05:00
}
}
2020-08-27 12:54:01 +03:00
/* The 'err' object is expected to start with -ERRORCODE and end with \r\n.
* Unlike addReplyErrorSds and others alike which rely on addReplyErrorLength . */
2021-01-14 21:40:17 +00:00
void addReplyErrorObject ( client * c , robj * err , int severity ) {
2020-08-27 12:54:01 +03:00
addReply ( c , err ) ;
2021-01-14 21:40:17 +00:00
afterErrorReply ( c , szFromObj ( err ) , sdslen ( szFromObj ( err ) ) - 2 , severity ) ; /* Ignore trailing \r\n */
2020-08-27 12:54:01 +03:00
}
2020-08-27 12:54:01 +03:00
/* See addReplyErrorLength for expectations from the input string. */
2019-02-15 14:11:05 -05:00
void addReplyError ( client * c , const char * err ) {
2012-01-23 17:15:49 +01:00
addReplyErrorLength ( c , err , strlen ( err ) ) ;
2020-08-27 12:54:01 +03:00
afterErrorReply ( c , err , strlen ( err ) ) ;
2010-09-02 19:52:24 +02:00
}
2010-06-22 00:07:48 +02:00
2020-08-27 12:54:01 +03:00
/* See addReplyErrorLength for expectations from the input string. */
2020-12-27 21:40:12 +02:00
/* As a side effect the SDS string is freed. */
2020-08-27 12:54:01 +03:00
void addReplyErrorSds ( client * c , sds err ) {
addReplyErrorLength ( c , err , sdslen ( err ) ) ;
afterErrorReply ( c , err , sdslen ( err ) ) ;
2020-12-27 21:40:12 +02:00
sdsfree ( err ) ;
2019-02-15 14:11:05 -05:00
}
2020-08-27 12:54:01 +03:00
/* See addReplyErrorLength for expectations from the formatted string.
* The formatted string is safe to contain \ r and \ n anywhere . */
2019-02-15 14:11:05 -05:00
void addReplyErrorFormat ( client * c , const char * fmt , . . . ) {
va_list ap ;
va_start ( ap , fmt ) ;
sds s = sdscatvprintf ( sdsempty ( ) , fmt , ap ) ;
va_end ( ap ) ;
2020-08-27 12:54:01 +03:00
/* Trim any newlines at the end (ones will be added by addReplyErrorLength) */
s = sdstrim ( s , " \r \n " ) ;
/* Make sure there are no newlines in the middle of the string, otherwise
* invalid protocol is emitted . */
s = sdsmapchars ( s , " \r \n " , " " , 2 ) ;
2019-02-15 14:11:05 -05:00
addReplyErrorLength ( c , s , sdslen ( s ) ) ;
2020-08-27 12:54:01 +03:00
afterErrorReply ( c , s , sdslen ( s ) ) ;
2019-02-15 14:11:05 -05:00
sdsfree ( s ) ;
}
void addReplyStatusLength ( client * c , const char * s , size_t len ) {
addReplyProto ( c , " + " , 1 ) ;
addReplyProto ( c , s , len ) ;
addReplyProto ( c , " \r \n " , 2 ) ;
}
void addReplyStatus ( client * c , const char * status ) {
addReplyStatusLength ( c , status , strlen ( status ) ) ;
}
void addReplyStatusFormat ( client * c , const char * fmt , . . . ) {
va_list ap ;
va_start ( ap , fmt ) ;
sds s = sdscatvprintf ( sdsempty ( ) , fmt , ap ) ;
va_end ( ap ) ;
addReplyStatusLength ( c , s , sdslen ( s ) ) ;
sdsfree ( s ) ;
}
2020-04-24 17:20:28 +03:00
/* Sometimes we are forced to create a new reply node, and we can't append to
* the previous one , when that happens , we wanna try to trim the unused space
* at the end of the last reply node which we won ' t use anymore . */
void trimReplyUnusedTailSpace ( client * c ) {
listNode * ln = listLast ( c - > reply ) ;
2020-05-22 15:42:50 -04:00
clientReplyBlock * tail = ln ? ( clientReplyBlock * ) listNodeValue ( ln ) : NULL ;
2020-04-24 17:20:28 +03:00
/* Note that 'tail' may be NULL even if we have a tail node, becuase when
2020-05-21 21:45:35 +08:00
* addReplyDeferredLen ( ) is used */
2020-04-24 17:20:28 +03:00
if ( ! tail ) return ;
/* We only try to trim the space is relatively high (more than a 1/4 of the
* allocation ) , otherwise there ' s a high chance realloc will NOP .
* Also , to avoid large memmove which happens as part of realloc , we only do
* that if the used part is small . */
if ( tail - > size - tail - > used > tail - > size / 4 & &
tail - > used < PROTO_REPLY_CHUNK_BYTES )
{
size_t old_size = tail - > size ;
2020-05-22 15:42:50 -04:00
tail = ( clientReplyBlock * ) zrealloc ( tail , tail - > used + sizeof ( clientReplyBlock ) ) ;
2020-04-24 17:20:28 +03:00
/* take over the allocation's internal fragmentation (at least for
* memory usage tracking ) */
2020-10-02 08:19:44 +03:00
tail - > size = zmalloc_usable_size ( tail ) - sizeof ( clientReplyBlock ) ;
2020-05-21 21:00:21 +08:00
c - > reply_bytes = c - > reply_bytes + tail - > size - old_size ;
2020-04-24 17:20:28 +03:00
listNodeValue ( ln ) = tail ;
}
}
2019-02-15 14:11:05 -05:00
/* Adds an empty object to the reply list that will contain the multi bulk
* length , which is not known when this function is called . */
2020-10-24 02:18:03 +00:00
void * addReplyDeferredLenCore ( client * c ) {
2019-02-15 14:11:05 -05:00
/* Note that we install the write event here even if the object is not
* ready to be sent , since we are sure that before returning to the
* event loop setDeferredAggregateLen ( ) will be called . */
2020-10-24 02:18:03 +00:00
if ( prepareClientToWrite ( c ) ! = C_OK ) return NULL ;
2020-04-24 17:20:28 +03:00
trimReplyUnusedTailSpace ( c ) ;
2019-02-15 14:11:05 -05:00
listAddNodeTail ( c - > reply , NULL ) ; /* NULL is our placeholder. */
return listLast ( c - > reply ) ;
}
2020-10-24 02:18:03 +00:00
void * addReplyDeferredLen ( client * c ) {
2019-02-18 22:25:35 -05:00
if ( FCorrectThread ( c ) )
2020-10-24 02:18:03 +00:00
return addReplyDeferredLenCore ( c ) ;
2019-02-18 22:25:35 -05:00
2020-10-15 23:10:17 +00:00
return ( void * ) ( ( ssize_t ) ( c - > replyAsync ? c - > replyAsync - > used : 0 ) ) ;
2019-02-18 22:25:35 -05:00
}
2021-01-06 10:34:27 +02:00
void setDeferredReply ( client * c , void * node , const char * s , size_t length ) {
2019-02-15 14:11:05 -05:00
listNode * ln = ( listNode * ) node ;
2021-03-30 23:06:29 +03:00
clientReplyBlock * next , * prev ;
2019-02-15 14:11:05 -05:00
/* Abort when *node is NULL: when the client should not accept writes
* we return NULL in addReplyDeferredLen ( ) */
if ( node = = NULL ) return ;
serverAssert ( ! listNodeValue ( ln ) ) ;
/* Normally we fill this dummy NULL node, added by addReplyDeferredLen(),
* with a new buffer structure containing the protocol needed to specify
2021-03-30 23:06:29 +03:00
* the length of the array following . However sometimes there might be room
* in the previous / next node so we can instead remove this NULL node , and
* suffix / prefix our data in the node immediately before / after it , in order
* to save a write ( 2 ) syscall later . Conditions needed to do it :
2019-02-15 14:11:05 -05:00
*
2021-03-30 23:06:29 +03:00
* - The prev node is non - NULL and has space in it or
2019-02-15 14:11:05 -05:00
* - The next node is non - NULL ,
* - It has enough room already allocated
* - And not too large ( avoid large memmove ) */
2021-05-21 05:54:39 +00:00
if ( ln - > prev ! = NULL & & ( prev = ( clientReplyBlock * ) listNodeValue ( ln - > prev ) ) & &
2021-04-01 00:07:19 +03:00
prev - > size - prev - > used > 0 )
2021-03-30 23:06:29 +03:00
{
2021-04-01 00:07:19 +03:00
size_t len_to_copy = prev - > size - prev - > used ;
if ( len_to_copy > length )
len_to_copy = length ;
2021-05-21 05:54:39 +00:00
memcpy ( prev - > buf ( ) + prev - > used , s , len_to_copy ) ;
2021-04-01 00:07:19 +03:00
prev - > used + = len_to_copy ;
length - = len_to_copy ;
if ( length = = 0 ) {
listDelNode ( c - > reply , ln ) ;
return ;
}
s + = len_to_copy ;
2021-03-30 23:06:29 +03:00
}
2021-04-01 00:07:19 +03:00
2019-02-15 14:11:05 -05:00
if ( ln - > next ! = NULL & & ( next = ( clientReplyBlock * ) listNodeValue ( ln - > next ) ) & &
2021-01-06 10:34:27 +02:00
next - > size - next - > used > = length & &
next - > used < PROTO_REPLY_CHUNK_BYTES * 4 )
{
2021-05-19 02:59:48 +00:00
memmove ( next - > buf ( ) + length , next - > buf ( ) , next - > used ) ;
memcpy ( next - > buf ( ) , s , length ) ;
2021-01-06 10:34:27 +02:00
next - > used + = length ;
2019-02-15 14:11:05 -05:00
listDelNode ( c - > reply , ln ) ;
} else {
/* Create a new node */
2021-05-19 02:59:48 +00:00
clientReplyBlock * buf = ( clientReplyBlock * ) zmalloc ( length + sizeof ( clientReplyBlock ) ) ;
2019-02-15 14:11:05 -05:00
/* Take over the allocation's internal fragmentation */
2020-10-02 08:19:44 +03:00
buf - > size = zmalloc_usable_size ( buf ) - sizeof ( clientReplyBlock ) ;
2021-01-06 10:34:27 +02:00
buf - > used = length ;
2021-05-19 02:59:48 +00:00
memcpy ( buf - > buf ( ) , s , length ) ;
2019-02-15 14:11:05 -05:00
listNodeValue ( ln ) = buf ;
c - > reply_bytes + = buf - > size ;
2021-03-30 23:06:29 +03:00
asyncCloseClientOnOutputBufferLimitReached ( c ) ;
2019-02-15 14:11:05 -05:00
}
}
2021-01-06 10:34:27 +02:00
/* Populate the length object and try gluing it to the next chunk. */
void setDeferredAggregateLen ( client * c , void * node , long length , char prefix ) {
serverAssert ( length > = 0 ) ;
2019-02-18 22:25:35 -05:00
2021-05-19 02:59:48 +00:00
if ( FCorrectThread ( c ) ) {
2021-05-25 20:51:18 +00:00
/* Abort when *node is NULL: when the client should not accept writes
* we return NULL in addReplyDeferredLen ( ) */
if ( node = = NULL ) return ;
2021-05-19 02:59:48 +00:00
char lenstr [ 128 ] ;
size_t lenstr_len = sprintf ( lenstr , " %c%ld \r \n " , prefix , length ) ;
setDeferredReply ( c , node , lenstr , lenstr_len ) ;
} else {
char lenstr [ 128 ] ;
int lenstr_len = sprintf ( lenstr , " %c%ld \r \n " , prefix , length ) ;
size_t idxSplice = ( size_t ) node ;
serverAssert ( idxSplice < = c - > replyAsync - > used ) ;
if ( c - > replyAsync - > size < ( c - > replyAsync - > used + lenstr_len ) )
{
int newsize = std : : max ( c - > replyAsync - > used + lenstr_len , c - > replyAsync - > size * 2 ) ;
clientReplyBlock * replyNew = ( clientReplyBlock * ) zmalloc ( sizeof ( clientReplyBlock ) + newsize ) ;
replyNew - > size = zmalloc_usable_size ( replyNew ) - sizeof ( clientReplyBlock ) ;
replyNew - > used = c - > replyAsync - > used ;
memcpy ( replyNew - > buf ( ) , c - > replyAsync - > buf ( ) , c - > replyAsync - > used ) ;
zfree ( c - > replyAsync ) ;
c - > replyAsync = replyNew ;
}
memmove ( c - > replyAsync - > buf ( ) + idxSplice + lenstr_len , c - > replyAsync - > buf ( ) + idxSplice , c - > replyAsync - > used - idxSplice ) ;
memcpy ( c - > replyAsync - > buf ( ) + idxSplice , lenstr , lenstr_len ) ;
c - > replyAsync - > used + = lenstr_len ;
2019-02-18 22:25:35 -05:00
}
}
2019-02-15 14:11:05 -05:00
void setDeferredArrayLen ( client * c , void * node , long length ) {
2018-11-08 12:28:56 +01:00
setDeferredAggregateLen ( c , node , length , ' * ' ) ;
2019-02-18 22:25:35 -05:00
}
2019-02-15 14:11:05 -05:00
void setDeferredMapLen ( client * c , void * node , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' % ' ;
if ( c - > resp = = 2 ) length * = 2 ;
setDeferredAggregateLen ( c , node , length , prefix ) ;
}
void setDeferredSetLen ( client * c , void * node , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' ~ ' ;
setDeferredAggregateLen ( c , node , length , prefix ) ;
}
void setDeferredAttributeLen ( client * c , void * node , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' | ' ;
if ( c - > resp = = 2 ) length * = 2 ;
setDeferredAggregateLen ( c , node , length , prefix ) ;
}
void setDeferredPushLen ( client * c , void * node , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' > ' ;
setDeferredAggregateLen ( c , node , length , prefix ) ;
}
/* Add a double as a bulk reply */
2020-10-24 02:18:03 +00:00
void addReplyDouble ( client * c , double d ) {
2019-07-11 20:20:01 -04:00
if ( std : : isinf ( d ) ) {
2019-02-15 14:11:05 -05:00
/* Libc in odd systems (Hi Solaris!) will format infinite in a
* different way , so better to handle it in an explicit way . */
if ( c - > resp = = 2 ) {
2020-10-24 02:18:03 +00:00
addReplyBulkCString ( c , d > 0 ? " inf " : " -inf " ) ;
2019-02-15 14:11:05 -05:00
} else {
2020-10-24 02:18:03 +00:00
addReplyProto ( c , d > 0 ? " ,inf \r \n " : " ,-inf \r \n " ,
d > 0 ? 6 : 7 ) ;
2019-02-15 14:11:05 -05:00
}
} else {
char dbuf [ MAX_LONG_DOUBLE_CHARS + 3 ] ,
sbuf [ MAX_LONG_DOUBLE_CHARS + 32 ] ;
int dlen , slen ;
if ( c - > resp = = 2 ) {
dlen = snprintf ( dbuf , sizeof ( dbuf ) , " %.17g " , d ) ;
slen = snprintf ( sbuf , sizeof ( sbuf ) , " $%d \r \n %s \r \n " , dlen , dbuf ) ;
2020-10-24 02:18:03 +00:00
addReplyProto ( c , sbuf , slen ) ;
2019-02-15 14:11:05 -05:00
} else {
dlen = snprintf ( dbuf , sizeof ( dbuf ) , " ,%.17g \r \n " , d ) ;
2020-10-24 02:18:03 +00:00
addReplyProto ( c , dbuf , dlen ) ;
2019-02-15 14:11:05 -05:00
}
}
}
/* Add a long double as a bulk reply, but uses a human readable formatting
* of the double instead of exposing the crude behavior of doubles to the
* dear user . */
2020-10-24 02:18:03 +00:00
void addReplyHumanLongDouble ( client * c , long double d ) {
2019-02-15 14:11:05 -05:00
if ( c - > resp = = 2 ) {
robj * o = createStringObjectFromLongDouble ( d , 1 ) ;
2020-10-24 02:18:03 +00:00
addReplyBulk ( c , o ) ;
2019-02-15 14:11:05 -05:00
decrRefCount ( o ) ;
} else {
char buf [ MAX_LONG_DOUBLE_CHARS ] ;
2019-11-03 16:42:31 +02:00
int len = ld2string ( buf , sizeof ( buf ) , d , LD_STR_HUMAN ) ;
2020-10-24 02:18:03 +00:00
addReplyProto ( c , " , " , 1 ) ;
addReplyProto ( c , buf , len ) ;
addReplyProto ( c , " \r \n " , 2 ) ;
2019-02-15 14:11:05 -05:00
}
}
/* Add a long long as integer reply or bulk len / multi bulk count.
* Basically this is used to output < prefix > < long long > < crlf > . */
2020-10-24 02:18:03 +00:00
void addReplyLongLongWithPrefix ( client * c , long long ll , char prefix ) {
2019-02-15 14:11:05 -05:00
char buf [ 128 ] ;
int len ;
/* Things like $3\r\n or *2\r\n are emitted very often by the protocol
* so we have a few shared objects to use if the integer is small
* like it is most of the times . */
if ( prefix = = ' * ' & & ll < OBJ_SHARED_BULKHDR_LEN & & ll > = 0 ) {
2020-10-24 02:18:03 +00:00
addReply ( c , shared . mbulkhdr [ ll ] ) ;
2019-02-15 14:11:05 -05:00
return ;
} else if ( prefix = = ' $ ' & & ll < OBJ_SHARED_BULKHDR_LEN & & ll > = 0 ) {
2020-10-24 02:18:03 +00:00
addReply ( c , shared . bulkhdr [ ll ] ) ;
2019-02-15 14:11:05 -05:00
return ;
}
buf [ 0 ] = prefix ;
len = ll2string ( buf + 1 , sizeof ( buf ) - 1 , ll ) ;
buf [ len + 1 ] = ' \r ' ;
buf [ len + 2 ] = ' \n ' ;
2020-10-24 02:18:03 +00:00
addReplyProto ( c , buf , len + 3 ) ;
2019-02-15 14:11:05 -05:00
}
2020-10-24 02:18:03 +00:00
void addReplyLongLong ( client * c , long long ll ) {
2019-02-15 14:11:05 -05:00
if ( ll = = 0 )
2020-10-24 02:18:03 +00:00
addReply ( c , shared . czero ) ;
2019-02-15 14:11:05 -05:00
else if ( ll = = 1 )
2020-10-24 02:18:03 +00:00
addReply ( c , shared . cone ) ;
2019-02-15 14:11:05 -05:00
else
2020-10-24 02:18:03 +00:00
addReplyLongLongWithPrefix ( c , ll , ' : ' ) ;
2019-02-20 01:20:26 -05:00
}
2020-10-24 02:18:03 +00:00
void addReplyAggregateLen ( client * c , long length , int prefix ) {
2020-08-14 16:05:34 +03:00
serverAssert ( length > = 0 ) ;
2021-02-02 16:54:19 +08:00
addReplyLongLongWithPrefix ( c , length , prefix ) ;
2019-02-15 14:11:05 -05:00
}
void addReplyArrayLen ( client * c , long length ) {
2020-10-24 02:18:03 +00:00
addReplyAggregateLen ( c , length , ' * ' ) ;
2019-02-18 22:25:35 -05:00
}
2020-10-24 02:18:03 +00:00
void addReplyMapLen ( client * c , long length ) {
2019-02-15 14:11:05 -05:00
int prefix = c - > resp = = 2 ? ' * ' : ' % ' ;
if ( c - > resp = = 2 ) length * = 2 ;
2020-10-24 02:18:03 +00:00
addReplyAggregateLen ( c , length , prefix ) ;
2019-02-15 14:11:05 -05:00
}
void addReplySetLen ( client * c , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' ~ ' ;
addReplyAggregateLen ( c , length , prefix ) ;
}
void addReplyAttributeLen ( client * c , long length ) {
int prefix = c - > resp = = 2 ? ' * ' : ' | ' ;
if ( c - > resp = = 2 ) length * = 2 ;
addReplyAggregateLen ( c , length , prefix ) ;
}
2019-02-18 22:25:35 -05:00
void addReplyPushLen ( client * c , long length ) {
2020-10-24 02:18:03 +00:00
int prefix = c - > resp = = 2 ? ' * ' : ' > ' ;
addReplyAggregateLen ( c , length , prefix ) ;
2019-02-18 22:25:35 -05:00
}
2020-10-24 02:18:03 +00:00
void addReplyNull ( client * c ) {
2019-02-15 14:11:05 -05:00
if ( c - > resp = = 2 ) {
2020-10-24 02:18:03 +00:00
addReplyProto ( c , " $-1 \r \n " , 5 ) ;
2019-02-15 14:11:05 -05:00
} else {
2020-10-24 02:18:03 +00:00
addReplyProto ( c , " _ \r \n " , 3 ) ;
2019-02-15 14:11:05 -05:00
}
}
void addReplyBool ( client * c , int b ) {
if ( c - > resp = = 2 ) {
addReply ( c , b ? shared . cone : shared . czero ) ;
} else {
addReplyProto ( c , b ? " #t \r \n " : " #f \r \n " , 4 ) ;
}
}
/* A null array is a concept that no longer exists in RESP3. However
* RESP2 had it , so API - wise we have this call , that will emit the correct
* RESP2 protocol , however for RESP3 the reply will always be just the
* Null type " _ \r \n " . */
2020-10-24 02:18:03 +00:00
void addReplyNullArray ( client * c )
2020-01-27 19:59:04 -05:00
{
2019-02-15 14:11:05 -05:00
if ( c - > resp = = 2 ) {
2020-10-24 02:18:03 +00:00
addReplyProto ( c , " *-1 \r \n " , 5 ) ;
2019-02-15 14:11:05 -05:00
} else {
2020-10-24 02:18:03 +00:00
addReplyProto ( c , " _ \r \n " , 3 ) ;
2019-02-15 14:11:05 -05:00
}
}
/* Create the length prefix of a bulk reply, example: $2234 */
2020-10-24 02:18:03 +00:00
void addReplyBulkLen ( client * c , robj_roptr obj ) {
2019-02-20 03:52:57 +00:00
size_t len = stringObjectLen ( obj ) ;
2019-02-15 14:11:05 -05:00
2021-02-02 16:54:19 +08:00
addReplyLongLongWithPrefix ( c , len , ' $ ' ) ;
2019-02-15 14:11:05 -05:00
}
/* Add a Redis Object as a bulk reply */
2020-10-24 02:18:03 +00:00
void addReplyBulk ( client * c , robj_roptr obj ) {
addReplyBulkLen ( c , obj ) ;
addReply ( c , obj ) ;
addReply ( c , shared . crlf ) ;
2019-02-15 14:11:05 -05:00
}
/* Add a C buffer as bulk reply */
void addReplyBulkCBuffer ( client * c , const void * p , size_t len ) {
2020-10-24 02:18:03 +00:00
addReplyLongLongWithPrefix ( c , len , ' $ ' ) ;
addReplyProto ( c , ( const char * ) p , len ) ;
addReply ( c , shared . crlf ) ;
2019-02-15 14:11:05 -05:00
}
/* Add sds to reply (takes ownership of sds and frees it) */
2020-10-24 02:18:03 +00:00
void addReplyBulkSds ( client * c , sds s ) {
addReplyLongLongWithPrefix ( c , sdslen ( s ) , ' $ ' ) ;
addReplySds ( c , s ) ;
addReply ( c , shared . crlf ) ;
2019-02-15 14:11:05 -05:00
}
2021-01-06 10:34:27 +02:00
/* Set sds to a deferred reply (for symmetry with addReplyBulkSds it also frees the sds) */
void setDeferredReplyBulkSds ( client * c , void * node , sds s ) {
sds reply = sdscatprintf ( sdsempty ( ) , " $%d \r \n %s \r \n " , ( unsigned ) sdslen ( s ) , s ) ;
setDeferredReply ( c , node , reply , sdslen ( reply ) ) ;
sdsfree ( reply ) ;
sdsfree ( s ) ;
}
2019-02-15 14:11:05 -05:00
/* Add a C null term string as bulk reply */
2020-10-24 02:18:03 +00:00
void addReplyBulkCString ( client * c , const char * s ) {
2019-02-15 14:11:05 -05:00
if ( s = = NULL ) {
2019-05-20 23:39:44 -04:00
if ( c - > resp < 3 )
2020-10-24 02:18:03 +00:00
addReply ( c , shared . nullbulk ) ;
2019-05-20 23:39:44 -04:00
else
2020-10-24 02:18:03 +00:00
addReplyNull ( c ) ;
2019-02-15 14:11:05 -05:00
} else {
2020-10-24 02:18:03 +00:00
addReplyBulkCBuffer ( c , s , strlen ( s ) ) ;
2019-02-15 14:11:05 -05:00
}
}
/* Add a long long as a bulk reply */
void addReplyBulkLongLong ( client * c , long long ll ) {
char buf [ 64 ] ;
int len ;
len = ll2string ( buf , 64 , ll ) ;
addReplyBulkCBuffer ( c , buf , len ) ;
}
/* Reply with a verbatim type having the specified extension.
*
* The ' ext ' is the " extension " of the file , actually just a three
* character type that describes the format of the verbatim string .
* For instance " txt " means it should be interpreted as a text only
* file by the receiver , " md " as markdown , and so forth . Only the
* three first characters of the extension are used , and if the
* provided one is shorter than that , the remaining is filled with
* spaces . */
2020-10-24 02:18:03 +00:00
void addReplyVerbatim ( client * c , const char * s , size_t len , const char * ext ) {
2019-02-15 14:11:05 -05:00
if ( c - > resp = = 2 ) {
2020-10-24 02:18:03 +00:00
addReplyBulkCBuffer ( c , s , len ) ;
2019-02-15 14:11:05 -05:00
} else {
char buf [ 32 ] ;
size_t preflen = snprintf ( buf , sizeof ( buf ) , " =%zu \r \n xxx: " , len + 4 ) ;
char * p = buf + preflen - 4 ;
for ( int i = 0 ; i < 3 ; i + + ) {
if ( * ext = = ' \0 ' ) {
p [ i ] = ' ' ;
} else {
p [ i ] = * ext + + ;
}
}
2020-10-24 02:18:03 +00:00
addReplyProto ( c , buf , preflen ) ;
addReplyProto ( c , s , len ) ;
addReplyProto ( c , " \r \n " , 2 ) ;
2019-02-15 14:11:05 -05:00
}
}
/* Add an array of C strings as status replies with a heading.
* This function is typically invoked by from commands that support
* subcommands in response to the ' help ' subcommand . The help array
* is terminated by NULL sentinel . */
void addReplyHelp ( client * c , const char * * help ) {
sds cmd = sdsnew ( ( char * ) ptrFromObj ( c - > argv [ 0 ] ) ) ;
void * blenp = addReplyDeferredLen ( c ) ;
int blen = 0 ;
sdstoupper ( cmd ) ;
addReplyStatusFormat ( c ,
2021-01-04 17:02:57 +02:00
" %s <subcommand> [<arg> [value] [opt] ...]. Subcommands are: " , cmd ) ;
2019-02-15 14:11:05 -05:00
sdsfree ( cmd ) ;
while ( help [ blen ] ) addReplyStatus ( c , help [ blen + + ] ) ;
2021-01-04 17:02:57 +02:00
addReplyStatus ( c , " HELP " ) ;
addReplyStatus ( c , " Prints this help. " ) ;
blen + = 1 ; /* Account for the header. */
blen + = 2 ; /* Account for the footer. */
2019-02-15 14:11:05 -05:00
setDeferredArrayLen ( c , blenp , blen ) ;
}
/* Add a suggestive error reply.
* This function is typically invoked by from commands that support
* subcommands in response to an unknown subcommand or argument error . */
void addReplySubcommandSyntaxError ( client * c ) {
sds cmd = sdsnew ( ( char * ) ptrFromObj ( c - > argv [ 0 ] ) ) ;
sdstoupper ( cmd ) ;
addReplyErrorFormat ( c ,
" Unknown subcommand or wrong number of arguments for '%s'. Try %s HELP. " ,
( char * ) ptrFromObj ( c - > argv [ 1 ] ) , cmd ) ;
sdsfree ( cmd ) ;
}
2020-12-24 03:42:52 -05:00
/* Append 'src' client output buffers into 'dst' client output buffers.
2019-03-24 13:10:55 +02:00
* This function clears the output buffers of ' src ' */
void AddReplyFromClient ( client * dst , client * src ) {
2020-12-08 16:41:20 +02:00
/* If the source client contains a partial response due to client output
* buffer limits , propagate that to the dest rather than copy a partial
* reply . We don ' t wanna run the risk of copying partial response in case
* for some reason the output limits don ' t reach the same decision ( maybe
* they changed ) */
if ( src - > flags & CLIENT_CLOSE_ASAP ) {
sds client = catClientInfoString ( sdsempty ( ) , dst ) ;
freeClientAsync ( dst ) ;
serverLog ( LL_WARNING , " Client %s scheduled to be closed ASAP for overcoming of output buffer limits. " , client ) ;
sdsfree ( client ) ;
2019-03-24 13:10:55 +02:00
return ;
2020-12-08 16:41:20 +02:00
}
/* First add the static buffer (either into the static buffer or reply list) */
2019-03-24 13:10:55 +02:00
addReplyProto ( dst , src - > buf , src - > bufpos ) ;
2020-12-08 16:41:20 +02:00
/* We need to check with prepareClientToWrite again (after addReplyProto)
* since addReplyProto may have changed something ( like CLIENT_CLOSE_ASAP ) */
if ( prepareClientToWrite ( dst ) ! = C_OK )
return ;
/* We're bypassing _addReplyProtoToList, so we need to add the pre/post
* checks in it . */
if ( dst - > flags & CLIENT_CLOSE_AFTER_REPLY ) return ;
/* Concatenate the reply list into the dest */
2019-03-24 13:10:55 +02:00
if ( listLength ( src - > reply ) )
listJoin ( dst - > reply , src - > reply ) ;
dst - > reply_bytes + = src - > reply_bytes ;
src - > reply_bytes = 0 ;
src - > bufpos = 0 ;
2020-12-08 16:41:20 +02:00
/* Check output buffer limits */
asyncCloseClientOnOutputBufferLimitReached ( dst ) ;
2019-03-24 13:10:55 +02:00
}
2019-02-15 14:11:05 -05:00
/* Copy 'src' client output buffers into 'dst' client output buffers.
* The function takes care of freeing the old output buffers of the
* destination client . */
void copyClientOutputBuffer ( client * dst , client * src ) {
listRelease ( dst - > reply ) ;
dst - > sentlen = 0 ;
dst - > reply = listDup ( src - > reply ) ;
memcpy ( dst - > buf , src - > buf , src - > bufpos ) ;
dst - > bufpos = src - > bufpos ;
dst - > reply_bytes = src - > reply_bytes ;
}
/* Return true if the specified client has pending reply buffers to write to
* the socket . */
2019-02-22 01:24:16 -05:00
int clientHasPendingReplies ( client * c ) {
2020-05-10 23:56:29 -04:00
return ( c - > bufpos | | listLength ( c - > reply ) ) ;
2019-02-15 14:11:05 -05:00
}
2020-02-11 03:44:28 -05:00
static std : : atomic < int > rgacceptsInFlight [ MAX_EVENT_LOOPS ] ;
2020-02-11 01:41:00 -05:00
int chooseBestThreadForAccept ( )
2020-02-11 01:00:21 -05:00
{
int ielMinLoad = 0 ;
2020-02-11 03:44:28 -05:00
int cclientsMin = INT_MAX ;
2020-02-11 01:00:21 -05:00
for ( int iel = 0 ; iel < cserver . cthreads ; + + iel )
{
2020-02-11 03:44:28 -05:00
int cclientsThread ;
atomicGet ( g_pserver - > rgthreadvar [ iel ] . cclients , cclientsThread ) ;
cclientsThread + = rgacceptsInFlight [ iel ] . load ( std : : memory_order_relaxed ) ;
if ( cclientsThread < cserver . thread_min_client_threshold )
2020-02-11 01:00:21 -05:00
return iel ;
2020-02-11 03:44:28 -05:00
if ( cclientsThread < cclientsMin )
{
cclientsMin = cclientsThread ;
2020-02-11 01:00:21 -05:00
ielMinLoad = iel ;
2020-02-11 03:44:28 -05:00
}
2020-02-11 01:00:21 -05:00
}
return ielMinLoad ;
}
2019-09-12 10:56:54 +03:00
void clientAcceptHandler ( connection * conn ) {
2020-01-27 02:55:48 -05:00
client * c = ( client * ) connGetPrivateData ( conn ) ;
2010-06-22 00:07:48 +02:00
2019-09-12 10:56:54 +03:00
if ( connGetState ( conn ) ! = CONN_STATE_CONNECTED ) {
2019-02-15 14:11:05 -05:00
serverLog ( LL_WARNING ,
2019-09-12 10:56:54 +03:00
" Error accepting a client connection: %s " ,
connGetLastError ( conn ) ) ;
2020-03-22 14:47:44 +02:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return ;
}
2019-02-26 15:14:35 -05:00
// Set thread affinity
2019-04-21 13:20:45 -04:00
if ( cserver . fThreadAffinity )
2020-01-27 02:55:48 -05:00
connSetThreadAffinity ( conn , c - > iel ) ;
2019-02-15 14:11:05 -05:00
/* If the server is running in protected mode (the default) and there
* is no password set , nor a specific interface is bound , we don ' t accept
* requests from non loopback interfaces . Instead we try to explain the
* user what to do to fix it if needed . */
2019-04-21 14:01:10 -04:00
if ( g_pserver - > protected_mode & &
g_pserver - > bindaddr_count = = 0 & &
2019-02-15 14:11:05 -05:00
DefaultUser - > flags & USER_FLAG_NOPASS & &
2019-09-12 10:56:54 +03:00
! ( c - > flags & CLIENT_UNIX_SOCKET ) )
2019-02-15 14:11:05 -05:00
{
2019-09-12 10:56:54 +03:00
char cip [ NET_IP_STR_LEN + 1 ] = { 0 } ;
connPeerToString ( conn , cip , sizeof ( cip ) - 1 , NULL ) ;
if ( strcmp ( cip , " 127.0.0.1 " ) & & strcmp ( cip , " ::1 " ) ) {
2019-02-15 14:11:05 -05:00
const char * err =
2021-04-23 21:55:01 +00:00
" -DENIED KeyDB is running in protected mode because protected "
2019-02-15 14:11:05 -05:00
" mode is enabled, no bind address was specified, no "
" authentication password is requested to clients. In this mode "
" connections are only accepted from the loopback interface. "
2021-04-23 21:55:01 +00:00
" If you want to connect from external computers to KeyDB you "
2019-02-15 14:11:05 -05:00
" may adopt one of the following solutions: "
" 1) Just disable protected mode sending the command "
" 'CONFIG SET protected-mode no' from the loopback interface "
2021-04-23 21:55:01 +00:00
" by connecting to KeyDB from the same host the server is "
" running, however MAKE SURE KeyDB is not publicly accessible "
2019-02-15 14:11:05 -05:00
" from internet if you do so. Use CONFIG REWRITE to make this "
" change permanent. "
" 2) Alternatively you can just disable the protected mode by "
2021-04-23 21:55:01 +00:00
" editing the KeyDB configuration file, and setting the protected "
2020-10-20 08:58:53 -04:00
" mode option to 'no', and then restarting the server "
2019-02-15 14:11:05 -05:00
" 3) If you started the server manually just for testing, restart "
" it with the '--protected-mode no' option. "
" 4) Setup a bind address or an authentication password. "
" NOTE: You only need to do one of the above things in order for "
" the server to start accepting connections from the outside. \r \n " ;
2019-09-12 10:56:54 +03:00
if ( connWrite ( c - > conn , err , strlen ( err ) ) = = - 1 ) {
2019-02-15 14:11:05 -05:00
/* Nothing to do, Just to avoid the warning... */
}
2019-04-21 14:01:10 -04:00
g_pserver - > stat_rejected_conn + + ;
2020-03-22 14:47:44 +02:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return ;
}
}
2019-04-21 14:01:10 -04:00
g_pserver - > stat_numconnections + + ;
2019-10-22 10:44:18 +02:00
moduleFireServerEvent ( REDISMODULE_EVENT_CLIENT_CHANGE ,
2019-10-22 12:48:07 +02:00
REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED ,
2019-10-22 10:44:18 +02:00
c ) ;
2019-09-12 10:56:54 +03:00
}
# define MAX_ACCEPTS_PER_CALL 1000
2020-01-27 02:55:48 -05:00
static void acceptCommonHandler ( connection * conn , int flags , char * ip , int iel ) {
2019-09-12 10:56:54 +03:00
client * c ;
2020-07-28 11:32:47 +03:00
char conninfo [ 100 ] ;
2019-09-12 10:56:54 +03:00
UNUSED ( ip ) ;
2020-01-28 17:54:00 -05:00
AeLocker locker ;
locker . arm ( nullptr ) ;
2019-09-12 10:56:54 +03:00
2020-07-28 11:32:47 +03:00
if ( connGetState ( conn ) ! = CONN_STATE_ACCEPTING ) {
serverLog ( LL_VERBOSE ,
" Accepted client connection in error state: %s (conn: %s) " ,
connGetLastError ( conn ) ,
connGetInfo ( conn , conninfo , sizeof ( conninfo ) ) ) ;
connClose ( conn ) ;
return ;
}
2020-06-16 11:45:03 +02:00
/* Limit the number of connections we take at the same time.
*
* Admission control will happen before a client is created and connAccept ( )
2019-09-12 10:56:54 +03:00
* called , because we don ' t want to even start transport - level negotiation
2020-06-16 11:45:03 +02:00
* if rejected . */
2020-09-30 19:47:55 +00:00
if ( listLength ( g_pserver - > clients ) + getClusterConnectionsCount ( )
> = g_pserver - > maxclients )
2020-06-16 11:45:03 +02:00
{
2020-09-30 19:47:55 +00:00
const char * err ;
if ( g_pserver - > cluster_enabled )
2020-06-16 11:45:03 +02:00
err = " -ERR max number of clients + cluster "
" connections reached \r \n " ;
2020-07-15 05:38:47 -04:00
else
err = " -ERR max number of clients reached \r \n " ;
2019-09-12 10:56:54 +03:00
/* That's a best effort error message, don't check write errors.
2020-06-16 11:45:03 +02:00
* Note that for TLS connections , no handshake was done yet so nothing
* is written and the connection will just drop . */
2019-09-12 10:56:54 +03:00
if ( connWrite ( conn , err , strlen ( err ) ) = = - 1 ) {
/* Nothing to do, Just to avoid the warning... */
}
2020-01-27 02:55:48 -05:00
g_pserver - > stat_rejected_conn + + ;
2019-09-12 10:56:54 +03:00
connClose ( conn ) ;
return ;
}
/* Create connection and client */
2020-01-27 02:55:48 -05:00
if ( ( c = createClient ( conn , iel ) ) = = NULL ) {
2019-09-12 10:56:54 +03:00
serverLog ( LL_WARNING ,
" Error registering fd event for the new client: %s (conn: %s) " ,
connGetLastError ( conn ) ,
connGetInfo ( conn , conninfo , sizeof ( conninfo ) ) ) ;
connClose ( conn ) ; /* May be already closed, just ignore errors */
return ;
}
/* Last chance to keep flags */
2019-02-15 14:11:05 -05:00
c - > flags | = flags ;
2019-09-12 10:56:54 +03:00
/* Initiate accept.
*
* Note that connAccept ( ) is free to do two things here :
* 1. Call clientAcceptHandler ( ) immediately ;
* 2. Schedule a future call to clientAcceptHandler ( ) .
*
* Because of that , we must do nothing else afterwards .
*/
if ( connAccept ( conn , clientAcceptHandler ) = = C_ERR ) {
char conninfo [ 100 ] ;
2020-03-22 14:47:44 +02:00
if ( connGetState ( conn ) = = CONN_STATE_ERROR )
serverLog ( LL_WARNING ,
" Error accepting a client connection: %s (conn: %s) " ,
connGetLastError ( conn ) , connGetInfo ( conn , conninfo , sizeof ( conninfo ) ) ) ;
2020-01-27 02:55:48 -05:00
freeClient ( ( client * ) connGetPrivateData ( conn ) ) ;
2019-09-12 10:56:54 +03:00
return ;
}
2019-02-15 14:11:05 -05:00
}
2020-05-23 16:03:24 -04:00
void acceptOnThread ( connection * conn , int flags , char * cip )
{
int ielCur = ielFromEventLoop ( serverTL - > el ) ;
2020-09-17 00:13:03 +00:00
bool fBootLoad = ( g_pserver - > loading = = LOADING_BOOT ) ;
2020-05-23 16:03:24 -04:00
int ielTarget = 0 ;
2020-09-17 00:13:03 +00:00
if ( fBootLoad )
2020-05-23 16:03:24 -04:00
{
ielTarget = IDX_EVENT_LOOP_MAIN ; // During load only the main thread is active
}
else if ( g_fTestMode )
{
// On test mode we don't want any bunching of clients
while ( cserver . cthreads > 1 & & ielTarget = = IDX_EVENT_LOOP_MAIN )
ielTarget = rand ( ) % cserver . cthreads ;
}
else
{
ielTarget = chooseBestThreadForAccept ( ) ;
}
rgacceptsInFlight [ ielTarget ] . fetch_add ( 1 , std : : memory_order_relaxed ) ;
if ( ielTarget ! = ielCur )
{
char * szT = nullptr ;
if ( cip ! = nullptr )
{
szT = ( char * ) zmalloc ( NET_IP_STR_LEN , MALLOC_LOCAL ) ;
memcpy ( szT , cip , NET_IP_STR_LEN ) ;
}
2020-09-17 00:13:03 +00:00
int res = aePostFunction ( g_pserver - > rgthreadvar [ ielTarget ] . el , [ conn , flags , ielTarget , szT , fBootLoad ] {
2020-05-24 19:57:16 -04:00
connMarshalThread ( conn ) ;
2020-05-23 16:03:24 -04:00
acceptCommonHandler ( conn , flags , szT , ielTarget ) ;
2020-09-17 00:13:03 +00:00
if ( ! g_fTestMode & & ! fBootLoad )
2020-05-23 16:03:24 -04:00
rgacceptsInFlight [ ielTarget ] . fetch_sub ( 1 , std : : memory_order_relaxed ) ;
zfree ( szT ) ;
} ) ;
if ( res = = AE_OK )
return ;
// If res != AE_OK we can still try to accept on the local thread
}
2020-09-17 00:13:03 +00:00
if ( ! g_fTestMode & & ! fBootLoad )
2020-05-23 16:03:24 -04:00
rgacceptsInFlight [ ielTarget ] . fetch_sub ( 1 , std : : memory_order_relaxed ) ;
aeAcquireLock ( ) ;
acceptCommonHandler ( conn , flags , cip , ielCur ) ;
aeReleaseLock ( ) ;
}
2019-02-15 14:11:05 -05:00
void acceptTcpHandler ( aeEventLoop * el , int fd , void * privdata , int mask ) {
int cport , cfd , max = MAX_ACCEPTS_PER_CALL ;
char cip [ NET_IP_STR_LEN ] ;
UNUSED ( mask ) ;
UNUSED ( privdata ) ;
2020-05-23 16:03:24 -04:00
UNUSED ( el ) ;
2019-02-15 14:11:05 -05:00
while ( max - - ) {
2019-07-18 17:11:28 -04:00
cfd = anetTcpAccept ( serverTL - > neterr , fd , cip , sizeof ( cip ) , & cport ) ;
2019-02-15 14:11:05 -05:00
if ( cfd = = ANET_ERR ) {
if ( errno ! = EWOULDBLOCK )
serverLog ( LL_WARNING ,
2019-07-18 17:11:28 -04:00
" Accepting client connection: %s " , serverTL - > neterr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
2021-01-20 04:57:30 +08:00
anetCloexec ( cfd ) ;
2019-02-15 14:11:05 -05:00
serverLog ( LL_VERBOSE , " Accepted %s:%d " , cip , cport ) ;
2020-02-11 01:00:21 -05:00
2020-05-23 16:03:24 -04:00
acceptOnThread ( connCreateAcceptedSocket ( cfd ) , 0 , cip ) ;
2019-02-15 14:11:05 -05:00
}
}
2019-09-12 10:56:54 +03:00
void acceptTLSHandler ( aeEventLoop * el , int fd , void * privdata , int mask ) {
int cport , cfd , max = MAX_ACCEPTS_PER_CALL ;
char cip [ NET_IP_STR_LEN ] ;
UNUSED ( el ) ;
UNUSED ( mask ) ;
UNUSED ( privdata ) ;
while ( max - - ) {
2020-01-27 02:55:48 -05:00
cfd = anetTcpAccept ( serverTL - > neterr , fd , cip , sizeof ( cip ) , & cport ) ;
2019-09-12 10:56:54 +03:00
if ( cfd = = ANET_ERR ) {
if ( errno ! = EWOULDBLOCK )
serverLog ( LL_WARNING ,
2020-01-27 02:55:48 -05:00
" Accepting client connection: %s " , serverTL - > neterr ) ;
2019-09-12 10:56:54 +03:00
return ;
}
2021-01-20 04:57:30 +08:00
anetCloexec ( cfd ) ;
2019-09-12 10:56:54 +03:00
serverLog ( LL_VERBOSE , " Accepted %s:%d " , cip , cport ) ;
2020-05-23 16:03:24 -04:00
acceptOnThread ( connCreateAcceptedTLS ( cfd , g_pserver - > tls_auth_clients ) , 0 , cip ) ;
2010-10-13 18:34:24 +02:00
}
}
2019-02-15 14:11:05 -05:00
void acceptUnixHandler ( aeEventLoop * el , int fd , void * privdata , int mask ) {
int cfd , max = MAX_ACCEPTS_PER_CALL ;
UNUSED ( el ) ;
UNUSED ( mask ) ;
UNUSED ( privdata ) ;
while ( max - - ) {
2019-07-18 17:11:28 -04:00
cfd = anetUnixAccept ( serverTL - > neterr , fd ) ;
2019-02-15 14:11:05 -05:00
if ( cfd = = ANET_ERR ) {
if ( errno ! = EWOULDBLOCK )
serverLog ( LL_WARNING ,
2019-07-18 17:11:28 -04:00
" Accepting client connection: %s " , serverTL - > neterr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
2021-01-20 04:57:30 +08:00
anetCloexec ( cfd ) ;
2019-04-21 14:01:10 -04:00
serverLog ( LL_VERBOSE , " Accepted connection to %s " , g_pserver - > unixsocket ) ;
2020-05-23 16:03:24 -04:00
acceptOnThread ( connCreateAcceptedSocket ( cfd ) , CLIENT_UNIX_SOCKET , NULL ) ;
2019-02-15 14:11:05 -05:00
}
}
2020-11-10 13:50:03 -08:00
void freeClientOriginalArgv ( client * c ) {
/* We didn't rewrite this client */
if ( ! c - > original_argv ) return ;
for ( int j = 0 ; j < c - > original_argc ; j + + )
decrRefCount ( c - > original_argv [ j ] ) ;
zfree ( c - > original_argv ) ;
c - > original_argv = NULL ;
c - > original_argc = 0 ;
}
2019-02-15 14:11:05 -05:00
static void freeClientArgv ( client * c ) {
int j ;
for ( j = 0 ; j < c - > argc ; j + + )
decrRefCount ( c - > argv [ j ] ) ;
c - > argc = 0 ;
c - > cmd = NULL ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
2019-02-15 14:11:05 -05:00
}
2019-03-28 15:12:43 -04:00
void disconnectSlavesExcept ( unsigned char * uuid )
{
2019-03-07 19:13:01 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-18 23:52:21 -05:00
listIter li ;
2019-02-23 00:09:34 -05:00
listNode * ln ;
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > slaves , & li ) ;
2019-02-18 23:52:21 -05:00
while ( ( ln = listNext ( & li ) ) ) {
2019-02-23 00:09:34 -05:00
client * c = ( client * ) listNodeValue ( ln ) ;
2019-03-28 15:12:43 -04:00
if ( uuid = = nullptr | | ! FUuidEqual ( c - > uuid , uuid ) )
freeClientAsync ( c ) ;
}
}
/* Close all the slaves connections. This is useful in chained replication
* when we resync with our own master and want to force all our slaves to
* resync with us as well . */
void disconnectSlaves ( void ) {
disconnectSlavesExcept ( nullptr ) ;
2019-02-15 14:11:05 -05:00
}
2020-09-22 14:47:58 +08:00
/* Check if there is any other slave waiting dumping RDB finished expect me.
* This function is useful to judge current dumping RDB can be used for full
* synchronization or not . */
int anyOtherSlaveWaitRdb ( client * except_me ) {
listIter li ;
listNode * ln ;
2021-05-19 02:59:48 +00:00
listRewind ( g_pserver - > slaves , & li ) ;
2020-09-22 14:47:58 +08:00
while ( ( ln = listNext ( & li ) ) ) {
2021-05-19 02:59:48 +00:00
client * slave = ( client * ) listNodeValue ( ln ) ;
2020-09-22 14:47:58 +08:00
if ( slave ! = except_me & &
slave - > replstate = = SLAVE_STATE_WAIT_BGSAVE_END )
{
return 1 ;
}
}
return 0 ;
}
2019-02-15 14:11:05 -05:00
/* Remove the specified client from global lists where the client could
* be referenced , not including the Pub / Sub channels .
* This is used by freeClient ( ) and replicationCacheMaster ( ) . */
void unlinkClient ( client * c ) {
listNode * ln ;
2019-02-19 01:11:00 -05:00
AssertCorrectThread ( c ) ;
2020-01-27 02:55:48 -05:00
serverAssert ( c - > conn = = nullptr | | GlobalLocksAcquired ( ) ) ;
serverAssert ( c - > conn = = nullptr | | c - > lock . fOwnLock ( ) ) ;
2019-02-15 14:11:05 -05:00
/* If this is marked as current client unset it. */
2019-05-09 19:00:27 -04:00
if ( serverTL & & serverTL - > current_client = = c ) serverTL - > current_client = NULL ;
2019-02-15 14:11:05 -05:00
2019-09-12 10:56:54 +03:00
/* Certain operations must be done only if the client has an active connection.
2019-02-15 14:11:05 -05:00
* If the client was already unlinked or if it ' s a " fake client " the
2019-09-12 10:56:54 +03:00
* conn is already set to NULL . */
if ( c - > conn ) {
2019-02-15 14:11:05 -05:00
/* Remove from the list of active clients. */
if ( c - > client_list_node ) {
uint64_t id = htonu64 ( c - > id ) ;
2019-04-21 14:01:10 -04:00
raxRemove ( g_pserver - > clients_index , ( unsigned char * ) & id , sizeof ( id ) , NULL ) ;
listDelNode ( g_pserver - > clients , c - > client_list_node ) ;
2019-02-15 14:11:05 -05:00
c - > client_list_node = NULL ;
}
2019-08-11 16:07:53 +03:00
/* Check if this is a replica waiting for diskless replication (rdb pipe),
* in which case it needs to be cleaned from that list */
if ( c - > flags & CLIENT_SLAVE & &
c - > replstate = = SLAVE_STATE_WAIT_BGSAVE_END & &
2020-01-27 02:55:48 -05:00
g_pserver - > rdb_pipe_conns )
2019-08-11 16:07:53 +03:00
{
int i ;
2020-01-27 02:55:48 -05:00
for ( i = 0 ; i < g_pserver - > rdb_pipe_numconns ; i + + ) {
if ( g_pserver - > rdb_pipe_conns [ i ] = = c - > conn ) {
2019-08-11 16:07:53 +03:00
rdbPipeWriteHandlerConnRemoved ( c - > conn ) ;
2020-01-27 02:55:48 -05:00
g_pserver - > rdb_pipe_conns [ i ] = NULL ;
2019-08-11 16:07:53 +03:00
break ;
}
}
2017-03-21 07:20:02 -07:00
}
2019-09-12 10:56:54 +03:00
connClose ( c - > conn ) ;
c - > conn = NULL ;
2019-04-21 14:01:10 -04:00
atomicDecr ( g_pserver - > rgthreadvar [ c - > iel ] . cclients , 1 ) ;
2019-02-15 14:11:05 -05:00
}
/* Remove from the list of pending writes if needed. */
if ( c - > flags & CLIENT_PENDING_WRITE ) {
2019-04-21 14:01:10 -04:00
std : : unique_lock < fastlock > lockf ( g_pserver - > rgthreadvar [ c - > iel ] . lockPendingWrite ) ;
2019-06-16 20:26:03 -04:00
auto itr = std : : find ( g_pserver - > rgthreadvar [ c - > iel ] . clients_pending_write . begin ( ) ,
g_pserver - > rgthreadvar [ c - > iel ] . clients_pending_write . end ( ) , c ) ;
serverAssert ( itr ! = g_pserver - > rgthreadvar [ c - > iel ] . clients_pending_write . end ( ) ) ;
g_pserver - > rgthreadvar [ c - > iel ] . clients_pending_write . erase ( itr ) ;
2019-02-15 14:11:05 -05:00
c - > flags & = ~ CLIENT_PENDING_WRITE ;
}
/* When client was just unblocked because of a blocking operation,
* remove it from the list of unblocked clients . */
if ( c - > flags & CLIENT_UNBLOCKED ) {
2019-04-21 14:01:10 -04:00
ln = listSearchKey ( g_pserver - > rgthreadvar [ c - > iel ] . unblocked_clients , c ) ;
2019-02-15 14:11:05 -05:00
serverAssert ( ln ! = NULL ) ;
2019-04-21 14:01:10 -04:00
listDelNode ( g_pserver - > rgthreadvar [ c - > iel ] . unblocked_clients , ln ) ;
2019-02-15 14:11:05 -05:00
c - > flags & = ~ CLIENT_UNBLOCKED ;
}
2019-02-19 01:11:00 -05:00
2019-02-20 23:30:21 -05:00
if ( c - > fPendingAsyncWrite ) {
2019-02-20 01:20:26 -05:00
ln = NULL ;
2019-02-22 21:00:14 -05:00
bool fFound = false ;
2019-04-21 13:20:45 -04:00
for ( int iel = 0 ; iel < cserver . cthreads ; + + iel )
2019-02-20 01:20:26 -05:00
{
2019-04-21 14:01:10 -04:00
ln = listSearchKey ( g_pserver - > rgthreadvar [ iel ] . clients_pending_asyncwrite , c ) ;
2019-02-20 01:20:26 -05:00
if ( ln )
2019-02-22 21:00:14 -05:00
{
fFound = true ;
2019-04-21 14:01:10 -04:00
listDelNode ( g_pserver - > rgthreadvar [ iel ] . clients_pending_asyncwrite , ln ) ;
2019-02-22 21:00:14 -05:00
}
2019-02-20 01:20:26 -05:00
}
2019-02-22 21:00:14 -05:00
serverAssert ( fFound ) ;
2019-02-20 23:30:21 -05:00
c - > fPendingAsyncWrite = FALSE ;
2019-02-19 01:11:00 -05:00
}
2019-07-19 00:01:56 -04:00
2019-06-29 20:08:41 -04:00
/* Clear the tracking status. */
if ( c - > flags & CLIENT_TRACKING ) disableTracking ( c ) ;
2019-02-15 14:11:05 -05:00
}
2019-08-26 20:18:52 -04:00
bool freeClient ( client * c ) {
2019-02-15 14:11:05 -05:00
listNode * ln ;
2020-01-27 02:55:48 -05:00
serverAssert ( c - > conn = = nullptr | | GlobalLocksAcquired ( ) ) ;
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2019-02-22 21:00:14 -05:00
std : : unique_lock < decltype ( c - > lock ) > ulock ( c - > lock ) ;
2019-02-15 14:11:05 -05:00
/* If a client is protected, yet we need to free it right now, make sure
* to at least use asynchronous freeing . */
2019-08-26 20:18:52 -04:00
if ( c - > flags & CLIENT_PROTECTED | | c - > casyncOpsPending ) {
2019-02-15 14:11:05 -05:00
freeClientAsync ( c ) ;
2019-08-26 20:18:52 -04:00
return false ;
2019-02-15 14:11:05 -05:00
}
2019-10-23 10:52:25 +02:00
/* For connected clients, call the disconnection event of modules hooks. */
if ( c - > conn ) {
moduleFireServerEvent ( REDISMODULE_EVENT_CLIENT_CHANGE ,
REDISMODULE_SUBEVENT_CLIENT_CHANGE_DISCONNECTED ,
c ) ;
}
2018-10-09 13:25:53 +02:00
2019-02-26 01:23:11 +00:00
/* Notify module system that this client auth status changed. */
moduleNotifyUserChanged ( c ) ;
2020-05-16 17:15:35 +02:00
/* If this client was scheduled for async freeing we need to remove it
* from the queue . Note that we need to do this here , because later
* we may call replicationCacheMaster ( ) and the client should already
* be removed from the list of clients to free . */
if ( c - > flags & CLIENT_CLOSE_ASAP ) {
2020-05-22 16:53:10 -04:00
ln = listSearchKey ( g_pserver - > clients_to_close , c ) ;
2020-05-16 17:15:35 +02:00
serverAssert ( ln ! = NULL ) ;
2020-05-22 16:53:10 -04:00
listDelNode ( g_pserver - > clients_to_close , ln ) ;
2020-05-16 17:15:35 +02:00
}
Squash merging 125 typo/grammar/comment/doc PRs (#7773)
List of squashed commits or PRs
===============================
commit 66801ea
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Jan 13 00:54:31 2020 -0500
typo fix in acl.c
commit 46f55db
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun Sep 6 18:24:11 2020 +0300
Updates a couple of comments
Specifically:
* RM_AutoMemory completed instead of pointing to docs
* Updated link to custom type doc
commit 61a2aa0
Author: xindoo <xindoo@qq.com>
Date: Tue Sep 1 19:24:59 2020 +0800
Correct errors in code comments
commit a5871d1
Author: yz1509 <pro-756@qq.com>
Date: Tue Sep 1 18:36:06 2020 +0800
fix typos in module.c
commit 41eede7
Author: bookug <bookug@qq.com>
Date: Sat Aug 15 01:11:33 2020 +0800
docs: fix typos in comments
commit c303c84
Author: lazy-snail <ws.niu@outlook.com>
Date: Fri Aug 7 11:15:44 2020 +0800
fix spelling in redis.conf
commit 1eb76bf
Author: zhujian <zhujianxyz@gmail.com>
Date: Thu Aug 6 15:22:10 2020 +0800
add a missing 'n' in comment
commit 1530ec2
Author: Daniel Dai <764122422@qq.com>
Date: Mon Jul 27 00:46:35 2020 -0400
fix spelling in tracking.c
commit e517b31
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:32 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit c300eff
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:23 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit 4c058a8
Author: 陈浩鹏 <chenhaopeng@heytea.com>
Date: Thu Jun 25 19:00:56 2020 +0800
Grammar fix and clarification
commit 5fcaa81
Author: bodong.ybd <bodong.ybd@alibaba-inc.com>
Date: Fri Jun 19 10:09:00 2020 +0800
Fix typos
commit 4caca9a
Author: Pruthvi P <pruthvi@ixigo.com>
Date: Fri May 22 00:33:22 2020 +0530
Fix typo eviciton => eviction
commit b2a25f6
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Sun May 17 12:39:59 2020 -0400
Fix a typo.
commit 12842ae
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun May 3 17:16:59 2020 -0400
fix spelling in redis conf
commit ddba07c
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Sat May 2 23:25:34 2020 +0100
Correct a "conflicts" spelling error.
commit 8fc7bf2
Author: Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Date: Thu Apr 30 10:25:27 2020 +0900
docs: fix EXPIRE_FAST_CYCLE_DURATION to ACTIVE_EXPIRE_CYCLE_FAST_DURATION
commit 9b2b67a
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Fri Apr 24 11:46:22 2020 -0400
Fix a typo.
commit 0746f10
Author: devilinrust <63737265+devilinrust@users.noreply.github.com>
Date: Thu Apr 16 00:17:53 2020 +0200
Fix typos in server.c
commit 92b588d
Author: benjessop12 <56115861+benjessop12@users.noreply.github.com>
Date: Mon Apr 13 13:43:55 2020 +0100
Fix spelling mistake in lazyfree.c
commit 1da37aa
Merge: 2d4ba28 c90b2a4
Author: hwware <wen.hui.ware@gmail.com>
Date: Thu Mar 5 22:41:31 2020 -0500
Merge remote-tracking branch 'upstream/unstable' into expiretypofix
commit 2d4ba28
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Mar 2 00:09:40 2020 -0500
fix typo in expire.c
commit 1a746f7
Author: SennoYuki <minakami1yuki@gmail.com>
Date: Thu Feb 27 16:54:32 2020 +0800
fix typo
commit 8599b1a
Author: dongheejeong <donghee950403@gmail.com>
Date: Sun Feb 16 20:31:43 2020 +0000
Fix typo in server.c
commit f38d4e8
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun Feb 2 22:58:38 2020 -0500
fix typo in evict.c
commit fe143fc
Author: Leo Murillo <leonardo.murillo@gmail.com>
Date: Sun Feb 2 01:57:22 2020 -0600
Fix a few typos in redis.conf
commit 1ab4d21
Author: viraja1 <anchan.viraj@gmail.com>
Date: Fri Dec 27 17:15:58 2019 +0530
Fix typo in Latency API docstring
commit ca1f70e
Author: gosth <danxuedexing@qq.com>
Date: Wed Dec 18 15:18:02 2019 +0800
fix typo in sort.c
commit a57c06b
Author: ZYunH <zyunhjob@163.com>
Date: Mon Dec 16 22:28:46 2019 +0800
fix-zset-typo
commit b8c92b5
Author: git-hulk <hulk.website@gmail.com>
Date: Mon Dec 16 15:51:42 2019 +0800
FIX: typo in cluster.c, onformation->information
commit 9dd981c
Author: wujm2007 <jim.wujm@gmail.com>
Date: Mon Dec 16 09:37:52 2019 +0800
Fix typo
commit e132d7a
Author: Sebastien Williams-Wynn <s.williamswynn.mail@gmail.com>
Date: Fri Nov 15 00:14:07 2019 +0000
Minor typo change
commit 47f44d5
Author: happynote3966 <01ssrmikururudevice01@gmail.com>
Date: Mon Nov 11 22:08:48 2019 +0900
fix comment typo in redis-cli.c
commit b8bdb0d
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 18:00:17 2019 +0800
Fix a spelling mistake of comments in defragDictBucketCallback
commit 0def46a
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 13:09:27 2019 +0800
fix some spelling mistakes of comments in defrag.c
commit f3596fd
Author: Phil Rajchgot <tophil@outlook.com>
Date: Sun Oct 13 02:02:32 2019 -0400
Typo and grammar fixes
Redis and its documentation are great -- just wanted to submit a few corrections in the spirit of Hacktoberfest. Thanks for all your work on this project. I use it all the time and it works beautifully.
commit 2b928cd
Author: KangZhiDong <worldkzd@gmail.com>
Date: Sun Sep 1 07:03:11 2019 +0800
fix typos
commit 33aea14
Author: Axlgrep <axlgrep@gmail.com>
Date: Tue Aug 27 11:02:18 2019 +0800
Fixed eviction spelling issues
commit e282a80
Author: Simen Flatby <simen@oms.no>
Date: Tue Aug 20 15:25:51 2019 +0200
Update comments to reflect prop name
In the comments the prop is referenced as replica-validity-factor,
but it is really named cluster-replica-validity-factor.
commit 74d1f9a
Author: Jim Green <jimgreen2013@qq.com>
Date: Tue Aug 20 20:00:31 2019 +0800
fix comment error, the code is ok
commit eea1407
Author: Liao Tonglang <liaotonglang@gmail.com>
Date: Fri May 31 10:16:18 2019 +0800
typo fix
fix cna't to can't
commit 0da553c
Author: KAWACHI Takashi <tkawachi@gmail.com>
Date: Wed Jul 17 00:38:16 2019 +0900
Fix typo
commit 7fc8fb6
Author: Michael Prokop <mika@grml.org>
Date: Tue May 28 17:58:42 2019 +0200
Typo fixes
s/familar/familiar/
s/compatiblity/compatibility/
s/ ot / to /
s/itsef/itself/
commit 5f46c9d
Author: zhumoing <34539422+zhumoing@users.noreply.github.com>
Date: Tue May 21 21:16:50 2019 +0800
typo-fixes
typo-fixes
commit 321dfe1
Author: wxisme <850885154@qq.com>
Date: Sat Mar 16 15:10:55 2019 +0800
typo fix
commit b4fb131
Merge: 267e0e6 4842305
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Fri Feb 8 22:55:45 2019 +0200
Merge branch 'unstable' of antirez/redis into unstable
commit 267e0e6
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Wed Jan 30 21:26:04 2019 +0200
Minor typo fix
commit 30544e7
Author: inshal96 <39904558+inshal96@users.noreply.github.com>
Date: Fri Jan 4 16:54:50 2019 +0500
remove an extra 'a' in the comments
commit 337969d
Author: BrotherGao <yangdongheng11@gmail.com>
Date: Sat Dec 29 12:37:29 2018 +0800
fix typo in redis.conf
commit 9f4b121
Merge: 423a030 19d0ece
Author: BrotherGao <yangdongheng@xiaomi.com>
Date: Sat Dec 29 11:41:12 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 423a030
Merge: 42b02b7 0423081
Author: 杨东衡 <yangdongheng@xiaomi.com>
Date: Tue Dec 4 23:56:11 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 42b02b7
Merge: 8c7dcff efa96f0
Author: Dongheng Yang <yangdongheng11@gmail.com>
Date: Sun Oct 28 15:54:23 2018 +0800
Merge pull request #1 from antirez/unstable
update local data
commit 714b589
Author: Christian <crifei93@gmail.com>
Date: Fri Dec 28 01:17:26 2018 +0100
fix typo "resulution"
commit e23259d
Author: garenchan <1412950785@qq.com>
Date: Wed Dec 26 09:58:35 2018 +0800
fix typo: segfauls -> segfault
commit a9359f8
Author: xjp <jianping_xie@aliyun.com>
Date: Tue Dec 18 17:31:44 2018 +0800
Fixed REDISMODULE_H spell bug
commit a12c3e4
Author: jdiaz <jrd.palacios@gmail.com>
Date: Sat Dec 15 23:39:52 2018 -0600
Fixes hyperloglog hash function comment block description
commit 770eb11
Author: 林上耀 <1210tom@163.com>
Date: Sun Nov 25 17:16:10 2018 +0800
fix typo
commit fd97fbb
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Fri Nov 23 17:14:01 2018 +0100
Correct "unsupported" typo.
commit a85522d
Author: Jungnam Lee <jungnam.lee@oracle.com>
Date: Thu Nov 8 23:01:29 2018 +0900
fix typo in test comments
commit ade8007
Author: Arun Kumar <palerdot@users.noreply.github.com>
Date: Tue Oct 23 16:56:35 2018 +0530
Fixed grammatical typo
Fixed typo for word 'dictionary'
commit 869ee39
Author: Hamid Alaei <hamid.a85@gmail.com>
Date: Sun Aug 12 16:40:02 2018 +0430
fix documentations: (ThreadSafeContextStart/Stop -> ThreadSafeContextLock/Unlock), minor typo
commit f89d158
Author: Mayank Jain <mayankjain255@gmail.com>
Date: Tue Jul 31 23:01:21 2018 +0530
Updated README.md with some spelling corrections.
Made correction in spelling of some misspelled words.
commit 892198e
Author: dsomeshwar <someshwar.dhayalan@gmail.com>
Date: Sat Jul 21 23:23:04 2018 +0530
typo fix
commit 8a4d780
Author: Itamar Haber <itamar@redislabs.com>
Date: Mon Apr 30 02:06:52 2018 +0300
Fixes some typos
commit e3acef6
Author: Noah Rosamilia <ivoahivoah@gmail.com>
Date: Sat Mar 3 23:41:21 2018 -0500
Fix typo in /deps/README.md
commit 04442fb
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:32:42 2018 +0800
Fix typo in readSyncBulkPayload() comment.
commit 9f36880
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:20:37 2018 +0800
replication.c comment: run_id -> replid.
commit f866b4a
Author: Francesco 'makevoid' Canessa <makevoid@gmail.com>
Date: Thu Feb 22 22:01:56 2018 +0000
fix comment typo in server.c
commit 0ebc69b
Author: 줍 <jubee0124@gmail.com>
Date: Mon Feb 12 16:38:48 2018 +0900
Fix typo in redis.conf
Fix `five behaviors` to `eight behaviors` in [this sentence ](antirez/redis@unstable/redis.conf#L564)
commit b50a620
Author: martinbroadhurst <martinbroadhurst@users.noreply.github.com>
Date: Thu Dec 28 12:07:30 2017 +0000
Fix typo in valgrind.sup
commit 7d8f349
Author: Peter Boughton <peter@sorcerersisle.com>
Date: Mon Nov 27 19:52:19 2017 +0000
Update CONTRIBUTING; refer doc updates to redis-doc repo.
commit 02dec7e
Author: Klauswk <klauswk1@hotmail.com>
Date: Tue Oct 24 16:18:38 2017 -0200
Fix typo in comment
commit e1efbc8
Author: chenshi <baiwfg2@gmail.com>
Date: Tue Oct 3 18:26:30 2017 +0800
Correct two spelling errors of comments
commit 93327d8
Author: spacewander <spacewanderlzx@gmail.com>
Date: Wed Sep 13 16:47:24 2017 +0800
Update the comment for OBJ_ENCODING_EMBSTR_SIZE_LIMIT's value
The value of OBJ_ENCODING_EMBSTR_SIZE_LIMIT is 44 now instead of 39.
commit 63d361f
Author: spacewander <spacewanderlzx@gmail.com>
Date: Tue Sep 12 15:06:42 2017 +0800
Fix <prevlen> related doc in ziplist.c
According to the definition of ZIP_BIG_PREVLEN and other related code,
the guard of single byte <prevlen> should be 254 instead of 255.
commit ebe228d
Author: hanael80 <hanael80@gmail.com>
Date: Tue Aug 15 09:09:40 2017 +0900
Fix typo
commit 6b696e6
Author: Matt Robenolt <matt@ydekproductions.com>
Date: Mon Aug 14 14:50:47 2017 -0700
Fix typo in LATENCY DOCTOR output
commit a2ec6ae
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 15 14:15:16 2017 +0800
Fix a typo: form => from
commit 3ab7699
Author: caosiyang <caosiyang@qiyi.com>
Date: Thu Aug 10 18:40:33 2017 +0800
Fix a typo: replicationFeedSlavesFromMaster() => replicationFeedSlavesFromMasterStream()
commit 72d43ef
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 8 15:57:25 2017 +0800
fix a typo: servewr => server
commit 707c958
Author: Bo Cai <charpty@gmail.com>
Date: Wed Jul 26 21:49:42 2017 +0800
redis-cli.c typo: conut -> count.
Signed-off-by: Bo Cai <charpty@gmail.com>
commit b9385b2
Author: JackDrogon <jack.xsuperman@gmail.com>
Date: Fri Jun 30 14:22:31 2017 +0800
Fix some spell problems
commit 20d9230
Author: akosel <aaronjkosel@gmail.com>
Date: Sun Jun 4 19:35:13 2017 -0500
Fix typo
commit b167bfc
Author: Krzysiek Witkowicz <krzysiekwitkowicz@gmail.com>
Date: Mon May 22 21:32:27 2017 +0100
Fix #4008 small typo in comment
commit 2b78ac8
Author: Jake Clarkson <jacobwclarkson@gmail.com>
Date: Wed Apr 26 15:49:50 2017 +0100
Correct typo in tests/unit/hyperloglog.tcl
commit b0f1cdb
Author: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Wed Apr 19 14:25:18 2017 -0700
Fix typo
commit a90b0f9
Author: charsyam <charsyam@naver.com>
Date: Thu Mar 16 18:19:53 2017 +0900
fix typos
fix typos
fix typos
commit 8430a79
Author: Richard Hart <richardhart92@gmail.com>
Date: Mon Mar 13 22:17:41 2017 -0400
Fixed log message typo in listenToPort.
commit 481a1c2
Author: Vinod Kumar <kumar003vinod@gmail.com>
Date: Sun Jan 15 23:04:51 2017 +0530
src/db.c: Correct "save" -> "safe" typo
commit 586b4d3
Author: wangshaonan <wshn13@gmail.com>
Date: Wed Dec 21 20:28:27 2016 +0800
Fix typo they->the in helloworld.c
commit c1c4b5e
Author: Jenner <hypxm@qq.com>
Date: Mon Dec 19 16:39:46 2016 +0800
typo error
commit 1ee1a3f
Author: tielei <43289893@qq.com>
Date: Mon Jul 18 13:52:25 2016 +0800
fix some comments
commit 11a41fb
Author: Otto Kekäläinen <otto@seravo.fi>
Date: Sun Jul 3 10:23:55 2016 +0100
Fix spelling in documentation and comments
commit 5fb5d82
Author: francischan <f1ancis621@gmail.com>
Date: Tue Jun 28 00:19:33 2016 +0800
Fix outdated comments about redis.c file.
It should now refer to server.c file.
commit 6b254bc
Author: lmatt-bit <lmatt123n@gmail.com>
Date: Thu Apr 21 21:45:58 2016 +0800
Refine the comment of dictRehashMilliseconds func
SLAVECONF->REPLCONF in comment - by andyli029
commit ee9869f
Author: clark.kang <charsyam@naver.com>
Date: Tue Mar 22 11:09:51 2016 +0900
fix typos
commit f7b3b11
Author: Harisankar H <harisankarh@gmail.com>
Date: Wed Mar 9 11:49:42 2016 +0530
Typo correction: "faield" --> "failed"
Typo correction: "faield" --> "failed"
commit 3fd40fc
Author: Itamar Haber <itamar@redislabs.com>
Date: Thu Feb 25 10:31:51 2016 +0200
Fixes a typo in comments
commit 621c160
Author: Prayag Verma <prayag.verma@gmail.com>
Date: Mon Feb 1 12:36:20 2016 +0530
Fix typo in Readme.md
Spelling mistakes -
`eviciton` > `eviction`
`familar` > `familiar`
commit d7d07d6
Author: WonCheol Lee <toctoc21c@gmail.com>
Date: Wed Dec 30 15:11:34 2015 +0900
Typo fixed
commit a4dade7
Author: Felix Bünemann <buenemann@louis.info>
Date: Mon Dec 28 11:02:55 2015 +0100
[ci skip] Improve supervised upstart config docs
This mentions that "expect stop" is required for supervised upstart
to work correctly. See http://upstart.ubuntu.com/cookbook/#expect-stop
for an explanation.
commit d9caba9
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:30:03 2015 +1100
README: Remove trailing whitespace
commit 72d42e5
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:32 2015 +1100
README: Fix typo. th => the
commit dd6e957
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:20 2015 +1100
README: Fix typo. familar => familiar
commit 3a12b23
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:28:54 2015 +1100
README: Fix typo. eviciton => eviction
commit 2d1d03b
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:21:45 2015 +1100
README: Fix typo. sever => server
commit 3973b06
Author: Itamar Haber <itamar@garantiadata.com>
Date: Sat Dec 19 17:01:20 2015 +0200
Typo fix
commit 4f2e460
Author: Steve Gao <fu@2token.com>
Date: Fri Dec 4 10:22:05 2015 +0800
Update README - fix typos
commit b21667c
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:48:37 2015 +0800
delete redundancy color judge in sdscatcolor
commit 88894c7
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:14:42 2015 +0800
the example output shoule be HelloWorld
commit 2763470
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 17:41:39 2015 +0800
modify error word keyevente
Signed-off-by: binyan <binbin.yan@nokia.com>
commit 0847b3d
Author: Bruno Martins <bscmartins@gmail.com>
Date: Wed Nov 4 11:37:01 2015 +0000
typo
commit bbb9e9e
Author: dawedawe <dawedawe@gmx.de>
Date: Fri Mar 27 00:46:41 2015 +0100
typo: zimap -> zipmap
commit 5ed297e
Author: Axel Advento <badwolf.bloodseeker.rev@gmail.com>
Date: Tue Mar 3 15:58:29 2015 +0800
Fix 'salve' typos to 'slave'
commit edec9d6
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Wed Jun 12 14:12:47 2019 +0200
Update README.md
Co-Authored-By: Qix <Qix-@users.noreply.github.com>
commit 692a7af
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Tue May 28 14:32:04 2019 +0200
grammar
commit d962b0a
Author: Nick Frost <nickfrostatx@gmail.com>
Date: Wed Jul 20 15:17:12 2016 -0700
Minor grammar fix
commit 24fff01aaccaf5956973ada8c50ceb1462e211c6 (typos)
Author: Chad Miller <chadm@squareup.com>
Date: Tue Sep 8 13:46:11 2020 -0400
Fix faulty comment about operation of unlink()
commit 3cd5c1f3326c52aa552ada7ec797c6bb16452355
Author: Kevin <kevin.xgr@gmail.com>
Date: Wed Nov 20 00:13:50 2019 +0800
Fix typo in server.c.
From a83af59 Mon Sep 17 00:00:00 2001
From: wuwo <wuwo@wacai.com>
Date: Fri, 17 Mar 2017 20:37:45 +0800
Subject: [PATCH] falure to failure
From c961896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B7=A6=E6=87=B6?= <veficos@gmail.com>
Date: Sat, 27 May 2017 15:33:04 +0800
Subject: [PATCH] fix typo
From e600ef2 Mon Sep 17 00:00:00 2001
From: "rui.zou" <rui.zou@yunify.com>
Date: Sat, 30 Sep 2017 12:38:15 +0800
Subject: [PATCH] fix a typo
From c7d07fa Mon Sep 17 00:00:00 2001
From: Alexandre Perrin <alex@kaworu.ch>
Date: Thu, 16 Aug 2018 10:35:31 +0200
Subject: [PATCH] deps README.md typo
From b25cb67 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 10:55:37 +0300
Subject: [PATCH 1/2] fix typos in header
From ad28ca6 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 11:02:36 +0300
Subject: [PATCH 2/2] fix typos
commit 34924cdedd8552466fc22c1168d49236cb7ee915
Author: Adrian Lynch <adi_ady_ade@hotmail.com>
Date: Sat Apr 4 21:59:15 2015 +0100
Typos fixed
commit fd2a1e7
Author: Jan <jsteemann@users.noreply.github.com>
Date: Sat Oct 27 19:13:01 2018 +0200
Fix typos
Fix typos
commit e14e47c1a234b53b0e103c5f6a1c61481cbcbb02
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:30:07 2019 -0500
Fix multiple misspellings of "following"
commit 79b948ce2dac6b453fe80995abbcaac04c213d5a
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:24:28 2019 -0500
Fix misspelling of create-cluster
commit 1fffde52666dc99ab35efbd31071a4c008cb5a71
Author: Andy Lester <andy@petdance.com>
Date: Wed Jul 31 17:57:56 2019 -0500
Fix typos
commit 204c9ba9651e9e05fd73936b452b9a30be456cfe
Author: Xiaobo Zhu <xiaobo.zhu@shopee.com>
Date: Tue Aug 13 22:19:25 2019 +0800
fix typos
Squashed commit of the following:
commit 1d9aaf8
Author: danmedani <danmedani@gmail.com>
Date: Sun Aug 2 11:40:26 2015 -0700
README typo fix.
Squashed commit of the following:
commit 32bfa7c
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Jul 6 21:15:08 2015 +0200
Fixed grammer
Squashed commit of the following:
commit b24f69c
Author: Sisir Koppaka <sisir.koppaka@gmail.com>
Date: Mon Mar 2 22:38:45 2015 -0500
utils/hashtable/rehashing.c: Fix typos
Squashed commit of the following:
commit 4e04082
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Mar 23 08:22:21 2015 +0000
Small config file documentation improvements
Squashed commit of the following:
commit acb8773
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:52:48 2015 -0700
Typo and grammar fixes in readme
commit 2eb75b6
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:36:18 2015 -0700
fixed redis.conf comment
Squashed commit of the following:
commit a8249a2
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri Dec 11 11:39:52 2015 +0530
Revise correction of typos.
Squashed commit of the following:
commit 3c02028
Author: zhaojun11 <zhaojun11@jd.com>
Date: Wed Jan 17 19:05:28 2018 +0800
Fix typos include two code typos in cluster.c and latency.c
Squashed commit of the following:
commit 9dba47c
Author: q191201771 <191201771@qq.com>
Date: Sat Jan 4 11:31:04 2020 +0800
fix function listCreate comment in adlist.c
Update src/server.c
commit 2c7c2cb536e78dd211b1ac6f7bda00f0f54faaeb
Author: charpty <charpty@gmail.com>
Date: Tue May 1 23:16:59 2018 +0800
server.c typo: modules system dictionary type comment
Signed-off-by: charpty <charpty@gmail.com>
commit a8395323fb63cb59cb3591cb0f0c8edb7c29a680
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun May 6 00:25:18 2018 +0300
Updates test_helper.tcl's help with undocumented options
Specifically:
* Host
* Port
* Client
commit bde6f9ced15755cd6407b4af7d601b030f36d60b
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 15:19:19 2018 +0800
fix comments in deps files
commit 3172474ba991532ab799ee1873439f3402412331
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 14:33:49 2018 +0800
fix some comments
commit 01b6f2b6858b5cf2ce4ad5092d2c746e755f53f0
Author: Thor Juhasz <thor@juhasz.pro>
Date: Sun Nov 18 14:37:41 2018 +0100
Minor fixes to comments
Found some parts a little unclear on a first read, which prompted me to have a better look at the file and fix some minor things I noticed.
Fixing minor typos and grammar. There are no changes to configuration options.
These changes are only meant to help the user better understand the explanations to the various configuration options
(cherry picked from commit 285ef446b05e09013556e7a490677494a9b4bb3e)
2020-09-10 13:43:38 +03:00
/* If it is our master that's being disconnected we should make sure
2019-02-15 14:11:05 -05:00
* to cache the state to try a partial resynchronization later .
*
* Note that before doing this we make sure that the client is not in
* some unexpected state , by checking its flags . */
2019-04-02 16:47:05 -04:00
if ( FActiveMaster ( c ) ) {
2019-02-15 14:11:05 -05:00
serverLog ( LL_WARNING , " Connection with master lost. " ) ;
2020-05-15 10:19:13 +02:00
if ( ! ( c - > flags & ( CLIENT_PROTOCOL_ERROR | CLIENT_BLOCKED ) ) ) {
2020-05-16 17:15:35 +02:00
c - > flags & = ~ ( CLIENT_CLOSE_ASAP | CLIENT_CLOSE_AFTER_REPLY ) ;
2019-04-02 16:47:05 -04:00
replicationCacheMaster ( MasterInfoFromClient ( c ) , c ) ;
2019-08-26 20:18:52 -04:00
return false ;
2019-02-15 14:11:05 -05:00
}
}
2019-10-13 12:29:20 -04:00
/* Log link disconnection with replica */
2020-02-06 14:12:08 +05:30
if ( getClientType ( c ) = = CLIENT_TYPE_SLAVE ) {
2019-02-15 14:11:05 -05:00
serverLog ( LL_WARNING , " Connection with replica %s lost. " ,
replicationGetSlaveName ( c ) ) ;
}
/* Free the query buffer */
sdsfree ( c - > querybuf ) ;
sdsfree ( c - > pending_querybuf ) ;
c - > querybuf = NULL ;
/* Deallocate structures used to block on blocking ops. */
if ( c - > flags & CLIENT_BLOCKED ) unblockClient ( c ) ;
dictRelease ( c - > bpop . keys ) ;
/* UNWATCH all the keys */
unwatchAllKeys ( c ) ;
listRelease ( c - > watched_keys ) ;
/* Unsubscribe from all the pubsub channels */
pubsubUnsubscribeAllChannels ( c , 0 ) ;
pubsubUnsubscribeAllPatterns ( c , 0 ) ;
dictRelease ( c - > pubsub_channels ) ;
listRelease ( c - > pubsub_patterns ) ;
/* Free data structures. */
listRelease ( c - > reply ) ;
freeClientArgv ( c ) ;
2020-11-10 13:50:03 -08:00
freeClientOriginalArgv ( c ) ;
2019-02-15 14:11:05 -05:00
/* Unlink the client: this will close the socket, remove the I/O
* handlers , and remove references of the client from different
* places where active clients may be referenced . */
unlinkClient ( c ) ;
2019-10-13 12:29:20 -04:00
/* Master/replica cleanup Case 1:
* we lost the connection with a replica . */
2019-02-15 14:11:05 -05:00
if ( c - > flags & CLIENT_SLAVE ) {
2020-09-22 14:47:58 +08:00
/* If there is no any other slave waiting dumping RDB finished, the
* current child process need not continue to dump RDB , then we kill it .
* So child process won ' t use more memory , and we also can fork a new
* child process asap to dump rdb for next full synchronization or bgsave .
* But we also need to check if users enable ' save ' RDB , if enable , we
* should not remove directly since that means RDB is important for users
* to keep data safe and we may delay configured ' save ' for full sync . */
2021-05-19 02:59:48 +00:00
if ( g_pserver - > saveparamslen = = 0 & &
2020-09-22 14:47:58 +08:00
c - > replstate = = SLAVE_STATE_WAIT_BGSAVE_END & &
2021-05-19 02:59:48 +00:00
g_pserver - > child_type = = CHILD_TYPE_RDB & &
g_pserver - > rdb_child_type = = RDB_CHILD_TYPE_DISK & &
2020-09-22 14:47:58 +08:00
anyOtherSlaveWaitRdb ( c ) = = 0 )
{
killRDBChild ( ) ;
}
2019-02-15 14:11:05 -05:00
if ( c - > replstate = = SLAVE_STATE_SEND_BULK ) {
if ( c - > repldbfd ! = - 1 ) close ( c - > repldbfd ) ;
if ( c - > replpreamble ) sdsfree ( c - > replpreamble ) ;
}
2019-04-21 14:01:10 -04:00
list * l = ( c - > flags & CLIENT_MONITOR ) ? g_pserver - > monitors : g_pserver - > slaves ;
2019-02-15 14:11:05 -05:00
ln = listSearchKey ( l , c ) ;
serverAssert ( ln ! = NULL ) ;
listDelNode ( l , ln ) ;
/* We need to remember the time when we started to have zero
* attached slaves , as after some time we ' ll free the replication
* backlog . */
2020-04-14 19:22:44 -04:00
if ( getClientType ( c ) = = CLIENT_TYPE_SLAVE & & listLength ( g_pserver - > slaves ) = = 0 )
2019-04-21 14:01:10 -04:00
g_pserver - > repl_no_slaves_since = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
refreshGoodSlavesCount ( ) ;
2019-10-29 17:59:09 +02:00
/* Fire the replica change modules event. */
if ( c - > replstate = = SLAVE_STATE_ONLINE )
moduleFireServerEvent ( REDISMODULE_EVENT_REPLICA_CHANGE ,
REDISMODULE_SUBEVENT_REPLICA_CHANGE_OFFLINE ,
NULL ) ;
2019-02-15 14:11:05 -05:00
}
2019-10-13 12:29:20 -04:00
/* Master/replica cleanup Case 2:
2019-02-15 14:11:05 -05:00
* we lost the connection with the master . */
2019-04-02 16:47:05 -04:00
if ( c - > flags & CLIENT_MASTER ) replicationHandleMasterDisconnection ( MasterInfoFromClient ( c ) ) ;
2019-02-15 14:11:05 -05:00
2020-05-16 17:15:35 +02:00
/* Remove the contribution that this client gave to our
2020-04-07 12:07:09 +02:00
* incrementally computed memory usage . */
2020-05-21 18:48:49 -04:00
g_pserver - > stat_clients_type_memory [ c - > client_cron_last_memory_type ] - =
2020-04-07 12:07:09 +02:00
c - > client_cron_last_memory_usage ;
2019-02-15 14:11:05 -05:00
/* Release other dynamically allocated client structure fields,
* and finally release the client structure itself . */
2020-10-15 23:10:17 +00:00
zfree ( c - > replyAsync ) ;
2019-02-15 14:11:05 -05:00
if ( c - > name ) decrRefCount ( c - > name ) ;
zfree ( c - > argv ) ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
2019-02-15 14:11:05 -05:00
freeClientMultiState ( c ) ;
sdsfree ( c - > peerid ) ;
2020-10-28 21:13:44 +02:00
sdsfree ( c - > sockname ) ;
2021-02-21 11:22:36 +02:00
sdsfree ( c - > slave_addr ) ;
2019-02-22 21:00:14 -05:00
ulock . unlock ( ) ;
2019-02-20 23:30:21 -05:00
fastlock_free ( & c - > lock ) ;
2019-02-15 14:11:05 -05:00
zfree ( c ) ;
2019-08-26 20:18:52 -04:00
return true ;
2019-02-15 14:11:05 -05:00
}
2020-05-10 23:14:15 -04:00
fastlock lockasyncfree { " async free lock " } ;
2019-02-15 14:11:05 -05:00
/* Schedule a client to free it at a safe time in the serverCron() function.
* This function is useful when we need to terminate a client but we are in
* a context where calling freeClient ( ) is not possible , because the client
* should be valid for the continuation of the flow of the program . */
void freeClientAsync ( client * c ) {
2020-05-22 15:56:35 -04:00
/* We need to handle concurrent access to the g_pserver->clients_to_close list
2017-10-24 08:35:05 +02:00
* only in the freeClientAsync ( ) function , since it ' s the only function that
* may access the list while Redis uses I / O threads . All the other accesses
* are in the context of the main thread while the other threads are
* idle . */
2019-08-26 20:18:52 -04:00
if ( c - > flags & CLIENT_CLOSE_ASAP | | c - > flags & CLIENT_LUA ) return ; // check without the lock first
2019-02-22 21:00:14 -05:00
std : : lock_guard < decltype ( c - > lock ) > clientlock ( c - > lock ) ;
2019-07-12 20:46:50 -04:00
AeLocker lock ;
lock . arm ( c ) ;
2019-08-26 20:18:52 -04:00
if ( c - > flags & CLIENT_CLOSE_ASAP | | c - > flags & CLIENT_LUA ) return ; // race condition after we acquire the lock
2019-02-20 01:20:26 -05:00
c - > flags | = CLIENT_CLOSE_ASAP ;
2020-05-10 23:14:15 -04:00
std : : unique_lock < fastlock > ul ( lockasyncfree ) ;
2019-04-21 14:01:10 -04:00
listAddNodeTail ( g_pserver - > clients_to_close , c ) ;
2019-02-15 14:11:05 -05:00
}
2020-05-22 16:45:18 -04:00
int freeClientsInAsyncFreeQueue ( int iel ) {
2019-08-26 20:18:52 -04:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-18 22:25:35 -05:00
listIter li ;
listNode * ln ;
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > clients_to_close , & li ) ;
2019-02-18 22:25:35 -05:00
2019-08-26 20:18:52 -04:00
// Store the clients in a temp vector since freeClient will modify this list
std : : vector < client * > vecclientsFree ;
2020-05-10 23:14:15 -04:00
std : : unique_lock < fastlock > ul ( lockasyncfree ) ;
2019-08-26 20:18:52 -04:00
while ( ( ln = listNext ( & li ) ) )
{
2019-02-15 14:11:05 -05:00
client * c = ( client * ) listNodeValue ( ln ) ;
2020-12-11 03:59:39 +00:00
if ( c - > iel = = iel & & ! ( c - > flags & CLIENT_PROTECTED ) & & ! c - > casyncOpsPending )
2019-08-26 20:18:52 -04:00
{
vecclientsFree . push_back ( c ) ;
listDelNode ( g_pserver - > clients_to_close , ln ) ;
}
}
2020-05-10 23:14:15 -04:00
ul . unlock ( ) ;
2019-02-15 14:11:05 -05:00
2019-08-26 20:18:52 -04:00
for ( client * c : vecclientsFree )
{
2019-02-15 14:11:05 -05:00
c - > flags & = ~ CLIENT_CLOSE_ASAP ;
freeClient ( c ) ;
}
2020-05-22 16:45:18 -04:00
return ( int ) vecclientsFree . size ( ) ;
2019-02-15 14:11:05 -05:00
}
/* Return a client by ID, or NULL if the client ID is not in the set
* of registered clients . Note that " fake clients " , created with - 1 as FD ,
* are not registered clients . */
client * lookupClientByID ( uint64_t id ) {
id = htonu64 ( id ) ;
2019-04-21 14:01:10 -04:00
client * c = ( client * ) raxFind ( g_pserver - > clients_index , ( unsigned char * ) & id , sizeof ( id ) ) ;
2019-02-15 14:11:05 -05:00
return ( c = = raxNotFound ) ? NULL : c ;
}
/* Write data in output buffers to client. Return C_OK if the client
2017-10-24 08:35:05 +02:00
* is still valid after the call , C_ERR if it was freed because of some
2019-09-12 10:56:54 +03:00
* error . If handler_installed is set , it will attempt to clear the
* write event .
2017-10-24 08:35:05 +02:00
*
* This function is called by threads , but always with handler_installed
* set to 0. So when handler_installed is set to 0 the function must be
* thread safe . */
2019-09-12 10:56:54 +03:00
int writeToClient ( client * c , int handler_installed ) {
2020-07-29 01:46:44 -04:00
/* Update total number of writes on server */
2020-09-30 19:47:55 +00:00
g_pserver - > stat_total_writes_processed . fetch_add ( 1 , std : : memory_order_relaxed ) ;
2020-07-29 01:46:44 -04:00
2019-02-15 14:11:05 -05:00
ssize_t nwritten = 0 , totwritten = 0 ;
clientReplyBlock * o ;
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2019-02-22 01:24:16 -05:00
std : : unique_lock < decltype ( c - > lock ) > lock ( c - > lock ) ;
2019-02-18 22:25:35 -05:00
2019-02-22 01:24:16 -05:00
while ( clientHasPendingReplies ( c ) ) {
if ( c - > bufpos > 0 ) {
2019-09-12 10:56:54 +03:00
nwritten = connWrite ( c - > conn , c - > buf + c - > sentlen , c - > bufpos - c - > sentlen ) ;
2019-02-15 14:11:05 -05:00
if ( nwritten < = 0 ) break ;
c - > sentlen + = nwritten ;
totwritten + = nwritten ;
/* If the buffer was sent, set bufpos to zero to continue with
* the remainder of the reply . */
if ( ( int ) c - > sentlen = = c - > bufpos ) {
c - > bufpos = 0 ;
c - > sentlen = 0 ;
}
} else {
o = ( clientReplyBlock * ) listNodeValue ( listFirst ( c - > reply ) ) ;
2019-02-18 22:25:35 -05:00
if ( o - > used = = 0 ) {
2019-02-15 14:11:05 -05:00
c - > reply_bytes - = o - > size ;
listDelNode ( c - > reply , listFirst ( c - > reply ) ) ;
continue ;
}
2020-01-27 02:55:48 -05:00
nwritten = connWrite ( c - > conn , o - > buf ( ) + c - > sentlen , o - > used - c - > sentlen ) ;
2013-05-24 18:58:57 +02:00
if ( nwritten < = 0 ) break ;
2019-02-15 14:11:05 -05:00
c - > sentlen + = nwritten ;
totwritten + = nwritten ;
2019-02-18 22:25:35 -05:00
2019-02-15 14:11:05 -05:00
/* If we fully sent the object on head go to the next one */
2019-02-18 22:25:35 -05:00
if ( c - > sentlen = = o - > used ) {
2019-02-15 14:11:05 -05:00
c - > reply_bytes - = o - > size ;
listDelNode ( c - > reply , listFirst ( c - > reply ) ) ;
c - > sentlen = 0 ;
/* If there are no longer objects in the list, we expect
2019-02-18 22:25:35 -05:00
* the count of reply bytes to be exactly zero . */
2019-02-15 14:11:05 -05:00
if ( listLength ( c - > reply ) = = 0 )
serverAssert ( c - > reply_bytes = = 0 ) ;
}
}
/* Note that we avoid to send more than NET_MAX_WRITES_PER_EVENT
* bytes , in a single threaded server it ' s a good idea to serve
* other clients as well , even if a very large request comes from
* super fast link that is always able to accept data ( in real world
* scenario think about ' KEYS * ' against the loopback interface ) .
*
* However if we are over the maxmemory limit we ignore that and
* just deliver as much data as it is possible to deliver .
*
* Moreover , we also send as much as possible if the client is
2020-04-14 19:22:44 -04:00
* a replica or a monitor ( otherwise , on high - speed traffic , the
2020-02-06 14:09:45 +05:30
* replication / output buffer will grow indefinitely ) */
2019-02-15 14:11:05 -05:00
if ( totwritten > NET_MAX_WRITES_PER_EVENT & &
2019-04-21 14:01:10 -04:00
( g_pserver - > maxmemory = = 0 | |
zmalloc_used_memory ( ) < g_pserver - > maxmemory ) & &
2019-02-15 14:11:05 -05:00
! ( c - > flags & CLIENT_SLAVE ) ) break ;
}
2019-05-11 02:20:34 -04:00
g_pserver - > stat_net_output_bytes + = totwritten ;
2019-02-15 14:11:05 -05:00
if ( nwritten = = - 1 ) {
2021-04-15 13:44:08 +08:00
if ( connGetState ( c - > conn ) ! = CONN_STATE_CONNECTED ) {
2019-02-15 14:11:05 -05:00
serverLog ( LL_VERBOSE ,
2019-09-12 10:56:54 +03:00
" Error writing to client: %s " , connGetLastError ( c - > conn ) ) ;
2019-07-12 23:51:45 -04:00
freeClientAsync ( c ) ;
2019-02-22 01:24:16 -05:00
2019-02-15 14:11:05 -05:00
return C_ERR ;
}
}
if ( totwritten > 0 ) {
/* For clients representing masters we don't count sending data
* as an interaction , since we always send REPLCONF ACK commands
* that take some time to just fill the socket output buffer .
* We just rely on data / pings received for timeout detection . */
2019-04-21 14:01:10 -04:00
if ( ! ( c - > flags & CLIENT_MASTER ) ) c - > lastinteraction = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
}
2019-02-22 01:24:16 -05:00
if ( ! clientHasPendingReplies ( c ) ) {
2019-02-15 14:11:05 -05:00
c - > sentlen = 0 ;
2019-09-12 10:56:54 +03:00
if ( handler_installed ) connSetWriteHandler ( c - > conn , NULL ) ;
2019-02-15 14:11:05 -05:00
/* Close connection after entire reply has been sent. */
if ( c - > flags & CLIENT_CLOSE_AFTER_REPLY ) {
2019-07-12 23:51:45 -04:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return C_ERR ;
}
}
return C_OK ;
}
/* Write event handler. Just send data to the client. */
2019-09-12 10:56:54 +03:00
void sendReplyToClient ( connection * conn ) {
2020-01-27 02:55:48 -05:00
client * c = ( client * ) connGetPrivateData ( conn ) ;
if ( writeToClient ( c , 1 ) = = C_ERR )
2019-07-12 23:51:45 -04:00
{
AeLocker ae ;
c - > lock . lock ( ) ;
ae . arm ( c ) ;
if ( c - > flags & CLIENT_CLOSE_ASAP )
2020-03-19 14:34:23 -04:00
{
if ( ! freeClient ( c ) )
2020-03-19 15:28:39 -04:00
c - > lock . unlock ( ) ;
2020-03-19 14:34:23 -04:00
}
2019-07-12 23:51:45 -04:00
}
2019-02-20 01:20:26 -05:00
}
2019-02-18 22:25:35 -05:00
2019-02-20 01:20:26 -05:00
void ProcessPendingAsyncWrites ( )
{
2019-03-07 19:13:01 -05:00
if ( serverTL = = nullptr )
return ; // module fake call
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-18 22:25:35 -05:00
2019-02-20 01:20:26 -05:00
while ( listLength ( serverTL - > clients_pending_asyncwrite ) ) {
client * c = ( client * ) listNodeValue ( listFirst ( serverTL - > clients_pending_asyncwrite ) ) ;
listDelNode ( serverTL - > clients_pending_asyncwrite , listFirst ( serverTL - > clients_pending_asyncwrite ) ) ;
2019-02-20 23:30:21 -05:00
std : : lock_guard < decltype ( c - > lock ) > lock ( c - > lock ) ;
2019-02-20 01:20:26 -05:00
2019-02-20 23:30:21 -05:00
serverAssert ( c - > fPendingAsyncWrite ) ;
2019-08-26 20:18:52 -04:00
if ( c - > flags & ( CLIENT_CLOSE_ASAP | CLIENT_CLOSE_AFTER_REPLY ) )
{
2020-10-15 23:10:17 +00:00
zfree ( c - > replyAsync ) ;
c - > replyAsync = nullptr ;
2019-08-26 20:18:52 -04:00
c - > fPendingAsyncWrite = FALSE ;
continue ;
}
2019-02-20 01:20:26 -05:00
2020-10-15 23:10:17 +00:00
int size = c - > replyAsync - > used ;
2019-02-20 01:20:26 -05:00
2020-10-15 23:10:17 +00:00
if ( listLength ( c - > reply ) = = 0 & & size < = ( PROTO_REPLY_CHUNK_BYTES - c - > bufpos ) ) {
memcpy ( c - > buf + c - > bufpos , c - > replyAsync - > buf ( ) , size ) ;
c - > bufpos + = size ;
} else {
c - > reply_bytes + = c - > replyAsync - > size ;
listAddNodeTail ( c - > reply , c - > replyAsync ) ;
c - > replyAsync = nullptr ;
}
zfree ( c - > replyAsync ) ;
c - > replyAsync = nullptr ;
2019-02-20 23:30:21 -05:00
c - > fPendingAsyncWrite = FALSE ;
2019-02-20 01:20:26 -05:00
// Now install the write event handler
int ae_flags = AE_WRITABLE | AE_WRITE_THREADSAFE ;
/* For the fsync=always policy, we want that a given FD is never
* served for reading and writing in the same event loop iteration ,
* so that in the middle of receiving the query , and serving it
* to the client , we ' ll call beforeSleep ( ) that will do the
* actual fsync of AOF to disk . AE_BARRIER ensures that . */
2019-04-21 14:01:10 -04:00
if ( g_pserver - > aof_state = = AOF_ON & &
g_pserver - > aof_fsync = = AOF_FSYNC_ALWAYS )
2019-02-20 01:20:26 -05:00
{
ae_flags | = AE_BARRIER ;
}
if ( ! ( ( c - > replstate = = REPL_STATE_NONE | |
( c - > replstate = = SLAVE_STATE_ONLINE & & ! c - > repl_put_online_on_ack ) ) ) )
continue ;
2019-02-22 01:24:16 -05:00
asyncCloseClientOnOutputBufferLimitReached ( c ) ;
2019-08-26 20:18:52 -04:00
if ( c - > flags & CLIENT_CLOSE_ASAP )
continue ; // we will never write this so don't post an op
std : : atomic_thread_fence ( std : : memory_order_seq_cst ) ;
2020-05-29 17:44:55 -04:00
if ( FCorrectThread ( c ) )
2019-08-26 20:18:52 -04:00
{
2020-10-24 02:18:03 +00:00
prepareClientToWrite ( c ) ; // queue an event
2020-05-29 17:44:55 -04:00
}
else
{
2020-10-16 06:47:40 +00:00
bool expected = false ;
if ( c - > fPendingAsyncWriteHandler . compare_exchange_strong ( expected , true ) ) {
2020-05-29 17:44:55 -04:00
bool fResult = c - > postFunction ( [ ] ( client * c ) {
c - > fPendingAsyncWriteHandler = false ;
2020-10-23 15:57:39 +00:00
clientInstallWriteHandler ( c ) ;
handleClientsWithPendingWrites ( c - > iel , g_pserver - > aof_state ) ;
2020-10-16 06:47:40 +00:00
} , false ) ;
2020-05-29 17:44:55 -04:00
if ( ! fResult )
c - > fPendingAsyncWriteHandler = false ; // if we failed to set the handler then prevent this from never being reset
2019-08-26 20:18:52 -04:00
}
}
2019-02-20 01:20:26 -05:00
}
2019-02-15 14:11:05 -05:00
}
/* This function is called just before entering the event loop, in the hope
* we can just write the replies to the client output buffer without any
* need to use a syscall in order to install the writable event handler ,
* get it called , and so forth . */
2020-04-15 22:30:19 -04:00
int handleClientsWithPendingWrites ( int iel , int aof_state ) {
2019-04-21 14:01:10 -04:00
std : : unique_lock < fastlock > lockf ( g_pserver - > rgthreadvar [ iel ] . lockPendingWrite ) ;
2020-10-12 04:28:39 +00:00
int processed = 0 ;
2019-04-21 14:01:10 -04:00
serverAssert ( iel = = ( serverTL - g_pserver - > rgthreadvar ) ) ;
2019-02-15 14:11:05 -05:00
2020-10-28 04:55:56 +00:00
if ( listLength ( serverTL - > clients_pending_asyncwrite ) )
{
AeLocker locker ;
locker . arm ( nullptr ) ;
ProcessPendingAsyncWrites ( ) ;
}
2019-07-12 23:51:45 -04:00
int ae_flags = AE_WRITABLE | AE_WRITE_THREADSAFE ;
/* For the fsync=always policy, we want that a given FD is never
* served for reading and writing in the same event loop iteration ,
* so that in the middle of receiving the query , and serving it
* to the client , we ' ll call beforeSleep ( ) that will do the
* actual fsync of AOF to disk . AE_BARRIER ensures that . */
2020-04-15 22:30:19 -04:00
if ( aof_state = = AOF_ON & &
2019-07-12 23:51:45 -04:00
g_pserver - > aof_fsync = = AOF_FSYNC_ALWAYS )
{
ae_flags | = AE_BARRIER ;
}
2020-10-12 04:28:39 +00:00
auto vec = std : : move ( g_pserver - > rgthreadvar [ iel ] . clients_pending_write ) ;
processed + = ( int ) vec . size ( ) ;
for ( client * c : vec ) {
2019-07-12 23:51:45 -04:00
AssertCorrectThread ( c ) ;
2019-02-20 23:30:21 -05:00
2020-10-12 04:28:39 +00:00
uint64_t flags = c - > flags . fetch_and ( ~ CLIENT_PENDING_WRITE , std : : memory_order_relaxed ) ;
2019-02-15 14:11:05 -05:00
/* If a client is protected, don't do anything,
2020-10-12 04:28:39 +00:00
* that may trigger write error or recreate handler . */
if ( flags & CLIENT_PROTECTED ) continue ;
2019-02-15 14:11:05 -05:00
2019-07-12 23:51:45 -04:00
std : : unique_lock < decltype ( c - > lock ) > lock ( c - > lock ) ;
Don't write replies if close the client ASAP (#7202)
Before this commit, we would have continued to add replies to the reply buffer even if client
output buffer limit is reached, so the used memory would keep increasing over the configured limit.
What's more, we shouldn’t write any reply to the client if it is set 'CLIENT_CLOSE_ASAP' flag
because that doesn't conform to its definition and we will close all clients flagged with
'CLIENT_CLOSE_ASAP' in ‘beforeSleep’.
Because of code execution order, before this, we may firstly write to part of the replies to
the socket before disconnecting it, but in fact, we may can’t send the full replies to clients
since OS socket buffer is limited. But this unexpected behavior makes some commands work well,
for instance ACL DELUSER, if the client deletes the current user, we need to send reply to client
and close the connection, but before, we close the client firstly and write the reply to reply
buffer. secondly, we shouldn't do this despite the fact it works well in most cases.
We add a flag 'CLIENT_CLOSE_AFTER_COMMAND' to mark clients, this flag means we will close the
client after executing commands and send all entire replies, so that we can write replies to
reply buffer during executing commands, send replies to clients, and close them later.
We also fix some implicit problems. If client output buffer limit is enforced in 'multi/exec',
all commands will be executed completely in redis and clients will not read any reply instead of
partial replies. Even more, if the client executes 'ACL deluser' the using user in 'multi/exec',
it will not read the replies after 'ACL deluser' just like before executing 'client kill' itself
in 'multi/exec'.
We added some tests for output buffer limit breach during multi-exec and using a pipeline of
many small commands rather than one with big response.
Co-authored-by: Oran Agra <oran@redislabs.com>
(cherry picked from commit 3085577c095a0f3b1261f6dbf016d7701aadab46)
2020-09-24 21:01:41 +08:00
/* Don't write to clients that are going to be closed anyway. */
if ( c - > flags & CLIENT_CLOSE_ASAP ) continue ;
2019-02-15 14:11:05 -05:00
/* Try to write buffers to the client socket. */
2020-01-27 02:55:48 -05:00
if ( writeToClient ( c , 0 ) = = C_ERR )
2019-08-26 20:18:52 -04:00
{
2019-07-12 23:51:45 -04:00
if ( c - > flags & CLIENT_CLOSE_ASAP )
{
2019-07-18 18:39:42 -04:00
lock . release ( ) ; // still locked
2019-07-12 23:51:45 -04:00
AeLocker ae ;
ae . arm ( c ) ;
2019-08-26 20:18:52 -04:00
if ( ! freeClient ( c ) ) // writeToClient will only async close, but there's no need to wait
c - > lock . unlock ( ) ; // if we just got put on the async close list, then we need to remove the lock
2019-07-12 23:51:45 -04:00
}
2019-02-22 21:00:14 -05:00
continue ;
}
2019-02-15 14:11:05 -05:00
/* If after the synchronous writes above we still have data to
2020-10-12 04:28:39 +00:00
* output to the client , we need to install the writable handler . */
2019-02-22 01:24:16 -05:00
if ( clientHasPendingReplies ( c ) ) {
2020-01-27 19:59:04 -05:00
if ( connSetWriteHandlerWithBarrier ( c - > conn , sendReplyToClient , ae_flags , true ) = = C_ERR )
2019-02-18 22:25:35 -05:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
}
}
2019-02-20 01:20:26 -05:00
2019-02-15 14:11:05 -05:00
return processed ;
}
/* resetClient prepare the client to process the next command */
void resetClient ( client * c ) {
redisCommandProc * prevcmd = c - > cmd ? c - > cmd - > proc : NULL ;
freeClientArgv ( c ) ;
c - > reqtype = 0 ;
c - > multibulklen = 0 ;
c - > bulklen = - 1 ;
/* We clear the ASKING flag as well if we are not inside a MULTI, and
* if what we just executed is not the ASKING command itself . */
if ( ! ( c - > flags & CLIENT_MULTI ) & & prevcmd ! = askingCommand )
c - > flags & = ~ CLIENT_ASKING ;
2020-02-21 16:39:42 +01:00
/* We do the same for the CACHING command as well. It also affects
* the next command or transaction executed , in a way very similar
* to ASKING . */
if ( ! ( c - > flags & CLIENT_MULTI ) & & prevcmd ! = clientCommand )
c - > flags & = ~ CLIENT_TRACKING_CACHING ;
2019-02-15 14:11:05 -05:00
/* Remove the CLIENT_REPLY_SKIP flag if any so that the reply
* to the next command will be sent , but set the flag if the command
* we just processed was " CLIENT REPLY SKIP " . */
c - > flags & = ~ CLIENT_REPLY_SKIP ;
if ( c - > flags & CLIENT_REPLY_SKIP_NEXT ) {
c - > flags | = CLIENT_REPLY_SKIP ;
c - > flags & = ~ CLIENT_REPLY_SKIP_NEXT ;
}
2021-03-25 10:20:27 +02:00
/* Always clear the prevent logging field. */
c - > flags & = ~ CLIENT_PREVENT_LOGGING ;
2019-02-15 14:11:05 -05:00
}
Squash merging 125 typo/grammar/comment/doc PRs (#7773)
List of squashed commits or PRs
===============================
commit 66801ea
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Jan 13 00:54:31 2020 -0500
typo fix in acl.c
commit 46f55db
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun Sep 6 18:24:11 2020 +0300
Updates a couple of comments
Specifically:
* RM_AutoMemory completed instead of pointing to docs
* Updated link to custom type doc
commit 61a2aa0
Author: xindoo <xindoo@qq.com>
Date: Tue Sep 1 19:24:59 2020 +0800
Correct errors in code comments
commit a5871d1
Author: yz1509 <pro-756@qq.com>
Date: Tue Sep 1 18:36:06 2020 +0800
fix typos in module.c
commit 41eede7
Author: bookug <bookug@qq.com>
Date: Sat Aug 15 01:11:33 2020 +0800
docs: fix typos in comments
commit c303c84
Author: lazy-snail <ws.niu@outlook.com>
Date: Fri Aug 7 11:15:44 2020 +0800
fix spelling in redis.conf
commit 1eb76bf
Author: zhujian <zhujianxyz@gmail.com>
Date: Thu Aug 6 15:22:10 2020 +0800
add a missing 'n' in comment
commit 1530ec2
Author: Daniel Dai <764122422@qq.com>
Date: Mon Jul 27 00:46:35 2020 -0400
fix spelling in tracking.c
commit e517b31
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:32 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit c300eff
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:23 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit 4c058a8
Author: 陈浩鹏 <chenhaopeng@heytea.com>
Date: Thu Jun 25 19:00:56 2020 +0800
Grammar fix and clarification
commit 5fcaa81
Author: bodong.ybd <bodong.ybd@alibaba-inc.com>
Date: Fri Jun 19 10:09:00 2020 +0800
Fix typos
commit 4caca9a
Author: Pruthvi P <pruthvi@ixigo.com>
Date: Fri May 22 00:33:22 2020 +0530
Fix typo eviciton => eviction
commit b2a25f6
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Sun May 17 12:39:59 2020 -0400
Fix a typo.
commit 12842ae
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun May 3 17:16:59 2020 -0400
fix spelling in redis conf
commit ddba07c
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Sat May 2 23:25:34 2020 +0100
Correct a "conflicts" spelling error.
commit 8fc7bf2
Author: Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Date: Thu Apr 30 10:25:27 2020 +0900
docs: fix EXPIRE_FAST_CYCLE_DURATION to ACTIVE_EXPIRE_CYCLE_FAST_DURATION
commit 9b2b67a
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Fri Apr 24 11:46:22 2020 -0400
Fix a typo.
commit 0746f10
Author: devilinrust <63737265+devilinrust@users.noreply.github.com>
Date: Thu Apr 16 00:17:53 2020 +0200
Fix typos in server.c
commit 92b588d
Author: benjessop12 <56115861+benjessop12@users.noreply.github.com>
Date: Mon Apr 13 13:43:55 2020 +0100
Fix spelling mistake in lazyfree.c
commit 1da37aa
Merge: 2d4ba28 c90b2a4
Author: hwware <wen.hui.ware@gmail.com>
Date: Thu Mar 5 22:41:31 2020 -0500
Merge remote-tracking branch 'upstream/unstable' into expiretypofix
commit 2d4ba28
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Mar 2 00:09:40 2020 -0500
fix typo in expire.c
commit 1a746f7
Author: SennoYuki <minakami1yuki@gmail.com>
Date: Thu Feb 27 16:54:32 2020 +0800
fix typo
commit 8599b1a
Author: dongheejeong <donghee950403@gmail.com>
Date: Sun Feb 16 20:31:43 2020 +0000
Fix typo in server.c
commit f38d4e8
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun Feb 2 22:58:38 2020 -0500
fix typo in evict.c
commit fe143fc
Author: Leo Murillo <leonardo.murillo@gmail.com>
Date: Sun Feb 2 01:57:22 2020 -0600
Fix a few typos in redis.conf
commit 1ab4d21
Author: viraja1 <anchan.viraj@gmail.com>
Date: Fri Dec 27 17:15:58 2019 +0530
Fix typo in Latency API docstring
commit ca1f70e
Author: gosth <danxuedexing@qq.com>
Date: Wed Dec 18 15:18:02 2019 +0800
fix typo in sort.c
commit a57c06b
Author: ZYunH <zyunhjob@163.com>
Date: Mon Dec 16 22:28:46 2019 +0800
fix-zset-typo
commit b8c92b5
Author: git-hulk <hulk.website@gmail.com>
Date: Mon Dec 16 15:51:42 2019 +0800
FIX: typo in cluster.c, onformation->information
commit 9dd981c
Author: wujm2007 <jim.wujm@gmail.com>
Date: Mon Dec 16 09:37:52 2019 +0800
Fix typo
commit e132d7a
Author: Sebastien Williams-Wynn <s.williamswynn.mail@gmail.com>
Date: Fri Nov 15 00:14:07 2019 +0000
Minor typo change
commit 47f44d5
Author: happynote3966 <01ssrmikururudevice01@gmail.com>
Date: Mon Nov 11 22:08:48 2019 +0900
fix comment typo in redis-cli.c
commit b8bdb0d
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 18:00:17 2019 +0800
Fix a spelling mistake of comments in defragDictBucketCallback
commit 0def46a
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 13:09:27 2019 +0800
fix some spelling mistakes of comments in defrag.c
commit f3596fd
Author: Phil Rajchgot <tophil@outlook.com>
Date: Sun Oct 13 02:02:32 2019 -0400
Typo and grammar fixes
Redis and its documentation are great -- just wanted to submit a few corrections in the spirit of Hacktoberfest. Thanks for all your work on this project. I use it all the time and it works beautifully.
commit 2b928cd
Author: KangZhiDong <worldkzd@gmail.com>
Date: Sun Sep 1 07:03:11 2019 +0800
fix typos
commit 33aea14
Author: Axlgrep <axlgrep@gmail.com>
Date: Tue Aug 27 11:02:18 2019 +0800
Fixed eviction spelling issues
commit e282a80
Author: Simen Flatby <simen@oms.no>
Date: Tue Aug 20 15:25:51 2019 +0200
Update comments to reflect prop name
In the comments the prop is referenced as replica-validity-factor,
but it is really named cluster-replica-validity-factor.
commit 74d1f9a
Author: Jim Green <jimgreen2013@qq.com>
Date: Tue Aug 20 20:00:31 2019 +0800
fix comment error, the code is ok
commit eea1407
Author: Liao Tonglang <liaotonglang@gmail.com>
Date: Fri May 31 10:16:18 2019 +0800
typo fix
fix cna't to can't
commit 0da553c
Author: KAWACHI Takashi <tkawachi@gmail.com>
Date: Wed Jul 17 00:38:16 2019 +0900
Fix typo
commit 7fc8fb6
Author: Michael Prokop <mika@grml.org>
Date: Tue May 28 17:58:42 2019 +0200
Typo fixes
s/familar/familiar/
s/compatiblity/compatibility/
s/ ot / to /
s/itsef/itself/
commit 5f46c9d
Author: zhumoing <34539422+zhumoing@users.noreply.github.com>
Date: Tue May 21 21:16:50 2019 +0800
typo-fixes
typo-fixes
commit 321dfe1
Author: wxisme <850885154@qq.com>
Date: Sat Mar 16 15:10:55 2019 +0800
typo fix
commit b4fb131
Merge: 267e0e6 4842305
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Fri Feb 8 22:55:45 2019 +0200
Merge branch 'unstable' of antirez/redis into unstable
commit 267e0e6
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Wed Jan 30 21:26:04 2019 +0200
Minor typo fix
commit 30544e7
Author: inshal96 <39904558+inshal96@users.noreply.github.com>
Date: Fri Jan 4 16:54:50 2019 +0500
remove an extra 'a' in the comments
commit 337969d
Author: BrotherGao <yangdongheng11@gmail.com>
Date: Sat Dec 29 12:37:29 2018 +0800
fix typo in redis.conf
commit 9f4b121
Merge: 423a030 19d0ece
Author: BrotherGao <yangdongheng@xiaomi.com>
Date: Sat Dec 29 11:41:12 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 423a030
Merge: 42b02b7 0423081
Author: 杨东衡 <yangdongheng@xiaomi.com>
Date: Tue Dec 4 23:56:11 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 42b02b7
Merge: 8c7dcff efa96f0
Author: Dongheng Yang <yangdongheng11@gmail.com>
Date: Sun Oct 28 15:54:23 2018 +0800
Merge pull request #1 from antirez/unstable
update local data
commit 714b589
Author: Christian <crifei93@gmail.com>
Date: Fri Dec 28 01:17:26 2018 +0100
fix typo "resulution"
commit e23259d
Author: garenchan <1412950785@qq.com>
Date: Wed Dec 26 09:58:35 2018 +0800
fix typo: segfauls -> segfault
commit a9359f8
Author: xjp <jianping_xie@aliyun.com>
Date: Tue Dec 18 17:31:44 2018 +0800
Fixed REDISMODULE_H spell bug
commit a12c3e4
Author: jdiaz <jrd.palacios@gmail.com>
Date: Sat Dec 15 23:39:52 2018 -0600
Fixes hyperloglog hash function comment block description
commit 770eb11
Author: 林上耀 <1210tom@163.com>
Date: Sun Nov 25 17:16:10 2018 +0800
fix typo
commit fd97fbb
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Fri Nov 23 17:14:01 2018 +0100
Correct "unsupported" typo.
commit a85522d
Author: Jungnam Lee <jungnam.lee@oracle.com>
Date: Thu Nov 8 23:01:29 2018 +0900
fix typo in test comments
commit ade8007
Author: Arun Kumar <palerdot@users.noreply.github.com>
Date: Tue Oct 23 16:56:35 2018 +0530
Fixed grammatical typo
Fixed typo for word 'dictionary'
commit 869ee39
Author: Hamid Alaei <hamid.a85@gmail.com>
Date: Sun Aug 12 16:40:02 2018 +0430
fix documentations: (ThreadSafeContextStart/Stop -> ThreadSafeContextLock/Unlock), minor typo
commit f89d158
Author: Mayank Jain <mayankjain255@gmail.com>
Date: Tue Jul 31 23:01:21 2018 +0530
Updated README.md with some spelling corrections.
Made correction in spelling of some misspelled words.
commit 892198e
Author: dsomeshwar <someshwar.dhayalan@gmail.com>
Date: Sat Jul 21 23:23:04 2018 +0530
typo fix
commit 8a4d780
Author: Itamar Haber <itamar@redislabs.com>
Date: Mon Apr 30 02:06:52 2018 +0300
Fixes some typos
commit e3acef6
Author: Noah Rosamilia <ivoahivoah@gmail.com>
Date: Sat Mar 3 23:41:21 2018 -0500
Fix typo in /deps/README.md
commit 04442fb
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:32:42 2018 +0800
Fix typo in readSyncBulkPayload() comment.
commit 9f36880
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:20:37 2018 +0800
replication.c comment: run_id -> replid.
commit f866b4a
Author: Francesco 'makevoid' Canessa <makevoid@gmail.com>
Date: Thu Feb 22 22:01:56 2018 +0000
fix comment typo in server.c
commit 0ebc69b
Author: 줍 <jubee0124@gmail.com>
Date: Mon Feb 12 16:38:48 2018 +0900
Fix typo in redis.conf
Fix `five behaviors` to `eight behaviors` in [this sentence ](antirez/redis@unstable/redis.conf#L564)
commit b50a620
Author: martinbroadhurst <martinbroadhurst@users.noreply.github.com>
Date: Thu Dec 28 12:07:30 2017 +0000
Fix typo in valgrind.sup
commit 7d8f349
Author: Peter Boughton <peter@sorcerersisle.com>
Date: Mon Nov 27 19:52:19 2017 +0000
Update CONTRIBUTING; refer doc updates to redis-doc repo.
commit 02dec7e
Author: Klauswk <klauswk1@hotmail.com>
Date: Tue Oct 24 16:18:38 2017 -0200
Fix typo in comment
commit e1efbc8
Author: chenshi <baiwfg2@gmail.com>
Date: Tue Oct 3 18:26:30 2017 +0800
Correct two spelling errors of comments
commit 93327d8
Author: spacewander <spacewanderlzx@gmail.com>
Date: Wed Sep 13 16:47:24 2017 +0800
Update the comment for OBJ_ENCODING_EMBSTR_SIZE_LIMIT's value
The value of OBJ_ENCODING_EMBSTR_SIZE_LIMIT is 44 now instead of 39.
commit 63d361f
Author: spacewander <spacewanderlzx@gmail.com>
Date: Tue Sep 12 15:06:42 2017 +0800
Fix <prevlen> related doc in ziplist.c
According to the definition of ZIP_BIG_PREVLEN and other related code,
the guard of single byte <prevlen> should be 254 instead of 255.
commit ebe228d
Author: hanael80 <hanael80@gmail.com>
Date: Tue Aug 15 09:09:40 2017 +0900
Fix typo
commit 6b696e6
Author: Matt Robenolt <matt@ydekproductions.com>
Date: Mon Aug 14 14:50:47 2017 -0700
Fix typo in LATENCY DOCTOR output
commit a2ec6ae
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 15 14:15:16 2017 +0800
Fix a typo: form => from
commit 3ab7699
Author: caosiyang <caosiyang@qiyi.com>
Date: Thu Aug 10 18:40:33 2017 +0800
Fix a typo: replicationFeedSlavesFromMaster() => replicationFeedSlavesFromMasterStream()
commit 72d43ef
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 8 15:57:25 2017 +0800
fix a typo: servewr => server
commit 707c958
Author: Bo Cai <charpty@gmail.com>
Date: Wed Jul 26 21:49:42 2017 +0800
redis-cli.c typo: conut -> count.
Signed-off-by: Bo Cai <charpty@gmail.com>
commit b9385b2
Author: JackDrogon <jack.xsuperman@gmail.com>
Date: Fri Jun 30 14:22:31 2017 +0800
Fix some spell problems
commit 20d9230
Author: akosel <aaronjkosel@gmail.com>
Date: Sun Jun 4 19:35:13 2017 -0500
Fix typo
commit b167bfc
Author: Krzysiek Witkowicz <krzysiekwitkowicz@gmail.com>
Date: Mon May 22 21:32:27 2017 +0100
Fix #4008 small typo in comment
commit 2b78ac8
Author: Jake Clarkson <jacobwclarkson@gmail.com>
Date: Wed Apr 26 15:49:50 2017 +0100
Correct typo in tests/unit/hyperloglog.tcl
commit b0f1cdb
Author: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Wed Apr 19 14:25:18 2017 -0700
Fix typo
commit a90b0f9
Author: charsyam <charsyam@naver.com>
Date: Thu Mar 16 18:19:53 2017 +0900
fix typos
fix typos
fix typos
commit 8430a79
Author: Richard Hart <richardhart92@gmail.com>
Date: Mon Mar 13 22:17:41 2017 -0400
Fixed log message typo in listenToPort.
commit 481a1c2
Author: Vinod Kumar <kumar003vinod@gmail.com>
Date: Sun Jan 15 23:04:51 2017 +0530
src/db.c: Correct "save" -> "safe" typo
commit 586b4d3
Author: wangshaonan <wshn13@gmail.com>
Date: Wed Dec 21 20:28:27 2016 +0800
Fix typo they->the in helloworld.c
commit c1c4b5e
Author: Jenner <hypxm@qq.com>
Date: Mon Dec 19 16:39:46 2016 +0800
typo error
commit 1ee1a3f
Author: tielei <43289893@qq.com>
Date: Mon Jul 18 13:52:25 2016 +0800
fix some comments
commit 11a41fb
Author: Otto Kekäläinen <otto@seravo.fi>
Date: Sun Jul 3 10:23:55 2016 +0100
Fix spelling in documentation and comments
commit 5fb5d82
Author: francischan <f1ancis621@gmail.com>
Date: Tue Jun 28 00:19:33 2016 +0800
Fix outdated comments about redis.c file.
It should now refer to server.c file.
commit 6b254bc
Author: lmatt-bit <lmatt123n@gmail.com>
Date: Thu Apr 21 21:45:58 2016 +0800
Refine the comment of dictRehashMilliseconds func
SLAVECONF->REPLCONF in comment - by andyli029
commit ee9869f
Author: clark.kang <charsyam@naver.com>
Date: Tue Mar 22 11:09:51 2016 +0900
fix typos
commit f7b3b11
Author: Harisankar H <harisankarh@gmail.com>
Date: Wed Mar 9 11:49:42 2016 +0530
Typo correction: "faield" --> "failed"
Typo correction: "faield" --> "failed"
commit 3fd40fc
Author: Itamar Haber <itamar@redislabs.com>
Date: Thu Feb 25 10:31:51 2016 +0200
Fixes a typo in comments
commit 621c160
Author: Prayag Verma <prayag.verma@gmail.com>
Date: Mon Feb 1 12:36:20 2016 +0530
Fix typo in Readme.md
Spelling mistakes -
`eviciton` > `eviction`
`familar` > `familiar`
commit d7d07d6
Author: WonCheol Lee <toctoc21c@gmail.com>
Date: Wed Dec 30 15:11:34 2015 +0900
Typo fixed
commit a4dade7
Author: Felix Bünemann <buenemann@louis.info>
Date: Mon Dec 28 11:02:55 2015 +0100
[ci skip] Improve supervised upstart config docs
This mentions that "expect stop" is required for supervised upstart
to work correctly. See http://upstart.ubuntu.com/cookbook/#expect-stop
for an explanation.
commit d9caba9
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:30:03 2015 +1100
README: Remove trailing whitespace
commit 72d42e5
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:32 2015 +1100
README: Fix typo. th => the
commit dd6e957
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:20 2015 +1100
README: Fix typo. familar => familiar
commit 3a12b23
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:28:54 2015 +1100
README: Fix typo. eviciton => eviction
commit 2d1d03b
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:21:45 2015 +1100
README: Fix typo. sever => server
commit 3973b06
Author: Itamar Haber <itamar@garantiadata.com>
Date: Sat Dec 19 17:01:20 2015 +0200
Typo fix
commit 4f2e460
Author: Steve Gao <fu@2token.com>
Date: Fri Dec 4 10:22:05 2015 +0800
Update README - fix typos
commit b21667c
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:48:37 2015 +0800
delete redundancy color judge in sdscatcolor
commit 88894c7
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:14:42 2015 +0800
the example output shoule be HelloWorld
commit 2763470
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 17:41:39 2015 +0800
modify error word keyevente
Signed-off-by: binyan <binbin.yan@nokia.com>
commit 0847b3d
Author: Bruno Martins <bscmartins@gmail.com>
Date: Wed Nov 4 11:37:01 2015 +0000
typo
commit bbb9e9e
Author: dawedawe <dawedawe@gmx.de>
Date: Fri Mar 27 00:46:41 2015 +0100
typo: zimap -> zipmap
commit 5ed297e
Author: Axel Advento <badwolf.bloodseeker.rev@gmail.com>
Date: Tue Mar 3 15:58:29 2015 +0800
Fix 'salve' typos to 'slave'
commit edec9d6
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Wed Jun 12 14:12:47 2019 +0200
Update README.md
Co-Authored-By: Qix <Qix-@users.noreply.github.com>
commit 692a7af
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Tue May 28 14:32:04 2019 +0200
grammar
commit d962b0a
Author: Nick Frost <nickfrostatx@gmail.com>
Date: Wed Jul 20 15:17:12 2016 -0700
Minor grammar fix
commit 24fff01aaccaf5956973ada8c50ceb1462e211c6 (typos)
Author: Chad Miller <chadm@squareup.com>
Date: Tue Sep 8 13:46:11 2020 -0400
Fix faulty comment about operation of unlink()
commit 3cd5c1f3326c52aa552ada7ec797c6bb16452355
Author: Kevin <kevin.xgr@gmail.com>
Date: Wed Nov 20 00:13:50 2019 +0800
Fix typo in server.c.
From a83af59 Mon Sep 17 00:00:00 2001
From: wuwo <wuwo@wacai.com>
Date: Fri, 17 Mar 2017 20:37:45 +0800
Subject: [PATCH] falure to failure
From c961896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B7=A6=E6=87=B6?= <veficos@gmail.com>
Date: Sat, 27 May 2017 15:33:04 +0800
Subject: [PATCH] fix typo
From e600ef2 Mon Sep 17 00:00:00 2001
From: "rui.zou" <rui.zou@yunify.com>
Date: Sat, 30 Sep 2017 12:38:15 +0800
Subject: [PATCH] fix a typo
From c7d07fa Mon Sep 17 00:00:00 2001
From: Alexandre Perrin <alex@kaworu.ch>
Date: Thu, 16 Aug 2018 10:35:31 +0200
Subject: [PATCH] deps README.md typo
From b25cb67 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 10:55:37 +0300
Subject: [PATCH 1/2] fix typos in header
From ad28ca6 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 11:02:36 +0300
Subject: [PATCH 2/2] fix typos
commit 34924cdedd8552466fc22c1168d49236cb7ee915
Author: Adrian Lynch <adi_ady_ade@hotmail.com>
Date: Sat Apr 4 21:59:15 2015 +0100
Typos fixed
commit fd2a1e7
Author: Jan <jsteemann@users.noreply.github.com>
Date: Sat Oct 27 19:13:01 2018 +0200
Fix typos
Fix typos
commit e14e47c1a234b53b0e103c5f6a1c61481cbcbb02
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:30:07 2019 -0500
Fix multiple misspellings of "following"
commit 79b948ce2dac6b453fe80995abbcaac04c213d5a
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:24:28 2019 -0500
Fix misspelling of create-cluster
commit 1fffde52666dc99ab35efbd31071a4c008cb5a71
Author: Andy Lester <andy@petdance.com>
Date: Wed Jul 31 17:57:56 2019 -0500
Fix typos
commit 204c9ba9651e9e05fd73936b452b9a30be456cfe
Author: Xiaobo Zhu <xiaobo.zhu@shopee.com>
Date: Tue Aug 13 22:19:25 2019 +0800
fix typos
Squashed commit of the following:
commit 1d9aaf8
Author: danmedani <danmedani@gmail.com>
Date: Sun Aug 2 11:40:26 2015 -0700
README typo fix.
Squashed commit of the following:
commit 32bfa7c
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Jul 6 21:15:08 2015 +0200
Fixed grammer
Squashed commit of the following:
commit b24f69c
Author: Sisir Koppaka <sisir.koppaka@gmail.com>
Date: Mon Mar 2 22:38:45 2015 -0500
utils/hashtable/rehashing.c: Fix typos
Squashed commit of the following:
commit 4e04082
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Mar 23 08:22:21 2015 +0000
Small config file documentation improvements
Squashed commit of the following:
commit acb8773
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:52:48 2015 -0700
Typo and grammar fixes in readme
commit 2eb75b6
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:36:18 2015 -0700
fixed redis.conf comment
Squashed commit of the following:
commit a8249a2
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri Dec 11 11:39:52 2015 +0530
Revise correction of typos.
Squashed commit of the following:
commit 3c02028
Author: zhaojun11 <zhaojun11@jd.com>
Date: Wed Jan 17 19:05:28 2018 +0800
Fix typos include two code typos in cluster.c and latency.c
Squashed commit of the following:
commit 9dba47c
Author: q191201771 <191201771@qq.com>
Date: Sat Jan 4 11:31:04 2020 +0800
fix function listCreate comment in adlist.c
Update src/server.c
commit 2c7c2cb536e78dd211b1ac6f7bda00f0f54faaeb
Author: charpty <charpty@gmail.com>
Date: Tue May 1 23:16:59 2018 +0800
server.c typo: modules system dictionary type comment
Signed-off-by: charpty <charpty@gmail.com>
commit a8395323fb63cb59cb3591cb0f0c8edb7c29a680
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun May 6 00:25:18 2018 +0300
Updates test_helper.tcl's help with undocumented options
Specifically:
* Host
* Port
* Client
commit bde6f9ced15755cd6407b4af7d601b030f36d60b
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 15:19:19 2018 +0800
fix comments in deps files
commit 3172474ba991532ab799ee1873439f3402412331
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 14:33:49 2018 +0800
fix some comments
commit 01b6f2b6858b5cf2ce4ad5092d2c746e755f53f0
Author: Thor Juhasz <thor@juhasz.pro>
Date: Sun Nov 18 14:37:41 2018 +0100
Minor fixes to comments
Found some parts a little unclear on a first read, which prompted me to have a better look at the file and fix some minor things I noticed.
Fixing minor typos and grammar. There are no changes to configuration options.
These changes are only meant to help the user better understand the explanations to the various configuration options
(cherry picked from commit 285ef446b05e09013556e7a490677494a9b4bb3e)
2020-09-10 13:43:38 +03:00
/* This function is used when we want to re-enter the event loop but there
2019-02-15 14:11:05 -05:00
* is the risk that the client we are dealing with will be freed in some
* way . This happens for instance in :
*
* * DEBUG RELOAD and similar .
* * When a Lua script is in - BUSY state .
*
* So the function will protect the client by doing two things :
*
* 1 ) It removes the file events . This way it is not possible that an
* error is signaled on the socket , freeing the client .
* 2 ) Moreover it makes sure that if the client is freed in a different code
* path , it is not really released , but only marked for later release . */
void protectClient ( client * c ) {
c - > flags | = CLIENT_PROTECTED ;
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2020-10-01 11:27:45 +03:00
if ( c - > conn ) {
connSetReadHandler ( c - > conn , NULL ) ;
connSetWriteHandler ( c - > conn , NULL ) ;
}
2019-02-15 14:11:05 -05:00
}
/* This will undo the client protection done by protectClient() */
void unprotectClient ( client * c ) {
2019-02-18 22:25:35 -05:00
AssertCorrectThread ( c ) ;
2019-02-15 14:11:05 -05:00
if ( c - > flags & CLIENT_PROTECTED ) {
c - > flags & = ~ CLIENT_PROTECTED ;
2020-10-01 11:27:45 +03:00
if ( c - > conn ) {
2021-01-25 16:07:08 +00:00
connSetReadHandler ( c - > conn , readQueryFromClient , true ) ;
2020-10-01 11:27:45 +03:00
if ( clientHasPendingReplies ( c ) ) clientInstallWriteHandler ( c ) ;
}
2019-02-15 14:11:05 -05:00
}
}
/* Like processMultibulkBuffer(), but for the inline protocol instead of RESP,
* this function consumes the client query buffer and creates a command ready
* to be executed inside the client structure . Returns C_OK if the command
* is ready to be executed , or C_ERR if there is still protocol to read to
* have a well formed command . The function also returns C_ERR when there is
* a protocol error : in such a case the client structure is setup to reply
* with the error and close the connection . */
int processInlineBuffer ( client * c ) {
char * newline ;
int argc , j , linefeed_chars = 1 ;
sds * argv , aux ;
size_t querylen ;
/* Search for end of line */
newline = strchr ( c - > querybuf + c - > qb_pos , ' \n ' ) ;
/* Nothing to do without a \r\n */
if ( newline = = NULL ) {
if ( sdslen ( c - > querybuf ) - c - > qb_pos > PROTO_INLINE_MAX_SIZE ) {
addReplyError ( c , " Protocol error: too big inline request " ) ;
setProtocolError ( " too big inline request " , c ) ;
}
return C_ERR ;
}
/* Handle the \r\n case. */
2021-01-14 04:00:55 +08:00
if ( newline ! = c - > querybuf + c - > qb_pos & & * ( newline - 1 ) = = ' \r ' )
2019-02-15 14:11:05 -05:00
newline - - , linefeed_chars + + ;
/* Split the input buffer up to the \r\n */
querylen = newline - ( c - > querybuf + c - > qb_pos ) ;
aux = sdsnewlen ( c - > querybuf + c - > qb_pos , querylen ) ;
argv = sdssplitargs ( aux , & argc ) ;
sdsfree ( aux ) ;
if ( argv = = NULL ) {
addReplyError ( c , " Protocol error: unbalanced quotes in request " ) ;
setProtocolError ( " unbalanced quotes in inline request " , c ) ;
return C_ERR ;
}
/* Newline from slaves can be used to refresh the last ACK time.
2019-10-13 12:29:20 -04:00
* This is useful for a replica to ping back while loading a big
2019-02-15 14:11:05 -05:00
* RDB file . */
2020-02-06 14:09:45 +05:30
if ( querylen = = 0 & & getClientType ( c ) = = CLIENT_TYPE_SLAVE )
2019-04-21 14:01:10 -04:00
c - > repl_ack_time = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
2020-05-27 11:45:49 +02:00
/* Masters should never send us inline protocol to run actual
* commands . If this happens , it is likely due to a bug in Redis where
* we got some desynchronization in the protocol , for example
* beause of a PSYNC gone bad .
*
* However the is an exception : masters may send us just a newline
* to keep the connection active . */
if ( querylen ! = 0 & & c - > flags & CLIENT_MASTER ) {
2021-01-06 14:20:53 -05:00
sdsfreesplitres ( argv , argc ) ;
2020-05-27 11:45:49 +02:00
serverLog ( LL_WARNING , " WARNING: Receiving inline protocol from master, master stream corruption? Closing the master connection and discarding the cached master. " ) ;
setProtocolError ( " Master using the inline protocol. Desync? " , c ) ;
return C_ERR ;
}
2019-02-15 14:11:05 -05:00
/* Move querybuffer position to the next query in the buffer. */
c - > qb_pos + = querylen + linefeed_chars ;
/* Setup argv array on client structure */
if ( argc ) {
if ( c - > argv ) zfree ( c - > argv ) ;
c - > argv = ( robj * * ) zmalloc ( sizeof ( robj * ) * argc , MALLOC_LOCAL ) ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
2019-02-15 14:11:05 -05:00
}
/* Create redis objects for all arguments. */
for ( c - > argc = 0 , j = 0 ; j < argc ; j + + ) {
2019-12-29 15:40:40 +01:00
c - > argv [ c - > argc ] = createObject ( OBJ_STRING , argv [ j ] ) ;
c - > argc + + ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum + = sdslen ( argv [ j ] ) ;
2019-02-15 14:11:05 -05:00
}
sds_free ( argv ) ;
return C_OK ;
}
/* Helper function. Record protocol erro details in server log,
2020-05-15 10:19:13 +02:00
* and set the client as CLIENT_CLOSE_AFTER_REPLY and
* CLIENT_PROTOCOL_ERROR . */
2019-02-15 14:11:05 -05:00
# define PROTO_DUMP_LEN 128
static void setProtocolError ( const char * errstr , client * c ) {
2020-05-29 00:57:07 -04:00
if ( cserver . verbosity < = LL_VERBOSE | | c - > flags & CLIENT_MASTER ) {
2019-02-15 14:11:05 -05:00
sds client = catClientInfoString ( sdsempty ( ) , c ) ;
/* Sample some protocol to given an idea about what was inside. */
char buf [ 256 ] ;
if ( sdslen ( c - > querybuf ) - c - > qb_pos < PROTO_DUMP_LEN ) {
snprintf ( buf , sizeof ( buf ) , " Query buffer during protocol error: '%s' " , c - > querybuf + c - > qb_pos ) ;
} else {
snprintf ( buf , sizeof ( buf ) , " Query buffer during protocol error: '%.*s' (... more %zu bytes ...) '%.*s' " , PROTO_DUMP_LEN / 2 , c - > querybuf + c - > qb_pos , sdslen ( c - > querybuf ) - c - > qb_pos - PROTO_DUMP_LEN , PROTO_DUMP_LEN / 2 , c - > querybuf + sdslen ( c - > querybuf ) - PROTO_DUMP_LEN / 2 ) ;
}
/* Remove non printable chars. */
char * p = buf ;
while ( * p ! = ' \0 ' ) {
if ( ! isprint ( * p ) ) * p = ' . ' ;
p + + ;
}
/* Log all the client and protocol info. */
2020-05-27 11:45:49 +02:00
int loglevel = ( c - > flags & CLIENT_MASTER ) ? LL_WARNING :
LL_VERBOSE ;
serverLog ( loglevel ,
2019-02-15 14:11:05 -05:00
" Protocol error (%s) from client: %s. %s " , errstr , client , buf ) ;
sdsfree ( client ) ;
}
2020-05-15 10:19:13 +02:00
c - > flags | = ( CLIENT_CLOSE_AFTER_REPLY | CLIENT_PROTOCOL_ERROR ) ;
2019-02-15 14:11:05 -05:00
}
/* Process the query buffer for client 'c', setting up the client argument
* vector for command execution . Returns C_OK if after running the function
* the client has a well - formed ready to be processed command , otherwise
* C_ERR if there is still to read more buffer to get the full command .
* The function also returns C_ERR when there is a protocol error : in such a
* case the client structure is setup to reply with the error and close
* the connection .
*
* This function is called if processInputBuffer ( ) detects that the next
* command is in RESP format , so the first byte in the command is found
* to be ' * ' . Otherwise for inline commands processInlineBuffer ( ) is called . */
int processMultibulkBuffer ( client * c ) {
char * newline = NULL ;
int ok ;
long long ll ;
if ( c - > multibulklen = = 0 ) {
/* The client should have been reset */
serverAssertWithInfo ( c , NULL , c - > argc = = 0 ) ;
/* Multi bulk length cannot be read without a \r\n */
newline = strchr ( c - > querybuf + c - > qb_pos , ' \r ' ) ;
if ( newline = = NULL ) {
if ( sdslen ( c - > querybuf ) - c - > qb_pos > PROTO_INLINE_MAX_SIZE ) {
addReplyError ( c , " Protocol error: too big mbulk count string " ) ;
setProtocolError ( " too big mbulk count string " , c ) ;
}
return C_ERR ;
}
/* Buffer should also contain \n */
if ( newline - ( c - > querybuf + c - > qb_pos ) > ( ssize_t ) ( sdslen ( c - > querybuf ) - c - > qb_pos - 2 ) )
return C_ERR ;
/* We know for sure there is a whole line since newline != NULL,
* so go ahead and find out the multi bulk length . */
serverAssertWithInfo ( c , NULL , c - > querybuf [ c - > qb_pos ] = = ' * ' ) ;
ok = string2ll ( c - > querybuf + 1 + c - > qb_pos , newline - ( c - > querybuf + 1 + c - > qb_pos ) , & ll ) ;
if ( ! ok | | ll > 1024 * 1024 ) {
addReplyError ( c , " Protocol error: invalid multibulk length " ) ;
setProtocolError ( " invalid mbulk count " , c ) ;
return C_ERR ;
}
c - > qb_pos = ( newline - c - > querybuf ) + 2 ;
if ( ll < = 0 ) return C_OK ;
c - > multibulklen = ll ;
/* Setup argv array on client structure */
if ( c - > argv ) zfree ( c - > argv ) ;
c - > argv = ( robj * * ) zmalloc ( sizeof ( robj * ) * c - > multibulklen , MALLOC_LOCAL ) ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
2019-02-15 14:11:05 -05:00
}
serverAssertWithInfo ( c , NULL , c - > multibulklen > 0 ) ;
while ( c - > multibulklen ) {
/* Read bulk length if unknown */
if ( c - > bulklen = = - 1 ) {
newline = strchr ( c - > querybuf + c - > qb_pos , ' \r ' ) ;
if ( newline = = NULL ) {
if ( sdslen ( c - > querybuf ) - c - > qb_pos > PROTO_INLINE_MAX_SIZE ) {
addReplyError ( c ,
" Protocol error: too big bulk count string " ) ;
setProtocolError ( " too big bulk count string " , c ) ;
return C_ERR ;
}
break ;
}
/* Buffer should also contain \n */
if ( newline - ( c - > querybuf + c - > qb_pos ) > ( ssize_t ) ( sdslen ( c - > querybuf ) - c - > qb_pos - 2 ) )
break ;
if ( c - > querybuf [ c - > qb_pos ] ! = ' $ ' ) {
addReplyErrorFormat ( c ,
" Protocol error: expected '$', got '%c' " ,
c - > querybuf [ c - > qb_pos ] ) ;
setProtocolError ( " expected $ but got something else " , c ) ;
return C_ERR ;
}
ok = string2ll ( c - > querybuf + c - > qb_pos + 1 , newline - ( c - > querybuf + c - > qb_pos + 1 ) , & ll ) ;
2018-10-30 00:50:36 +08:00
if ( ! ok | | ll < 0 | |
2020-09-30 19:47:55 +00:00
( ! ( c - > flags & CLIENT_MASTER ) & & ll > g_pserver - > proto_max_bulk_len ) ) {
2019-02-15 14:11:05 -05:00
addReplyError ( c , " Protocol error: invalid bulk length " ) ;
setProtocolError ( " invalid bulk length " , c ) ;
return C_ERR ;
}
c - > qb_pos = newline - c - > querybuf + 2 ;
if ( ll > = PROTO_MBULK_BIG_ARG ) {
/* If we are going to read a large object from network
* try to make it likely that it will start at c - > querybuf
* boundary so that we can optimize object creation
* avoiding a large copy of data .
*
* But only when the data we have not parsed is less than
* or equal to ll + 2. If the data length is greater than
* ll + 2 , trimming querybuf is just a waste of time , because
* at this time the querybuf contains not only our bulk . */
if ( sdslen ( c - > querybuf ) - c - > qb_pos < = ( size_t ) ll + 2 ) {
sdsrange ( c - > querybuf , c - > qb_pos , - 1 ) ;
c - > qb_pos = 0 ;
/* Hint the sds library about the amount of bytes this string is
* going to contain . */
2020-12-17 11:58:58 -08:00
c - > querybuf = sdsMakeRoomFor ( c - > querybuf , ll + 2 - sdslen ( c - > querybuf ) ) ;
2019-02-15 14:11:05 -05:00
}
}
c - > bulklen = ll ;
}
/* Read bulk argument */
if ( sdslen ( c - > querybuf ) - c - > qb_pos < ( size_t ) ( c - > bulklen + 2 ) ) {
/* Not enough data (+2 == trailing \r\n) */
break ;
} else {
/* Optimization: if the buffer contains JUST our bulk element
* instead of creating a new object by * copying * the sds we
* just use the current sds string . */
if ( c - > qb_pos = = 0 & &
c - > bulklen > = PROTO_MBULK_BIG_ARG & &
sdslen ( c - > querybuf ) = = ( size_t ) ( c - > bulklen + 2 ) )
{
c - > argv [ c - > argc + + ] = createObject ( OBJ_STRING , c - > querybuf ) ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum + = c - > bulklen ;
2019-02-15 14:11:05 -05:00
sdsIncrLen ( c - > querybuf , - 2 ) ; /* remove CRLF */
/* Assume that if we saw a fat argument we'll see another one
* likely . . . */
c - > querybuf = sdsnewlen ( SDS_NOINIT , c - > bulklen + 2 ) ;
sdsclear ( c - > querybuf ) ;
} else {
c - > argv [ c - > argc + + ] =
createStringObject ( c - > querybuf + c - > qb_pos , c - > bulklen ) ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum + = c - > bulklen ;
2019-02-15 14:11:05 -05:00
c - > qb_pos + = c - > bulklen + 2 ;
}
c - > bulklen = - 1 ;
c - > multibulklen - - ;
}
}
/* We're done when c->multibulk == 0 */
if ( c - > multibulklen = = 0 ) return C_OK ;
/* Still not ready to process the command */
return C_ERR ;
}
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
/* Perform necessary tasks after a command was executed:
*
* 1. The client is reset unless there are reasons to avoid doing it .
* 2. In the case of master clients , the replication offset is updated .
* 3. Propagate commands we got from our master to replicas down the line . */
2020-09-23 04:16:08 +00:00
void commandProcessed ( client * c , int flags ) {
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
long long prev_offset = c - > reploff ;
if ( c - > flags & CLIENT_MASTER & & ! ( c - > flags & CLIENT_MULTI ) ) {
/* Update the applied replication offset of our master. */
c - > reploff = c - > read_reploff - sdslen ( c - > querybuf ) + c - > qb_pos ;
}
2021-03-25 10:20:27 +02:00
/* Don't reset the client structure for blocked clients, so that the reply
* callback will still be able to access the client argv and argc fields .
* The client will be reset in unblockClient ( ) . */
if ( ! ( c - > flags & CLIENT_BLOCKED ) ) {
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
resetClient ( c ) ;
}
/* If the client is a master we need to compute the difference
* between the applied offset before and after processing the buffer ,
* to understand how much of the replication stream was actually
* applied to the master state : this quantity , and its corresponding
* part of the replication stream , will be propagated to the
* sub - replicas and to the replication backlog . */
if ( c - > flags & CLIENT_MASTER ) {
2020-05-24 01:58:33 -04:00
AeLocker ae ;
ae . arm ( c ) ;
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
long long applied = c - > reploff - prev_offset ;
if ( applied ) {
2020-09-23 04:16:08 +00:00
if ( ! g_pserver - > fActiveReplica & & ( flags & CMD_CALL_PROPAGATE ) )
2020-05-21 22:09:06 -04:00
{
2020-10-23 20:24:01 +00:00
replicationFeedSlavesFromMasterStream ( c - > pending_querybuf , applied ) ;
2020-05-21 22:09:06 -04:00
}
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
sdsrange ( c - > pending_querybuf , applied , - 1 ) ;
}
}
}
2019-04-26 19:29:50 +02:00
/* This function calls processCommand(), but also performs a few sub tasks
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
* for the client that are useful in that context :
2019-04-26 19:29:50 +02:00
*
* 1. It sets the current client to the client ' c ' .
Keep track of meaningful replication offset in replicas too
Now both master and replicas keep track of the last replication offset
that contains meaningful data (ignoring the tailing pings), and both
trim that tail from the replication backlog, and the offset with which
they try to use for psync.
the implication is that if someone missed some pings, or even have
excessive pings that the promoted replica has, it'll still be able to
psync (avoid full sync).
the downside (which was already committed) is that replicas running old
code may fail to psync, since the promoted replica trims pings form it's
backlog.
This commit adds a test that reproduces several cases of promotions and
demotions with stale and non-stale pings
Background:
The mearningful offset on the master was added recently to solve a problem were
the master is left all alone, injecting PINGs into it's backlog when no one is
listening and then gets demoted and tries to replicate from a replica that didn't
have any of the PINGs (or at least not the last ones).
however, consider this case:
master A has two replicas (B and C) replicating directly from it.
there's no traffic at all, and also no network issues, just many pings in the
tail of the backlog. now B gets promoted, A becomes a replica of B, and C
remains a replica of A. when A gets demoted, it trims the pings from its
backlog, and successfully replicate from B. however, C is still aware of
these PINGs, when it'll disconnect and re-connect to A, it'll ask for something
that's not in the backlog anymore (since A trimmed the tail of it's backlog),
and be forced to do a full sync (something it didn't have to do before the
meaningful offset fix).
Besides that, the psync2 test was always failing randomly here and there, it
turns out the reason were PINGs. Investigating it shows the following scenario:
cycle 1: redis #1 is master, and all the rest are direct replicas of #1
cycle 2: redis #2 is promoted to master, #1 is a replica of #2 and #3 is replica of #1
now we see that when #1 is demoted it prints:
17339:S 21 Apr 2020 11:16:38.523 * Using the meaningful offset 3929963 instead of 3929977 to exclude the final PINGs (14 bytes difference)
17339:S 21 Apr 2020 11:16:39.391 * Trying a partial resynchronization (request e2b3f8817735fdfe5fa4626766daa938b61419e5:3929964).
17339:S 21 Apr 2020 11:16:39.392 * Successful partial resynchronization with master.
and when #3 connects to the demoted #2, #2 says:
17339:S 21 Apr 2020 11:16:40.084 * Partial resynchronization not accepted: Requested offset for secondary ID was 3929978, but I can reply up to 3929964
so the issue here is that the meaningful offset feature saved the day for the
demoted master (since it needs to sync from a replica that didn't get the last
ping), but it didn't help one of the other replicas which did get the last ping.
2020-04-23 15:04:42 +03:00
* 2. calls commandProcessed ( ) if the command was handled .
2019-04-26 19:29:50 +02:00
*
* The function returns C_ERR in case the client was freed as a side effect
* of processing the command , otherwise C_OK is returned . */
2019-05-11 02:20:34 -04:00
int processCommandAndResetClient ( client * c , int flags ) {
2019-04-26 19:29:50 +02:00
int deadclient = 0 ;
2021-05-21 05:54:39 +00:00
client * old_client = serverTL - > current_client ;
2019-05-11 02:20:34 -04:00
serverTL - > current_client = c ;
2020-07-10 11:33:47 +03:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
if ( processCommand ( c , flags ) = = C_OK ) {
2020-09-23 04:16:08 +00:00
commandProcessed ( c , flags ) ;
2019-04-26 19:29:50 +02:00
}
2019-05-11 02:20:34 -04:00
if ( serverTL - > current_client = = NULL ) deadclient = 1 ;
2021-03-29 13:34:16 +03:00
/*
* Restore the old client , this is needed because when a script
* times out , we will get into this code from processEventsWhileBlocked .
* Which will cause to set the server . current_client . If not restored
* we will return 1 to our caller which will falsely indicate the client
* is dead and will stop reading from its buffer .
*/
2021-05-21 05:54:39 +00:00
serverTL - > current_client = old_client ;
2020-09-15 23:16:01 -07:00
/* performEvictions may flush slave output buffers. This may
2021-05-19 02:59:48 +00:00
* result in a replica , that may be the active client , to be
2019-04-26 19:29:50 +02:00
* freed . */
return deadclient ? C_ERR : C_OK ;
}
2021-01-07 23:36:54 -08:00
/* This function will execute any fully parsed commands pending on
* the client . Returns C_ERR if the client is no longer valid after executing
* the command , and C_OK for all other cases . */
2021-05-19 02:59:48 +00:00
int processPendingCommandsAndResetClient ( client * c , int flags ) {
2021-01-07 23:36:54 -08:00
if ( c - > flags & CLIENT_PENDING_COMMAND ) {
c - > flags & = ~ CLIENT_PENDING_COMMAND ;
2021-05-19 02:59:48 +00:00
if ( processCommandAndResetClient ( c , flags ) = = C_ERR ) {
2021-01-07 23:36:54 -08:00
return C_ERR ;
}
}
return C_OK ;
}
2019-02-15 14:11:05 -05:00
/* This function is called every time, in the client structure 'c', there is
* more query buffer to process , because we read more data from the socket
* or because a client was blocked and later reactivated , so there could be
* pending query buffer , already representing a full command , to process . */
2019-04-06 00:14:27 -04:00
void processInputBuffer ( client * c , int callFlags ) {
2019-02-20 23:30:21 -05:00
AssertCorrectThread ( c ) ;
2019-02-15 14:11:05 -05:00
/* Keep processing while there is something in the input buffer */
while ( c - > qb_pos < sdslen ( c - > querybuf ) ) {
/* Immediately abort if the client is in the middle of something. */
if ( c - > flags & CLIENT_BLOCKED ) break ;
2019-04-26 19:29:50 +02:00
if ( c - > flags & CLIENT_PENDING_COMMAND ) break ;
2019-02-15 14:11:05 -05:00
2021-03-30 23:30:17 +00:00
if ( c - > flags & CLIENT_EXECUTING_COMMAND ) break ;
2019-02-15 14:11:05 -05:00
/* Don't process input from the master while there is a busy script
2019-10-13 12:29:20 -04:00
* condition on the replica . We want just to accumulate the replication
2019-02-15 14:11:05 -05:00
* stream ( instead of replying - BUSY like we do with other clients ) and
* later resume the processing . */
2019-04-21 14:01:10 -04:00
if ( g_pserver - > lua_timedout & & c - > flags & CLIENT_MASTER ) break ;
2019-02-15 14:11:05 -05:00
/* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is
* written to the client . Make sure to not let the reply grow after
* this flag has been set ( i . e . don ' t process more commands ) .
*
* The same applies for clients we want to terminate ASAP . */
if ( c - > flags & ( CLIENT_CLOSE_AFTER_REPLY | CLIENT_CLOSE_ASAP ) ) break ;
/* Determine request type when unknown. */
if ( ! c - > reqtype ) {
if ( c - > querybuf [ c - > qb_pos ] = = ' * ' ) {
c - > reqtype = PROTO_REQ_MULTIBULK ;
} else {
c - > reqtype = PROTO_REQ_INLINE ;
}
}
if ( c - > reqtype = = PROTO_REQ_INLINE ) {
if ( processInlineBuffer ( c ) ! = C_OK ) break ;
} else if ( c - > reqtype = = PROTO_REQ_MULTIBULK ) {
if ( processMultibulkBuffer ( c ) ! = C_OK ) break ;
} else {
serverPanic ( " Unknown request type " ) ;
}
/* Multibulk processing could see a <= 0 length. */
if ( c - > argc = = 0 ) {
resetClient ( c ) ;
} else {
2021-03-30 23:30:17 +00:00
c - > flags | = CLIENT_EXECUTING_COMMAND ;
2019-04-26 19:29:50 +02:00
/* We are finally ready to execute the command. */
2019-05-11 02:20:34 -04:00
if ( processCommandAndResetClient ( c , callFlags ) = = C_ERR ) {
2019-04-26 19:29:50 +02:00
/* If the client is no longer valid, we avoid exiting this
* loop and trimming the client buffer later . So we return
* ASAP in that case . */
2021-03-30 23:30:17 +00:00
c - > flags & = ~ CLIENT_EXECUTING_COMMAND ;
2019-04-26 19:29:50 +02:00
return ;
2019-02-22 22:09:25 -05:00
}
2021-03-30 23:30:17 +00:00
c - > flags & = ~ CLIENT_EXECUTING_COMMAND ;
2019-02-15 14:11:05 -05:00
}
}
/* Trim to pos */
2019-04-26 19:29:50 +02:00
if ( c - > qb_pos ) {
2019-02-15 14:11:05 -05:00
sdsrange ( c - > querybuf , c - > qb_pos , - 1 ) ;
c - > qb_pos = 0 ;
}
}
2019-09-12 10:56:54 +03:00
void readQueryFromClient ( connection * conn ) {
2020-01-27 02:55:48 -05:00
client * c = ( client * ) connGetPrivateData ( conn ) ;
2020-01-27 18:16:19 -05:00
serverAssert ( conn = = c - > conn ) ;
2019-02-15 14:11:05 -05:00
int nread , readlen ;
size_t qblen ;
2010-06-22 00:07:48 +02:00
2020-01-27 02:55:48 -05:00
serverAssert ( FCorrectThread ( c ) ) ;
2019-02-22 01:24:16 -05:00
AeLocker aelock ;
2019-02-20 01:20:26 -05:00
AssertCorrectThread ( c ) ;
2019-02-22 01:24:16 -05:00
std : : unique_lock < decltype ( c - > lock ) > lock ( c - > lock , std : : defer_lock ) ;
if ( ! lock . try_lock ( ) )
return ; // Process something else while we wait
2019-02-15 14:11:05 -05:00
2020-07-29 01:46:44 -04:00
/* Update total number of reads on server */
2020-09-30 19:47:55 +00:00
g_pserver - > stat_total_reads_processed . fetch_add ( 1 , std : : memory_order_relaxed ) ;
2020-07-29 01:46:44 -04:00
2019-02-15 14:11:05 -05:00
readlen = PROTO_IOBUF_LEN ;
/* If this is a multi bulk request, and we are processing a bulk reply
* that is large enough , try to maximize the probability that the query
* buffer contains exactly the SDS string representing the object , even
* at the risk of requiring more read ( 2 ) calls . This way the function
* processMultiBulkBuffer ( ) can avoid copying buffers to create the
* Redis Object representing the argument . */
if ( c - > reqtype = = PROTO_REQ_MULTIBULK & & c - > multibulklen & & c - > bulklen ! = - 1
& & c - > bulklen > = PROTO_MBULK_BIG_ARG )
{
ssize_t remaining = ( size_t ) ( c - > bulklen + 2 ) - sdslen ( c - > querybuf ) ;
/* Note that the 'remaining' variable may be zero in some edge case,
* for example once we resume a blocked client after CLIENT PAUSE . */
if ( remaining > 0 & & remaining < readlen ) readlen = remaining ;
}
qblen = sdslen ( c - > querybuf ) ;
if ( c - > querybuf_peak < qblen ) c - > querybuf_peak = qblen ;
c - > querybuf = sdsMakeRoomFor ( c - > querybuf , readlen ) ;
2020-01-27 02:55:48 -05:00
2019-09-12 10:56:54 +03:00
nread = connRead ( c - > conn , c - > querybuf + qblen , readlen ) ;
2019-02-15 14:11:05 -05:00
if ( nread = = - 1 ) {
2019-09-12 10:56:54 +03:00
if ( connGetState ( conn ) = = CONN_STATE_CONNECTED ) {
2019-02-15 14:11:05 -05:00
return ;
} else {
2019-09-12 10:56:54 +03:00
serverLog ( LL_VERBOSE , " Reading from client: %s " , connGetLastError ( c - > conn ) ) ;
2020-05-10 23:14:15 -04:00
aelock . arm ( c ) ;
2019-03-31 21:59:50 +02:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return ;
}
} else if ( nread = = 0 ) {
serverLog ( LL_VERBOSE , " Client closed connection " ) ;
2020-05-10 23:14:15 -04:00
aelock . arm ( c ) ;
2019-03-31 21:59:50 +02:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return ;
} else if ( c - > flags & CLIENT_MASTER ) {
/* Append the query buffer to the pending (not applied) buffer
* of the master . We ' ll use this buffer later in order to have a
* copy of the string applied by the last command executed . */
c - > pending_querybuf = sdscatlen ( c - > pending_querybuf ,
c - > querybuf + qblen , nread ) ;
}
sdsIncrLen ( c - > querybuf , nread ) ;
2019-04-21 14:01:10 -04:00
c - > lastinteraction = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
if ( c - > flags & CLIENT_MASTER ) c - > read_reploff + = nread ;
2019-04-21 14:01:10 -04:00
g_pserver - > stat_net_input_bytes + = nread ;
2019-04-21 13:20:45 -04:00
if ( sdslen ( c - > querybuf ) > cserver . client_max_querybuf_len ) {
2019-02-15 14:11:05 -05:00
sds ci = catClientInfoString ( sdsempty ( ) , c ) , bytes = sdsempty ( ) ;
bytes = sdscatrepr ( bytes , c - > querybuf , 64 ) ;
serverLog ( LL_WARNING , " Closing client that reached max query buffer length: %s (qbuf initial bytes: %s) " , ci , bytes ) ;
sdsfree ( ci ) ;
2019-05-11 02:20:34 -04:00
sdsfree ( bytes ) ;
2019-03-31 21:59:50 +02:00
freeClientAsync ( c ) ;
2019-02-15 14:11:05 -05:00
return ;
}
2020-09-07 03:35:46 +00:00
serverTL - > vecclientsProcess . push_back ( c ) ;
2020-09-07 00:49:53 +00:00
}
void processClients ( )
{
2020-07-10 11:33:47 +03:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2021-05-29 01:08:14 +00:00
while ( ! serverTL - > vecclientsProcess . empty ( ) ) {
client * c = serverTL - > vecclientsProcess . front ( ) ;
serverTL - > vecclientsProcess . erase ( serverTL - > vecclientsProcess . begin ( ) ) ;
2020-09-07 00:49:53 +00:00
/* There is more data in the client input buffer, continue parsing it
* in case to check if there is a full command to execute . */
std : : unique_lock < fastlock > ul ( c - > lock ) ;
processInputBuffer ( c , CMD_CALL_FULL ) ;
}
2019-06-16 00:16:36 -04:00
if ( listLength ( serverTL - > clients_pending_asyncwrite ) )
{
ProcessPendingAsyncWrites ( ) ;
}
2020-09-07 00:49:53 +00:00
serverTL - > vecclientsProcess . clear ( ) ;
2019-02-15 14:11:05 -05:00
}
void getClientsMaxBuffers ( unsigned long * longest_output_list ,
unsigned long * biggest_input_buffer ) {
client * c ;
listNode * ln ;
listIter li ;
unsigned long lol = 0 , bib = 0 ;
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > clients , & li ) ;
2019-02-15 14:11:05 -05:00
while ( ( ln = listNext ( & li ) ) ! = NULL ) {
c = ( client * ) listNodeValue ( ln ) ;
if ( listLength ( c - > reply ) > lol ) lol = listLength ( c - > reply ) ;
if ( sdslen ( c - > querybuf ) > bib ) bib = sdslen ( c - > querybuf ) ;
}
* longest_output_list = lol ;
* biggest_input_buffer = bib ;
}
2020-10-28 21:13:44 +02:00
/* A Redis "Address String" is a colon separated ip:port pair.
2019-02-15 14:11:05 -05:00
* For IPv4 it ' s in the form x . y . z . k : port , example : " 127.0.0.1:1234 " .
* For IPv6 addresses we use [ ] around the IP part , like in " [::1]:1234 " .
* For Unix sockets we use path : 0 , like in " /tmp/redis:0 " .
*
2020-10-28 21:13:44 +02:00
* An Address String always fits inside a buffer of NET_ADDR_STR_LEN bytes ,
* including the null term .
2019-02-15 14:11:05 -05:00
*
2020-10-28 21:13:44 +02:00
* On failure the function still populates ' addr ' with the " ?:0 " string in case
* you want to relax error checking or need to display something anyway ( see
* anetFdToString implementation for more info ) . */
void genClientAddrString ( client * client , char * addr ,
size_t addr_len , int fd_to_str_type ) {
2019-02-15 14:11:05 -05:00
if ( client - > flags & CLIENT_UNIX_SOCKET ) {
/* Unix socket client. */
2021-05-19 02:59:48 +00:00
snprintf ( addr , addr_len , " %s:0 " , g_pserver - > unixsocket ) ;
2019-02-15 14:11:05 -05:00
} else {
/* TCP client. */
2020-10-28 21:13:44 +02:00
connFormatFdAddr ( client - > conn , addr , addr_len , fd_to_str_type ) ;
2019-02-15 14:11:05 -05:00
}
}
/* This function returns the client peer id, by creating and caching it
* if client - > peerid is NULL , otherwise returning the cached value .
* The Peer ID never changes during the life of the client , however it
* is expensive to compute . */
char * getClientPeerId ( client * c ) {
2020-10-28 21:13:44 +02:00
char peerid [ NET_ADDR_STR_LEN ] ;
2019-02-15 14:11:05 -05:00
if ( c - > peerid = = NULL ) {
2020-10-28 21:13:44 +02:00
genClientAddrString ( c , peerid , sizeof ( peerid ) , FD_TO_PEER_NAME ) ;
2019-02-15 14:11:05 -05:00
c - > peerid = sdsnew ( peerid ) ;
}
return c - > peerid ;
}
2020-10-28 21:13:44 +02:00
/* This function returns the client bound socket name, by creating and caching
* it if client - > sockname is NULL , otherwise returning the cached value .
* The Socket Name never changes during the life of the client , however it
* is expensive to compute . */
char * getClientSockname ( client * c ) {
char sockname [ NET_ADDR_STR_LEN ] ;
if ( c - > sockname = = NULL ) {
genClientAddrString ( c , sockname , sizeof ( sockname ) , FD_TO_SOCK_NAME ) ;
c - > sockname = sdsnew ( sockname ) ;
}
return c - > sockname ;
}
Squash merging 125 typo/grammar/comment/doc PRs (#7773)
List of squashed commits or PRs
===============================
commit 66801ea
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Jan 13 00:54:31 2020 -0500
typo fix in acl.c
commit 46f55db
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun Sep 6 18:24:11 2020 +0300
Updates a couple of comments
Specifically:
* RM_AutoMemory completed instead of pointing to docs
* Updated link to custom type doc
commit 61a2aa0
Author: xindoo <xindoo@qq.com>
Date: Tue Sep 1 19:24:59 2020 +0800
Correct errors in code comments
commit a5871d1
Author: yz1509 <pro-756@qq.com>
Date: Tue Sep 1 18:36:06 2020 +0800
fix typos in module.c
commit 41eede7
Author: bookug <bookug@qq.com>
Date: Sat Aug 15 01:11:33 2020 +0800
docs: fix typos in comments
commit c303c84
Author: lazy-snail <ws.niu@outlook.com>
Date: Fri Aug 7 11:15:44 2020 +0800
fix spelling in redis.conf
commit 1eb76bf
Author: zhujian <zhujianxyz@gmail.com>
Date: Thu Aug 6 15:22:10 2020 +0800
add a missing 'n' in comment
commit 1530ec2
Author: Daniel Dai <764122422@qq.com>
Date: Mon Jul 27 00:46:35 2020 -0400
fix spelling in tracking.c
commit e517b31
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:32 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit c300eff
Author: Hunter-Chen <huntcool001@gmail.com>
Date: Fri Jul 17 22:33:23 2020 +0800
Update redis.conf
Co-authored-by: Itamar Haber <itamar@redislabs.com>
commit 4c058a8
Author: 陈浩鹏 <chenhaopeng@heytea.com>
Date: Thu Jun 25 19:00:56 2020 +0800
Grammar fix and clarification
commit 5fcaa81
Author: bodong.ybd <bodong.ybd@alibaba-inc.com>
Date: Fri Jun 19 10:09:00 2020 +0800
Fix typos
commit 4caca9a
Author: Pruthvi P <pruthvi@ixigo.com>
Date: Fri May 22 00:33:22 2020 +0530
Fix typo eviciton => eviction
commit b2a25f6
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Sun May 17 12:39:59 2020 -0400
Fix a typo.
commit 12842ae
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun May 3 17:16:59 2020 -0400
fix spelling in redis conf
commit ddba07c
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Sat May 2 23:25:34 2020 +0100
Correct a "conflicts" spelling error.
commit 8fc7bf2
Author: Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Date: Thu Apr 30 10:25:27 2020 +0900
docs: fix EXPIRE_FAST_CYCLE_DURATION to ACTIVE_EXPIRE_CYCLE_FAST_DURATION
commit 9b2b67a
Author: Brad Dunbar <dunbarb2@gmail.com>
Date: Fri Apr 24 11:46:22 2020 -0400
Fix a typo.
commit 0746f10
Author: devilinrust <63737265+devilinrust@users.noreply.github.com>
Date: Thu Apr 16 00:17:53 2020 +0200
Fix typos in server.c
commit 92b588d
Author: benjessop12 <56115861+benjessop12@users.noreply.github.com>
Date: Mon Apr 13 13:43:55 2020 +0100
Fix spelling mistake in lazyfree.c
commit 1da37aa
Merge: 2d4ba28 c90b2a4
Author: hwware <wen.hui.ware@gmail.com>
Date: Thu Mar 5 22:41:31 2020 -0500
Merge remote-tracking branch 'upstream/unstable' into expiretypofix
commit 2d4ba28
Author: hwware <wen.hui.ware@gmail.com>
Date: Mon Mar 2 00:09:40 2020 -0500
fix typo in expire.c
commit 1a746f7
Author: SennoYuki <minakami1yuki@gmail.com>
Date: Thu Feb 27 16:54:32 2020 +0800
fix typo
commit 8599b1a
Author: dongheejeong <donghee950403@gmail.com>
Date: Sun Feb 16 20:31:43 2020 +0000
Fix typo in server.c
commit f38d4e8
Author: hwware <wen.hui.ware@gmail.com>
Date: Sun Feb 2 22:58:38 2020 -0500
fix typo in evict.c
commit fe143fc
Author: Leo Murillo <leonardo.murillo@gmail.com>
Date: Sun Feb 2 01:57:22 2020 -0600
Fix a few typos in redis.conf
commit 1ab4d21
Author: viraja1 <anchan.viraj@gmail.com>
Date: Fri Dec 27 17:15:58 2019 +0530
Fix typo in Latency API docstring
commit ca1f70e
Author: gosth <danxuedexing@qq.com>
Date: Wed Dec 18 15:18:02 2019 +0800
fix typo in sort.c
commit a57c06b
Author: ZYunH <zyunhjob@163.com>
Date: Mon Dec 16 22:28:46 2019 +0800
fix-zset-typo
commit b8c92b5
Author: git-hulk <hulk.website@gmail.com>
Date: Mon Dec 16 15:51:42 2019 +0800
FIX: typo in cluster.c, onformation->information
commit 9dd981c
Author: wujm2007 <jim.wujm@gmail.com>
Date: Mon Dec 16 09:37:52 2019 +0800
Fix typo
commit e132d7a
Author: Sebastien Williams-Wynn <s.williamswynn.mail@gmail.com>
Date: Fri Nov 15 00:14:07 2019 +0000
Minor typo change
commit 47f44d5
Author: happynote3966 <01ssrmikururudevice01@gmail.com>
Date: Mon Nov 11 22:08:48 2019 +0900
fix comment typo in redis-cli.c
commit b8bdb0d
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 18:00:17 2019 +0800
Fix a spelling mistake of comments in defragDictBucketCallback
commit 0def46a
Author: fulei <fulei@kuaishou.com>
Date: Wed Oct 16 13:09:27 2019 +0800
fix some spelling mistakes of comments in defrag.c
commit f3596fd
Author: Phil Rajchgot <tophil@outlook.com>
Date: Sun Oct 13 02:02:32 2019 -0400
Typo and grammar fixes
Redis and its documentation are great -- just wanted to submit a few corrections in the spirit of Hacktoberfest. Thanks for all your work on this project. I use it all the time and it works beautifully.
commit 2b928cd
Author: KangZhiDong <worldkzd@gmail.com>
Date: Sun Sep 1 07:03:11 2019 +0800
fix typos
commit 33aea14
Author: Axlgrep <axlgrep@gmail.com>
Date: Tue Aug 27 11:02:18 2019 +0800
Fixed eviction spelling issues
commit e282a80
Author: Simen Flatby <simen@oms.no>
Date: Tue Aug 20 15:25:51 2019 +0200
Update comments to reflect prop name
In the comments the prop is referenced as replica-validity-factor,
but it is really named cluster-replica-validity-factor.
commit 74d1f9a
Author: Jim Green <jimgreen2013@qq.com>
Date: Tue Aug 20 20:00:31 2019 +0800
fix comment error, the code is ok
commit eea1407
Author: Liao Tonglang <liaotonglang@gmail.com>
Date: Fri May 31 10:16:18 2019 +0800
typo fix
fix cna't to can't
commit 0da553c
Author: KAWACHI Takashi <tkawachi@gmail.com>
Date: Wed Jul 17 00:38:16 2019 +0900
Fix typo
commit 7fc8fb6
Author: Michael Prokop <mika@grml.org>
Date: Tue May 28 17:58:42 2019 +0200
Typo fixes
s/familar/familiar/
s/compatiblity/compatibility/
s/ ot / to /
s/itsef/itself/
commit 5f46c9d
Author: zhumoing <34539422+zhumoing@users.noreply.github.com>
Date: Tue May 21 21:16:50 2019 +0800
typo-fixes
typo-fixes
commit 321dfe1
Author: wxisme <850885154@qq.com>
Date: Sat Mar 16 15:10:55 2019 +0800
typo fix
commit b4fb131
Merge: 267e0e6 4842305
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Fri Feb 8 22:55:45 2019 +0200
Merge branch 'unstable' of antirez/redis into unstable
commit 267e0e6
Author: Nikitas Bastas <nikitasbst@gmail.com>
Date: Wed Jan 30 21:26:04 2019 +0200
Minor typo fix
commit 30544e7
Author: inshal96 <39904558+inshal96@users.noreply.github.com>
Date: Fri Jan 4 16:54:50 2019 +0500
remove an extra 'a' in the comments
commit 337969d
Author: BrotherGao <yangdongheng11@gmail.com>
Date: Sat Dec 29 12:37:29 2018 +0800
fix typo in redis.conf
commit 9f4b121
Merge: 423a030 19d0ece
Author: BrotherGao <yangdongheng@xiaomi.com>
Date: Sat Dec 29 11:41:12 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 423a030
Merge: 42b02b7 0423081
Author: 杨东衡 <yangdongheng@xiaomi.com>
Date: Tue Dec 4 23:56:11 2018 +0800
Merge branch 'unstable' of antirez/redis into unstable
commit 42b02b7
Merge: 8c7dcff efa96f0
Author: Dongheng Yang <yangdongheng11@gmail.com>
Date: Sun Oct 28 15:54:23 2018 +0800
Merge pull request #1 from antirez/unstable
update local data
commit 714b589
Author: Christian <crifei93@gmail.com>
Date: Fri Dec 28 01:17:26 2018 +0100
fix typo "resulution"
commit e23259d
Author: garenchan <1412950785@qq.com>
Date: Wed Dec 26 09:58:35 2018 +0800
fix typo: segfauls -> segfault
commit a9359f8
Author: xjp <jianping_xie@aliyun.com>
Date: Tue Dec 18 17:31:44 2018 +0800
Fixed REDISMODULE_H spell bug
commit a12c3e4
Author: jdiaz <jrd.palacios@gmail.com>
Date: Sat Dec 15 23:39:52 2018 -0600
Fixes hyperloglog hash function comment block description
commit 770eb11
Author: 林上耀 <1210tom@163.com>
Date: Sun Nov 25 17:16:10 2018 +0800
fix typo
commit fd97fbb
Author: Chris Lamb <chris@chris-lamb.co.uk>
Date: Fri Nov 23 17:14:01 2018 +0100
Correct "unsupported" typo.
commit a85522d
Author: Jungnam Lee <jungnam.lee@oracle.com>
Date: Thu Nov 8 23:01:29 2018 +0900
fix typo in test comments
commit ade8007
Author: Arun Kumar <palerdot@users.noreply.github.com>
Date: Tue Oct 23 16:56:35 2018 +0530
Fixed grammatical typo
Fixed typo for word 'dictionary'
commit 869ee39
Author: Hamid Alaei <hamid.a85@gmail.com>
Date: Sun Aug 12 16:40:02 2018 +0430
fix documentations: (ThreadSafeContextStart/Stop -> ThreadSafeContextLock/Unlock), minor typo
commit f89d158
Author: Mayank Jain <mayankjain255@gmail.com>
Date: Tue Jul 31 23:01:21 2018 +0530
Updated README.md with some spelling corrections.
Made correction in spelling of some misspelled words.
commit 892198e
Author: dsomeshwar <someshwar.dhayalan@gmail.com>
Date: Sat Jul 21 23:23:04 2018 +0530
typo fix
commit 8a4d780
Author: Itamar Haber <itamar@redislabs.com>
Date: Mon Apr 30 02:06:52 2018 +0300
Fixes some typos
commit e3acef6
Author: Noah Rosamilia <ivoahivoah@gmail.com>
Date: Sat Mar 3 23:41:21 2018 -0500
Fix typo in /deps/README.md
commit 04442fb
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:32:42 2018 +0800
Fix typo in readSyncBulkPayload() comment.
commit 9f36880
Author: WuYunlong <xzsyeb@126.com>
Date: Sat Mar 3 10:20:37 2018 +0800
replication.c comment: run_id -> replid.
commit f866b4a
Author: Francesco 'makevoid' Canessa <makevoid@gmail.com>
Date: Thu Feb 22 22:01:56 2018 +0000
fix comment typo in server.c
commit 0ebc69b
Author: 줍 <jubee0124@gmail.com>
Date: Mon Feb 12 16:38:48 2018 +0900
Fix typo in redis.conf
Fix `five behaviors` to `eight behaviors` in [this sentence ](antirez/redis@unstable/redis.conf#L564)
commit b50a620
Author: martinbroadhurst <martinbroadhurst@users.noreply.github.com>
Date: Thu Dec 28 12:07:30 2017 +0000
Fix typo in valgrind.sup
commit 7d8f349
Author: Peter Boughton <peter@sorcerersisle.com>
Date: Mon Nov 27 19:52:19 2017 +0000
Update CONTRIBUTING; refer doc updates to redis-doc repo.
commit 02dec7e
Author: Klauswk <klauswk1@hotmail.com>
Date: Tue Oct 24 16:18:38 2017 -0200
Fix typo in comment
commit e1efbc8
Author: chenshi <baiwfg2@gmail.com>
Date: Tue Oct 3 18:26:30 2017 +0800
Correct two spelling errors of comments
commit 93327d8
Author: spacewander <spacewanderlzx@gmail.com>
Date: Wed Sep 13 16:47:24 2017 +0800
Update the comment for OBJ_ENCODING_EMBSTR_SIZE_LIMIT's value
The value of OBJ_ENCODING_EMBSTR_SIZE_LIMIT is 44 now instead of 39.
commit 63d361f
Author: spacewander <spacewanderlzx@gmail.com>
Date: Tue Sep 12 15:06:42 2017 +0800
Fix <prevlen> related doc in ziplist.c
According to the definition of ZIP_BIG_PREVLEN and other related code,
the guard of single byte <prevlen> should be 254 instead of 255.
commit ebe228d
Author: hanael80 <hanael80@gmail.com>
Date: Tue Aug 15 09:09:40 2017 +0900
Fix typo
commit 6b696e6
Author: Matt Robenolt <matt@ydekproductions.com>
Date: Mon Aug 14 14:50:47 2017 -0700
Fix typo in LATENCY DOCTOR output
commit a2ec6ae
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 15 14:15:16 2017 +0800
Fix a typo: form => from
commit 3ab7699
Author: caosiyang <caosiyang@qiyi.com>
Date: Thu Aug 10 18:40:33 2017 +0800
Fix a typo: replicationFeedSlavesFromMaster() => replicationFeedSlavesFromMasterStream()
commit 72d43ef
Author: caosiyang <caosiyang@qiyi.com>
Date: Tue Aug 8 15:57:25 2017 +0800
fix a typo: servewr => server
commit 707c958
Author: Bo Cai <charpty@gmail.com>
Date: Wed Jul 26 21:49:42 2017 +0800
redis-cli.c typo: conut -> count.
Signed-off-by: Bo Cai <charpty@gmail.com>
commit b9385b2
Author: JackDrogon <jack.xsuperman@gmail.com>
Date: Fri Jun 30 14:22:31 2017 +0800
Fix some spell problems
commit 20d9230
Author: akosel <aaronjkosel@gmail.com>
Date: Sun Jun 4 19:35:13 2017 -0500
Fix typo
commit b167bfc
Author: Krzysiek Witkowicz <krzysiekwitkowicz@gmail.com>
Date: Mon May 22 21:32:27 2017 +0100
Fix #4008 small typo in comment
commit 2b78ac8
Author: Jake Clarkson <jacobwclarkson@gmail.com>
Date: Wed Apr 26 15:49:50 2017 +0100
Correct typo in tests/unit/hyperloglog.tcl
commit b0f1cdb
Author: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Wed Apr 19 14:25:18 2017 -0700
Fix typo
commit a90b0f9
Author: charsyam <charsyam@naver.com>
Date: Thu Mar 16 18:19:53 2017 +0900
fix typos
fix typos
fix typos
commit 8430a79
Author: Richard Hart <richardhart92@gmail.com>
Date: Mon Mar 13 22:17:41 2017 -0400
Fixed log message typo in listenToPort.
commit 481a1c2
Author: Vinod Kumar <kumar003vinod@gmail.com>
Date: Sun Jan 15 23:04:51 2017 +0530
src/db.c: Correct "save" -> "safe" typo
commit 586b4d3
Author: wangshaonan <wshn13@gmail.com>
Date: Wed Dec 21 20:28:27 2016 +0800
Fix typo they->the in helloworld.c
commit c1c4b5e
Author: Jenner <hypxm@qq.com>
Date: Mon Dec 19 16:39:46 2016 +0800
typo error
commit 1ee1a3f
Author: tielei <43289893@qq.com>
Date: Mon Jul 18 13:52:25 2016 +0800
fix some comments
commit 11a41fb
Author: Otto Kekäläinen <otto@seravo.fi>
Date: Sun Jul 3 10:23:55 2016 +0100
Fix spelling in documentation and comments
commit 5fb5d82
Author: francischan <f1ancis621@gmail.com>
Date: Tue Jun 28 00:19:33 2016 +0800
Fix outdated comments about redis.c file.
It should now refer to server.c file.
commit 6b254bc
Author: lmatt-bit <lmatt123n@gmail.com>
Date: Thu Apr 21 21:45:58 2016 +0800
Refine the comment of dictRehashMilliseconds func
SLAVECONF->REPLCONF in comment - by andyli029
commit ee9869f
Author: clark.kang <charsyam@naver.com>
Date: Tue Mar 22 11:09:51 2016 +0900
fix typos
commit f7b3b11
Author: Harisankar H <harisankarh@gmail.com>
Date: Wed Mar 9 11:49:42 2016 +0530
Typo correction: "faield" --> "failed"
Typo correction: "faield" --> "failed"
commit 3fd40fc
Author: Itamar Haber <itamar@redislabs.com>
Date: Thu Feb 25 10:31:51 2016 +0200
Fixes a typo in comments
commit 621c160
Author: Prayag Verma <prayag.verma@gmail.com>
Date: Mon Feb 1 12:36:20 2016 +0530
Fix typo in Readme.md
Spelling mistakes -
`eviciton` > `eviction`
`familar` > `familiar`
commit d7d07d6
Author: WonCheol Lee <toctoc21c@gmail.com>
Date: Wed Dec 30 15:11:34 2015 +0900
Typo fixed
commit a4dade7
Author: Felix Bünemann <buenemann@louis.info>
Date: Mon Dec 28 11:02:55 2015 +0100
[ci skip] Improve supervised upstart config docs
This mentions that "expect stop" is required for supervised upstart
to work correctly. See http://upstart.ubuntu.com/cookbook/#expect-stop
for an explanation.
commit d9caba9
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:30:03 2015 +1100
README: Remove trailing whitespace
commit 72d42e5
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:32 2015 +1100
README: Fix typo. th => the
commit dd6e957
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:29:20 2015 +1100
README: Fix typo. familar => familiar
commit 3a12b23
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:28:54 2015 +1100
README: Fix typo. eviciton => eviction
commit 2d1d03b
Author: daurnimator <quae@daurnimator.com>
Date: Mon Dec 21 18:21:45 2015 +1100
README: Fix typo. sever => server
commit 3973b06
Author: Itamar Haber <itamar@garantiadata.com>
Date: Sat Dec 19 17:01:20 2015 +0200
Typo fix
commit 4f2e460
Author: Steve Gao <fu@2token.com>
Date: Fri Dec 4 10:22:05 2015 +0800
Update README - fix typos
commit b21667c
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:48:37 2015 +0800
delete redundancy color judge in sdscatcolor
commit 88894c7
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 22:14:42 2015 +0800
the example output shoule be HelloWorld
commit 2763470
Author: binyan <binbin.yan@nokia.com>
Date: Wed Dec 2 17:41:39 2015 +0800
modify error word keyevente
Signed-off-by: binyan <binbin.yan@nokia.com>
commit 0847b3d
Author: Bruno Martins <bscmartins@gmail.com>
Date: Wed Nov 4 11:37:01 2015 +0000
typo
commit bbb9e9e
Author: dawedawe <dawedawe@gmx.de>
Date: Fri Mar 27 00:46:41 2015 +0100
typo: zimap -> zipmap
commit 5ed297e
Author: Axel Advento <badwolf.bloodseeker.rev@gmail.com>
Date: Tue Mar 3 15:58:29 2015 +0800
Fix 'salve' typos to 'slave'
commit edec9d6
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Wed Jun 12 14:12:47 2019 +0200
Update README.md
Co-Authored-By: Qix <Qix-@users.noreply.github.com>
commit 692a7af
Author: LudwikJaniuk <ludvig.janiuk@gmail.com>
Date: Tue May 28 14:32:04 2019 +0200
grammar
commit d962b0a
Author: Nick Frost <nickfrostatx@gmail.com>
Date: Wed Jul 20 15:17:12 2016 -0700
Minor grammar fix
commit 24fff01aaccaf5956973ada8c50ceb1462e211c6 (typos)
Author: Chad Miller <chadm@squareup.com>
Date: Tue Sep 8 13:46:11 2020 -0400
Fix faulty comment about operation of unlink()
commit 3cd5c1f3326c52aa552ada7ec797c6bb16452355
Author: Kevin <kevin.xgr@gmail.com>
Date: Wed Nov 20 00:13:50 2019 +0800
Fix typo in server.c.
From a83af59 Mon Sep 17 00:00:00 2001
From: wuwo <wuwo@wacai.com>
Date: Fri, 17 Mar 2017 20:37:45 +0800
Subject: [PATCH] falure to failure
From c961896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B7=A6=E6=87=B6?= <veficos@gmail.com>
Date: Sat, 27 May 2017 15:33:04 +0800
Subject: [PATCH] fix typo
From e600ef2 Mon Sep 17 00:00:00 2001
From: "rui.zou" <rui.zou@yunify.com>
Date: Sat, 30 Sep 2017 12:38:15 +0800
Subject: [PATCH] fix a typo
From c7d07fa Mon Sep 17 00:00:00 2001
From: Alexandre Perrin <alex@kaworu.ch>
Date: Thu, 16 Aug 2018 10:35:31 +0200
Subject: [PATCH] deps README.md typo
From b25cb67 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 10:55:37 +0300
Subject: [PATCH 1/2] fix typos in header
From ad28ca6 Mon Sep 17 00:00:00 2001
From: Guy Korland <gkorland@gmail.com>
Date: Wed, 26 Sep 2018 11:02:36 +0300
Subject: [PATCH 2/2] fix typos
commit 34924cdedd8552466fc22c1168d49236cb7ee915
Author: Adrian Lynch <adi_ady_ade@hotmail.com>
Date: Sat Apr 4 21:59:15 2015 +0100
Typos fixed
commit fd2a1e7
Author: Jan <jsteemann@users.noreply.github.com>
Date: Sat Oct 27 19:13:01 2018 +0200
Fix typos
Fix typos
commit e14e47c1a234b53b0e103c5f6a1c61481cbcbb02
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:30:07 2019 -0500
Fix multiple misspellings of "following"
commit 79b948ce2dac6b453fe80995abbcaac04c213d5a
Author: Andy Lester <andy@petdance.com>
Date: Fri Aug 2 22:24:28 2019 -0500
Fix misspelling of create-cluster
commit 1fffde52666dc99ab35efbd31071a4c008cb5a71
Author: Andy Lester <andy@petdance.com>
Date: Wed Jul 31 17:57:56 2019 -0500
Fix typos
commit 204c9ba9651e9e05fd73936b452b9a30be456cfe
Author: Xiaobo Zhu <xiaobo.zhu@shopee.com>
Date: Tue Aug 13 22:19:25 2019 +0800
fix typos
Squashed commit of the following:
commit 1d9aaf8
Author: danmedani <danmedani@gmail.com>
Date: Sun Aug 2 11:40:26 2015 -0700
README typo fix.
Squashed commit of the following:
commit 32bfa7c
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Jul 6 21:15:08 2015 +0200
Fixed grammer
Squashed commit of the following:
commit b24f69c
Author: Sisir Koppaka <sisir.koppaka@gmail.com>
Date: Mon Mar 2 22:38:45 2015 -0500
utils/hashtable/rehashing.c: Fix typos
Squashed commit of the following:
commit 4e04082
Author: Erik Dubbelboer <erik@dubbelboer.com>
Date: Mon Mar 23 08:22:21 2015 +0000
Small config file documentation improvements
Squashed commit of the following:
commit acb8773
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:52:48 2015 -0700
Typo and grammar fixes in readme
commit 2eb75b6
Author: ctd1500 <ctd1500@gmail.com>
Date: Fri May 8 01:36:18 2015 -0700
fixed redis.conf comment
Squashed commit of the following:
commit a8249a2
Author: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri Dec 11 11:39:52 2015 +0530
Revise correction of typos.
Squashed commit of the following:
commit 3c02028
Author: zhaojun11 <zhaojun11@jd.com>
Date: Wed Jan 17 19:05:28 2018 +0800
Fix typos include two code typos in cluster.c and latency.c
Squashed commit of the following:
commit 9dba47c
Author: q191201771 <191201771@qq.com>
Date: Sat Jan 4 11:31:04 2020 +0800
fix function listCreate comment in adlist.c
Update src/server.c
commit 2c7c2cb536e78dd211b1ac6f7bda00f0f54faaeb
Author: charpty <charpty@gmail.com>
Date: Tue May 1 23:16:59 2018 +0800
server.c typo: modules system dictionary type comment
Signed-off-by: charpty <charpty@gmail.com>
commit a8395323fb63cb59cb3591cb0f0c8edb7c29a680
Author: Itamar Haber <itamar@redislabs.com>
Date: Sun May 6 00:25:18 2018 +0300
Updates test_helper.tcl's help with undocumented options
Specifically:
* Host
* Port
* Client
commit bde6f9ced15755cd6407b4af7d601b030f36d60b
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 15:19:19 2018 +0800
fix comments in deps files
commit 3172474ba991532ab799ee1873439f3402412331
Author: wxisme <850885154@qq.com>
Date: Wed Aug 8 14:33:49 2018 +0800
fix some comments
commit 01b6f2b6858b5cf2ce4ad5092d2c746e755f53f0
Author: Thor Juhasz <thor@juhasz.pro>
Date: Sun Nov 18 14:37:41 2018 +0100
Minor fixes to comments
Found some parts a little unclear on a first read, which prompted me to have a better look at the file and fix some minor things I noticed.
Fixing minor typos and grammar. There are no changes to configuration options.
These changes are only meant to help the user better understand the explanations to the various configuration options
(cherry picked from commit 285ef446b05e09013556e7a490677494a9b4bb3e)
2020-09-10 13:43:38 +03:00
/* Concatenate a string representing the state of a client in a human
2019-02-15 14:11:05 -05:00
* readable format , into the sds string ' s ' . */
sds catClientInfoString ( sds s , client * client ) {
2019-09-12 10:56:54 +03:00
char flags [ 16 ] , events [ 3 ] , conninfo [ CONN_INFO_LEN ] , * p ;
2019-02-15 14:11:05 -05:00
p = flags ;
if ( client - > flags & CLIENT_SLAVE ) {
if ( client - > flags & CLIENT_MONITOR )
* p + + = ' O ' ;
else
* p + + = ' S ' ;
}
if ( client - > flags & CLIENT_MASTER ) * p + + = ' M ' ;
if ( client - > flags & CLIENT_PUBSUB ) * p + + = ' P ' ;
if ( client - > flags & CLIENT_MULTI ) * p + + = ' x ' ;
if ( client - > flags & CLIENT_BLOCKED ) * p + + = ' b ' ;
2019-06-29 20:08:41 -04:00
if ( client - > flags & CLIENT_TRACKING ) * p + + = ' t ' ;
2019-07-03 19:16:20 +02:00
if ( client - > flags & CLIENT_TRACKING_BROKEN_REDIR ) * p + + = ' R ' ;
2020-11-11 01:22:17 -05:00
if ( client - > flags & CLIENT_TRACKING_BCAST ) * p + + = ' B ' ;
2019-02-15 14:11:05 -05:00
if ( client - > flags & CLIENT_DIRTY_CAS ) * p + + = ' d ' ;
if ( client - > flags & CLIENT_CLOSE_AFTER_REPLY ) * p + + = ' c ' ;
if ( client - > flags & CLIENT_UNBLOCKED ) * p + + = ' u ' ;
if ( client - > flags & CLIENT_CLOSE_ASAP ) * p + + = ' A ' ;
if ( client - > flags & CLIENT_UNIX_SOCKET ) * p + + = ' U ' ;
if ( client - > flags & CLIENT_READONLY ) * p + + = ' r ' ;
if ( p = = flags ) * p + + = ' N ' ;
* p + + = ' \0 ' ;
p = events ;
2019-09-12 10:56:54 +03:00
if ( client - > conn ) {
if ( connHasReadHandler ( client - > conn ) ) * p + + = ' r ' ;
if ( connHasWriteHandler ( client - > conn ) ) * p + + = ' w ' ;
}
2019-02-15 14:11:05 -05:00
* p = ' \0 ' ;
2020-10-05 11:15:36 +03:00
/* Compute the total memory consumed by this client. */
size_t obufmem = getClientOutputBufferMemoryUsage ( client ) ;
size_t total_mem = obufmem ;
total_mem + = zmalloc_size ( client ) ; /* includes client->buf */
total_mem + = sdsZmallocSize ( client - > querybuf ) ;
/* For efficiency (less work keeping track of the argv memory), it doesn't include the used memory
* i . e . unused sds space and internal fragmentation , just the string length . but this is enough to
* spot problematic clients . */
total_mem + = client - > argv_len_sum ;
if ( client - > argv )
total_mem + = zmalloc_size ( client - > argv ) ;
2019-02-15 14:11:05 -05:00
return sdscatfmt ( s ,
2020-11-11 01:22:17 -05:00
" id=%U addr=%s laddr=%s %s name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U argv-mem=%U obl=%U oll=%U omem=%U tot-mem=%U events=%s cmd=%s user=%s redir=%I " ,
2019-02-15 14:11:05 -05:00
( unsigned long long ) client - > id ,
getClientPeerId ( client ) ,
2020-10-28 21:13:44 +02:00
getClientSockname ( client ) ,
2019-09-12 10:56:54 +03:00
connGetInfo ( client - > conn , conninfo , sizeof ( conninfo ) ) ,
2020-01-27 02:55:48 -05:00
client - > name ? ( char * ) szFromObj ( client - > name ) : " " ,
2019-04-21 14:01:10 -04:00
( long long ) ( g_pserver - > unixtime - client - > ctime ) ,
( long long ) ( g_pserver - > unixtime - client - > lastinteraction ) ,
2019-02-15 14:11:05 -05:00
flags ,
client - > db - > id ,
( int ) dictSize ( client - > pubsub_channels ) ,
( int ) listLength ( client - > pubsub_patterns ) ,
( client - > flags & CLIENT_MULTI ) ? client - > mstate . count : - 1 ,
( unsigned long long ) sdslen ( client - > querybuf ) ,
( unsigned long long ) sdsavail ( client - > querybuf ) ,
2020-10-05 11:15:36 +03:00
( unsigned long long ) client - > argv_len_sum ,
2019-02-15 14:11:05 -05:00
( unsigned long long ) client - > bufpos ,
( unsigned long long ) listLength ( client - > reply ) ,
2020-10-05 11:15:36 +03:00
( unsigned long long ) obufmem , /* should not include client->buf since we want to see 0 for static clients. */
( unsigned long long ) total_mem ,
2019-02-15 14:11:05 -05:00
events ,
2020-01-27 18:16:19 -05:00
client - > lastcmd ? client - > lastcmd - > name : " NULL " ,
2020-11-11 01:22:17 -05:00
client - > user ? client - > user - > name : " (superuser) " ,
( client - > flags & CLIENT_TRACKING ) ? ( long long ) client - > client_tracking_redirection : - 1 ) ;
2019-02-15 14:11:05 -05:00
}
sds getAllClientsInfoString ( int type ) {
listNode * ln ;
listIter li ;
client * client ;
2019-04-21 14:01:10 -04:00
sds o = sdsnewlen ( SDS_NOINIT , 200 * listLength ( g_pserver - > clients ) ) ;
2019-02-15 14:11:05 -05:00
sdsclear ( o ) ;
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > clients , & li ) ;
2019-02-15 14:11:05 -05:00
while ( ( ln = listNext ( & li ) ) ! = NULL ) {
client = reinterpret_cast < struct client * > ( listNodeValue ( ln ) ) ;
2019-07-18 15:49:12 -04:00
std : : unique_lock < decltype ( client - > lock ) > lock ( client - > lock ) ;
2021-05-26 01:18:47 +00:00
if ( client - > flags & CLIENT_CLOSE_ASAP ) continue ;
2019-02-15 14:11:05 -05:00
if ( type ! = - 1 & & getClientType ( client ) ! = type ) continue ;
o = catClientInfoString ( o , client ) ;
o = sdscatlen ( o , " \n " , 1 ) ;
}
return o ;
}
2019-02-25 16:51:49 +01:00
/* This function implements CLIENT SETNAME, including replying to the
* user with an error if the charset is wrong ( in that case C_ERR is
* returned ) . If the function succeeeded C_OK is returned , and it ' s up
* to the caller to send a reply if needed .
*
* Setting an empty string as name has the effect of unsetting the
* currently set name : the client will remain unnamed .
*
* This function is also used to implement the HELLO SETNAME option . */
int clientSetNameOrReply ( client * c , robj * name ) {
2019-03-02 18:07:18 -05:00
int len = sdslen ( ( sds ) ptrFromObj ( name ) ) ;
char * p = ( char * ) ptrFromObj ( name ) ;
2019-02-25 16:51:49 +01:00
/* Setting the client name to an empty string actually removes
* the current name . */
if ( len = = 0 ) {
if ( c - > name ) decrRefCount ( c - > name ) ;
c - > name = NULL ;
return C_OK ;
}
/* Otherwise check if the charset is ok. We need to do this otherwise
* CLIENT LIST format will break . You should always be able to
* split by space to get the different fields . */
for ( int j = 0 ; j < len ; j + + ) {
if ( p [ j ] < ' ! ' | | p [ j ] > ' ~ ' ) { /* ASCII is assumed. */
addReplyError ( c ,
" Client names cannot contain spaces, "
" newlines or special characters. " ) ;
return C_ERR ;
}
}
if ( c - > name ) decrRefCount ( c - > name ) ;
c - > name = name ;
incrRefCount ( name ) ;
return C_OK ;
}
2020-11-05 10:51:26 +02:00
/* Reset the client state to resemble a newly connected client.
*/
void resetCommand ( client * c ) {
listNode * ln ;
/* MONITOR clients are also marked with CLIENT_SLAVE, we need to
* distinguish between the two .
*/
if ( c - > flags & CLIENT_MONITOR ) {
2021-05-19 02:59:48 +00:00
ln = listSearchKey ( g_pserver - > monitors , c ) ;
2020-11-05 10:51:26 +02:00
serverAssert ( ln ! = NULL ) ;
2021-05-19 02:59:48 +00:00
listDelNode ( g_pserver - > monitors , ln ) ;
2020-11-05 10:51:26 +02:00
c - > flags & = ~ ( CLIENT_MONITOR | CLIENT_SLAVE ) ;
}
if ( c - > flags & ( CLIENT_SLAVE | CLIENT_MASTER | CLIENT_MODULE ) ) {
addReplyError ( c , " can only reset normal client connections " ) ;
return ;
}
if ( c - > flags & CLIENT_TRACKING ) disableTracking ( c ) ;
selectDb ( c , 0 ) ;
c - > resp = 2 ;
clientSetDefaultAuth ( c ) ;
moduleNotifyUserChanged ( c ) ;
discardTransaction ( c ) ;
pubsubUnsubscribeAllChannels ( c , 0 ) ;
pubsubUnsubscribeAllPatterns ( c , 0 ) ;
if ( c - > name ) {
decrRefCount ( c - > name ) ;
c - > name = NULL ;
}
/* Selectively clear state flags not covered above */
c - > flags & = ~ ( CLIENT_ASKING | CLIENT_READONLY | CLIENT_PUBSUB |
CLIENT_REPLY_OFF | CLIENT_REPLY_SKIP_NEXT ) ;
addReplyStatus ( c , " RESET " ) ;
}
2019-02-15 14:11:05 -05:00
void clientCommand ( client * c ) {
listNode * ln ;
listIter li ;
if ( c - > argc = = 2 & & ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 1 ] ) , " help " ) ) {
const char * help [ ] = {
2021-01-04 17:02:57 +02:00
" CACHING (YES|NO) " ,
" Enable/disable tracking of the keys for next command in OPTIN/OPTOUT modes. " ,
" GETREDIR " ,
" Return the client ID we are redirecting to when tracking is enabled. " ,
" GETNAME " ,
" Return the name of the current connection. " ,
" ID " ,
" Return the ID of the current connection. " ,
" INFO " ,
" Return information about the current client connection. " ,
" KILL <ip:port> " ,
" Kill connection made from <ip:port>. " ,
" KILL <option> <value> [<option> <value> [...]] " ,
" Kill connections. Options are: " ,
2021-01-28 20:49:46 +02:00
" * ADDR (<ip:port>|<unixsocket>:0) " ,
" Kill connections made from the specified address " ,
" * LADDR (<ip:port>|<unixsocket>:0) " ,
" Kill connections made to specified local address " ,
2021-01-04 17:02:57 +02:00
" * TYPE (normal|master|replica|pubsub) " ,
" Kill connections by type. " ,
" * USER <username> " ,
" Kill connections authenticated by <username>. " ,
" * SKIPME (YES|NO) " ,
" Skip killing current connection (default: yes). " ,
" LIST [options ...] " ,
" Return information about client connections. Options: " ,
" * TYPE (NORMAL|MASTER|REPLICA|PUBSUB) " ,
" Return clients of specified type. " ,
2021-01-07 23:36:54 -08:00
" UNPAUSE " ,
" Stop the current client pause, resuming traffic. " ,
" PAUSE <timeout> [WRITE|ALL] " ,
" Suspend all, or just write, clients for <timout> milliseconds. " ,
2021-01-04 17:02:57 +02:00
" REPLY (ON|OFF|SKIP) " ,
" Control the replies sent to the current connection. " ,
" SETNAME <name> " ,
" Assign the name <name> to the current connection. " ,
" UNBLOCK <clientid> [TIMEOUT|ERROR] " ,
" Unblock the specified blocked client. " ,
" TRACKING (ON|OFF) [REDIRECT <id>] [BCAST] [PREFIX <prefix> [...]] " ,
" [OPTIN] [OPTOUT] " ,
" Control server assisted client side caching. " ,
" TRACKINGINFO " ,
" Report tracking status for the current connection. " ,
2019-02-15 14:11:05 -05:00
NULL
} ;
addReplyHelp ( c , help ) ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 1 ] ) , " id " ) & & c - > argc = = 2 ) {
/* CLIENT ID */
addReplyLongLong ( c , c - > id ) ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " info " ) & & c - > argc = = 2 ) {
2020-12-07 14:24:05 +02:00
/* CLIENT INFO */
sds o = catClientInfoString ( sdsempty ( ) , c ) ;
o = sdscatlen ( o , " \n " , 1 ) ;
addReplyVerbatim ( c , o , sdslen ( o ) , " txt " ) ;
sdsfree ( o ) ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " list " ) ) {
2019-02-15 14:11:05 -05:00
/* CLIENT LIST */
int type = - 1 ;
2020-12-07 14:24:05 +02:00
sds o = NULL ;
2019-02-15 14:11:05 -05:00
if ( c - > argc = = 4 & & ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 2 ] ) , " type " ) ) {
type = getClientTypeByName ( ( char * ) ptrFromObj ( c - > argv [ 3 ] ) ) ;
if ( type = = - 1 ) {
addReplyErrorFormat ( c , " Unknown client type '%s' " ,
( char * ) ptrFromObj ( c - > argv [ 3 ] ) ) ;
return ;
2020-12-07 14:24:05 +02:00
}
2021-05-19 02:59:48 +00:00
} else if ( c - > argc > 3 & & ! strcasecmp ( szFromObj ( c - > argv [ 2 ] ) , " id " ) ) {
2020-12-07 14:24:05 +02:00
int j ;
o = sdsempty ( ) ;
for ( j = 3 ; j < c - > argc ; j + + ) {
long long cid ;
if ( getLongLongFromObjectOrReply ( c , c - > argv [ j ] , & cid ,
" Invalid client ID " ) ) {
sdsfree ( o ) ;
return ;
}
client * cl = lookupClientByID ( cid ) ;
if ( cl ) {
o = catClientInfoString ( o , cl ) ;
o = sdscatlen ( o , " \n " , 1 ) ;
}
}
2019-02-15 14:11:05 -05:00
} else if ( c - > argc ! = 2 ) {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
2020-12-07 14:24:05 +02:00
if ( ! o )
o = getAllClientsInfoString ( type ) ;
2019-09-18 18:52:13 +02:00
addReplyVerbatim ( c , o , sdslen ( o ) , " txt " ) ;
2019-02-15 14:11:05 -05:00
sdsfree ( o ) ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 1 ] ) , " reply " ) & & c - > argc = = 3 ) {
/* CLIENT REPLY ON|OFF|SKIP */
if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 2 ] ) , " on " ) ) {
c - > flags & = ~ ( CLIENT_REPLY_SKIP | CLIENT_REPLY_OFF ) ;
addReply ( c , shared . ok ) ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 2 ] ) , " off " ) ) {
c - > flags | = CLIENT_REPLY_OFF ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 2 ] ) , " skip " ) ) {
if ( ! ( c - > flags & CLIENT_REPLY_OFF ) )
c - > flags | = CLIENT_REPLY_SKIP_NEXT ;
} else {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 1 ] ) , " kill " ) ) {
/* CLIENT KILL <ip:port>
* CLIENT KILL < option > [ value ] . . . < option > [ value ] */
char * addr = NULL ;
2020-10-28 21:13:44 +02:00
char * laddr = NULL ;
2020-04-30 09:58:06 +02:00
user * user = NULL ;
2019-02-15 14:11:05 -05:00
int type = - 1 ;
uint64_t id = 0 ;
int skipme = 1 ;
int killed = 0 , close_this_client = 0 ;
if ( c - > argc = = 3 ) {
/* Old style syntax: CLIENT KILL <addr> */
addr = ( char * ) ptrFromObj ( c - > argv [ 2 ] ) ;
skipme = 0 ; /* With the old form, you can kill yourself. */
} else if ( c - > argc > 3 ) {
int i = 2 ; /* Next option index. */
/* New style syntax: parse options. */
while ( i < c - > argc ) {
int moreargs = c - > argc > i + 1 ;
if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ i ] ) , " id " ) & & moreargs ) {
long long tmp ;
if ( getLongLongFromObjectOrReply ( c , c - > argv [ i + 1 ] , & tmp , NULL )
! = C_OK ) return ;
id = tmp ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ i ] ) , " type " ) & & moreargs ) {
type = getClientTypeByName ( ( const char * ) ptrFromObj ( c - > argv [ i + 1 ] ) ) ;
if ( type = = - 1 ) {
addReplyErrorFormat ( c , " Unknown client type '%s' " ,
( char * ) ptrFromObj ( c - > argv [ i + 1 ] ) ) ;
return ;
}
2020-05-21 22:09:06 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " addr " ) & & moreargs ) {
addr = szFromObj ( c - > argv [ i + 1 ] ) ;
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " user " ) & & moreargs ) {
user = ACLGetUserByName ( szFromObj ( c - > argv [ i + 1 ] ) ,
sdslen ( szFromObj ( c - > argv [ i + 1 ] ) ) ) ;
2020-04-30 09:58:06 +02:00
if ( user = = NULL ) {
addReplyErrorFormat ( c , " No such user '%s' " ,
2020-05-21 22:09:06 -04:00
szFromObj ( c - > argv [ i + 1 ] ) ) ;
2020-04-30 09:58:06 +02:00
return ;
}
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " addr " ) & & moreargs ) {
addr = szFromObj ( c - > argv [ i + 1 ] ) ;
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " laddr " ) & & moreargs ) {
laddr = szFromObj ( c - > argv [ i + 1 ] ) ;
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " user " ) & & moreargs ) {
user = ACLGetUserByName ( szFromObj ( c - > argv [ i + 1 ] ) ,
sdslen ( szFromObj ( c - > argv [ i + 1 ] ) ) ) ;
if ( user = = NULL ) {
addReplyErrorFormat ( c , " No such user '%s' " ,
( char * ) szFromObj ( c - > argv [ i + 1 ] ) ) ;
return ;
}
2020-05-21 22:09:06 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ i ] ) , " skipme " ) & & moreargs ) {
if ( ! strcasecmp ( szFromObj ( c - > argv [ i + 1 ] ) , " yes " ) ) {
2019-02-15 14:11:05 -05:00
skipme = 1 ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ i + 1 ] ) , " no " ) ) {
skipme = 0 ;
} else {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
} else {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
i + = 2 ;
}
} else {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-02-15 14:11:05 -05:00
return ;
}
/* Iterate clients killing all the matching clients. */
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > clients , & li ) ;
2019-02-15 14:11:05 -05:00
while ( ( ln = listNext ( & li ) ) ! = NULL ) {
2020-04-14 20:09:53 -04:00
client * client = ( struct client * ) listNodeValue ( ln ) ;
2019-02-15 14:11:05 -05:00
if ( addr & & strcmp ( getClientPeerId ( client ) , addr ) ! = 0 ) continue ;
2020-10-28 21:13:44 +02:00
if ( laddr & & strcmp ( getClientSockname ( client ) , laddr ) ! = 0 ) continue ;
2019-02-15 14:11:05 -05:00
if ( type ! = - 1 & & getClientType ( client ) ! = type ) continue ;
if ( id ! = 0 & & client - > id ! = id ) continue ;
2020-04-30 09:58:06 +02:00
if ( user & & client - > user ! = user ) continue ;
2019-02-15 14:11:05 -05:00
if ( c = = client & & skipme ) continue ;
/* Kill it. */
if ( c = = client ) {
close_this_client = 1 ;
} else {
2019-04-03 00:11:34 -04:00
if ( FCorrectThread ( client ) )
2019-11-14 19:49:32 -05:00
{
2019-04-03 00:11:34 -04:00
freeClient ( client ) ;
2019-11-14 19:49:32 -05:00
}
2019-04-03 00:11:34 -04:00
else
2019-11-14 19:49:32 -05:00
{
int iel = client - > iel ;
2019-04-03 00:11:34 -04:00
freeClientAsync ( client ) ;
2020-02-11 01:00:21 -05:00
aePostFunction ( g_pserver - > rgthreadvar [ client - > iel ] . el , [ iel ] { // note: failure is OK
2019-11-14 19:49:32 -05:00
freeClientsInAsyncFreeQueue ( iel ) ;
} ) ;
}
2019-02-15 14:11:05 -05:00
}
killed + + ;
}
/* Reply according to old/new format. */
if ( c - > argc = = 3 ) {
if ( killed = = 0 )
addReplyError ( c , " No such client " ) ;
else
addReply ( c , shared . ok ) ;
} else {
addReplyLongLong ( c , killed ) ;
}
/* If this client has to be closed, flag it as CLOSE_AFTER_REPLY
* only after we queued the reply to its output buffers . */
if ( close_this_client ) c - > flags | = CLIENT_CLOSE_AFTER_REPLY ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 1 ] ) , " unblock " ) & & ( c - > argc = = 3 | |
c - > argc = = 4 ) )
{
/* CLIENT UNBLOCK <id> [timeout|error] */
long long id ;
int unblock_error = 0 ;
if ( c - > argc = = 4 ) {
if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 3 ] ) , " timeout " ) ) {
unblock_error = 0 ;
} else if ( ! strcasecmp ( ( const char * ) ptrFromObj ( c - > argv [ 3 ] ) , " error " ) ) {
unblock_error = 1 ;
} else {
addReplyError ( c ,
" CLIENT UNBLOCK reason should be TIMEOUT or ERROR " ) ;
return ;
}
}
if ( getLongLongFromObjectOrReply ( c , c - > argv [ 2 ] , & id , NULL )
! = C_OK ) return ;
struct client * target = lookupClientByID ( id ) ;
if ( target & & target - > flags & CLIENT_BLOCKED ) {
2020-05-10 22:08:50 -04:00
std : : unique_lock < fastlock > ul ( target - > lock ) ;
2019-02-15 14:11:05 -05:00
if ( unblock_error )
2020-10-24 02:18:03 +00:00
addReplyError ( target ,
2019-02-15 14:11:05 -05:00
" -UNBLOCKED client unblocked via CLIENT UNBLOCK " ) ;
else
replyToBlockedClientTimedOut ( target ) ;
unblockClient ( target ) ;
addReply ( c , shared . cone ) ;
} else {
addReply ( c , shared . czero ) ;
}
2019-07-19 00:01:56 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " setname " ) & & c - > argc = = 3 ) {
2019-07-03 11:58:20 +02:00
/* CLIENT SETNAME */
2019-02-25 16:51:49 +01:00
if ( clientSetNameOrReply ( c , c - > argv [ 2 ] ) = = C_OK )
2019-02-15 14:11:05 -05:00
addReply ( c , shared . ok ) ;
2019-07-19 00:01:56 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " getname " ) & & c - > argc = = 2 ) {
2019-07-03 11:58:20 +02:00
/* CLIENT GETNAME */
2019-02-15 14:11:05 -05:00
if ( c - > name )
addReplyBulk ( c , c - > name ) ;
else
2020-09-11 20:48:18 +00:00
addReplyNull ( c ) ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " unpause " ) & & c - > argc = = 2 ) {
2021-01-07 23:36:54 -08:00
/* CLIENT UNPAUSE */
unpauseClients ( ) ;
addReply ( c , shared . ok ) ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " pause " ) & & ( c - > argc = = 3 | |
2021-01-07 23:36:54 -08:00
c - > argc = = 4 ) )
{
/* CLIENT PAUSE TIMEOUT [WRITE|ALL] */
2021-01-28 13:18:05 -08:00
mstime_t end ;
2021-05-19 02:59:48 +00:00
pause_type type = CLIENT_PAUSE_ALL ;
2021-01-07 23:36:54 -08:00
if ( c - > argc = = 4 ) {
2021-05-19 02:59:48 +00:00
if ( ! strcasecmp ( szFromObj ( c - > argv [ 3 ] ) , " write " ) ) {
2021-01-07 23:36:54 -08:00
type = CLIENT_PAUSE_WRITE ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 3 ] ) , " all " ) ) {
2021-01-07 23:36:54 -08:00
type = CLIENT_PAUSE_ALL ;
} else {
addReplyError ( c ,
" CLIENT PAUSE mode must be WRITE or ALL " ) ;
return ;
}
}
2019-02-15 14:11:05 -05:00
2021-01-28 13:18:05 -08:00
if ( getTimeoutFromObjectOrReply ( c , c - > argv [ 2 ] , & end ,
2021-01-07 23:36:54 -08:00
UNIT_MILLISECONDS ) ! = C_OK ) return ;
2021-01-28 13:18:05 -08:00
pauseClients ( end , type ) ;
2019-02-15 14:11:05 -05:00
addReply ( c , shared . ok ) ;
2020-04-14 20:09:53 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " tracking " ) & & c - > argc > = 3 ) {
2020-02-10 17:18:11 +01:00
/* CLIENT TRACKING (on|off) [REDIRECT <id>] [BCAST] [PREFIX first]
2020-02-21 16:39:42 +01:00
* [ PREFIX second ] [ OPTIN ] [ OPTOUT ] . . . */
2019-07-03 11:58:20 +02:00
long long redir = 0 ;
2020-02-21 16:39:42 +01:00
uint64_t options = 0 ;
2020-02-12 19:22:04 +01:00
robj * * prefix = NULL ;
2020-02-10 17:18:11 +01:00
size_t numprefix = 0 ;
2019-07-03 11:58:20 +02:00
2020-02-10 17:18:11 +01:00
/* Parse the options. */
2020-02-11 17:26:27 +01:00
for ( int j = 3 ; j < c - > argc ; j + + ) {
2020-02-10 17:18:11 +01:00
int moreargs = ( c - > argc - 1 ) - j ;
2020-04-14 20:09:53 -04:00
if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " redirect " ) & & moreargs ) {
2020-02-10 17:18:11 +01:00
j + + ;
2020-02-16 05:41:39 -08:00
if ( redir ! = 0 ) {
addReplyError ( c , " A client can only redirect to a single "
" other client " ) ;
zfree ( prefix ) ;
return ;
}
2020-02-10 17:18:11 +01:00
if ( getLongLongFromObjectOrReply ( c , c - > argv [ j ] , & redir , NULL ) ! =
2020-02-16 05:16:51 -08:00
C_OK )
{
zfree ( prefix ) ;
return ;
}
2020-02-10 17:18:11 +01:00
/* We will require the client with the specified ID to exist
* right now , even if it is possible that it gets disconnected
* later . Still a valid sanity check . */
2019-07-03 11:58:20 +02:00
if ( lookupClientByID ( redir ) = = NULL ) {
addReplyError ( c , " The client ID you want redirect to "
" does not exist " ) ;
2020-02-16 05:16:51 -08:00
zfree ( prefix ) ;
2019-07-03 11:58:20 +02:00
return ;
}
2020-04-14 20:09:53 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " bcast " ) ) {
2020-02-21 16:39:42 +01:00
options | = CLIENT_TRACKING_BCAST ;
2020-04-14 20:19:48 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " optin " ) ) {
2020-02-21 16:39:42 +01:00
options | = CLIENT_TRACKING_OPTIN ;
2020-04-14 20:19:48 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " optout " ) ) {
2020-02-21 16:39:42 +01:00
options | = CLIENT_TRACKING_OPTOUT ;
2020-05-21 22:09:06 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " noloop " ) ) {
2020-04-21 17:29:18 +02:00
options | = CLIENT_TRACKING_NOLOOP ;
2020-04-14 20:09:53 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ j ] ) , " prefix " ) & & moreargs ) {
2020-02-10 17:18:11 +01:00
j + + ;
2020-04-14 20:09:53 -04:00
prefix = ( robj * * ) zrealloc ( prefix , sizeof ( robj * ) * ( numprefix + 1 ) , MALLOC_LOCAL ) ;
2020-02-11 17:26:27 +01:00
prefix [ numprefix + + ] = c - > argv [ j ] ;
2020-02-10 17:18:11 +01:00
} else {
2020-02-13 16:58:07 +01:00
zfree ( prefix ) ;
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2020-02-10 17:18:11 +01:00
return ;
2019-07-03 11:58:20 +02:00
}
}
2020-02-10 17:18:11 +01:00
/* Options are ok: enable or disable the tracking for this client. */
2019-07-19 00:01:56 -04:00
if ( ! strcasecmp ( szFromObj ( c - > argv [ 2 ] ) , " on " ) ) {
2020-02-13 16:58:07 +01:00
/* Before enabling tracking, make sure options are compatible
* among each other and with the current state of the client . */
2020-02-21 16:39:42 +01:00
if ( ! ( options & CLIENT_TRACKING_BCAST ) & & numprefix ) {
2020-02-13 16:58:07 +01:00
addReplyError ( c ,
" PREFIX option requires BCAST mode to be enabled " ) ;
zfree ( prefix ) ;
return ;
}
if ( c - > flags & CLIENT_TRACKING ) {
2020-02-14 14:27:22 +01:00
int oldbcast = ! ! ( c - > flags & CLIENT_TRACKING_BCAST ) ;
2020-02-21 16:39:42 +01:00
int newbcast = ! ! ( options & CLIENT_TRACKING_BCAST ) ;
if ( oldbcast ! = newbcast ) {
2020-02-13 16:58:07 +01:00
addReplyError ( c ,
" You can't switch BCAST mode on/off before disabling "
" tracking for this client, and then re-enabling it with "
" a different mode. " ) ;
zfree ( prefix ) ;
return ;
}
}
2020-02-21 16:39:42 +01:00
if ( options & CLIENT_TRACKING_BCAST & &
options & ( CLIENT_TRACKING_OPTIN | CLIENT_TRACKING_OPTOUT ) )
{
addReplyError ( c ,
" OPTIN and OPTOUT are not compatible with BCAST " ) ;
zfree ( prefix ) ;
return ;
}
2020-03-29 23:20:54 -04:00
if ( options & CLIENT_TRACKING_OPTIN & & options & CLIENT_TRACKING_OPTOUT )
2020-03-29 23:06:50 -04:00
{
addReplyError ( c ,
" You can't specify both OPTIN mode and OPTOUT mode " ) ;
zfree ( prefix ) ;
return ;
}
2020-03-29 23:20:54 -04:00
if ( ( options & CLIENT_TRACKING_OPTIN & & c - > flags & CLIENT_TRACKING_OPTOUT ) | |
( options & CLIENT_TRACKING_OPTOUT & & c - > flags & CLIENT_TRACKING_OPTIN ) )
{
addReplyError ( c ,
" You can't switch OPTIN/OPTOUT mode before disabling "
" tracking for this client, and then re-enabling it with "
" a different mode. " ) ;
zfree ( prefix ) ;
return ;
}
2021-01-08 00:00:35 -08:00
if ( options & CLIENT_TRACKING_BCAST ) {
if ( ! checkPrefixCollisionsOrReply ( c , prefix , numprefix ) ) {
zfree ( prefix ) ;
return ;
}
}
2020-02-21 16:39:42 +01:00
enableTracking ( c , redir , options , prefix , numprefix ) ;
2019-07-19 00:01:56 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 2 ] ) , " off " ) ) {
2019-07-03 11:58:20 +02:00
disableTracking ( c ) ;
} else {
2020-02-13 16:58:07 +01:00
zfree ( prefix ) ;
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2019-07-03 11:58:20 +02:00
return ;
}
2020-02-10 17:18:11 +01:00
zfree ( prefix ) ;
2019-07-03 11:58:20 +02:00
addReply ( c , shared . ok ) ;
2020-04-14 20:19:48 -04:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " caching " ) & & c - > argc > = 3 ) {
2020-02-21 16:39:42 +01:00
if ( ! ( c - > flags & CLIENT_TRACKING ) ) {
addReplyError ( c , " CLIENT CACHING can be called only when the "
" client is in tracking mode with OPTIN or "
" OPTOUT mode enabled " ) ;
return ;
}
2021-05-19 02:59:48 +00:00
char * opt = szFromObj ( c - > argv [ 2 ] ) ;
2020-02-21 16:39:42 +01:00
if ( ! strcasecmp ( opt , " yes " ) ) {
if ( c - > flags & CLIENT_TRACKING_OPTIN ) {
c - > flags | = CLIENT_TRACKING_CACHING ;
} else {
addReplyError ( c , " CLIENT CACHING YES is only valid when tracking is enabled in OPTIN mode. " ) ;
return ;
}
} else if ( ! strcasecmp ( opt , " no " ) ) {
if ( c - > flags & CLIENT_TRACKING_OPTOUT ) {
c - > flags | = CLIENT_TRACKING_CACHING ;
} else {
addReplyError ( c , " CLIENT CACHING NO is only valid when tracking is enabled in OPTOUT mode. " ) ;
return ;
}
} else {
2020-12-23 19:06:25 -08:00
addReplyErrorObject ( c , shared . syntaxerr ) ;
2020-02-21 16:39:42 +01:00
return ;
}
/* Common reply for when we succeeded. */
addReply ( c , shared . ok ) ;
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " caching " ) & & c - > argc > = 3 ) {
if ( ! ( c - > flags & CLIENT_TRACKING ) ) {
addReplyError ( c , " CLIENT CACHING can be called only when the "
" client is in tracking mode with OPTIN or "
" OPTOUT mode enabled " ) ;
return ;
}
2020-04-14 20:19:48 -04:00
char * opt = szFromObj ( c - > argv [ 2 ] ) ;
2020-02-21 16:39:42 +01:00
if ( ! strcasecmp ( opt , " yes " ) ) {
if ( c - > flags & CLIENT_TRACKING_OPTIN ) {
c - > flags | = CLIENT_TRACKING_CACHING ;
} else {
addReplyError ( c , " CLIENT CACHING YES is only valid when tracking is enabled in OPTIN mode. " ) ;
return ;
}
} else if ( ! strcasecmp ( opt , " no " ) ) {
if ( c - > flags & CLIENT_TRACKING_OPTOUT ) {
c - > flags | = CLIENT_TRACKING_CACHING ;
} else {
addReplyError ( c , " CLIENT CACHING NO is only valid when tracking is enabled in OPTOUT mode. " ) ;
return ;
}
} else {
addReply ( c , shared . syntaxerr ) ;
return ;
}
/* Common reply for when we succeeded. */
addReply ( c , shared . ok ) ;
2020-01-27 02:55:48 -05:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " getredir " ) & & c - > argc = = 2 ) {
2019-07-10 18:17:07 +02:00
/* CLIENT GETREDIR */
if ( c - > flags & CLIENT_TRACKING ) {
addReplyLongLong ( c , c - > client_tracking_redirection ) ;
} else {
addReplyLongLong ( c , - 1 ) ;
}
2021-05-19 02:59:48 +00:00
} else if ( ! strcasecmp ( szFromObj ( c - > argv [ 1 ] ) , " trackinginfo " ) & & c - > argc = = 2 ) {
2020-12-27 19:14:39 +08:00
addReplyMapLen ( c , 3 ) ;
/* Flags */
addReplyBulkCString ( c , " flags " ) ;
void * arraylen_ptr = addReplyDeferredLen ( c ) ;
int numflags = 0 ;
addReplyBulkCString ( c , c - > flags & CLIENT_TRACKING ? " on " : " off " ) ;
numflags + + ;
if ( c - > flags & CLIENT_TRACKING_BCAST ) {
addReplyBulkCString ( c , " bcast " ) ;
numflags + + ;
}
if ( c - > flags & CLIENT_TRACKING_OPTIN ) {
addReplyBulkCString ( c , " optin " ) ;
numflags + + ;
if ( c - > flags & CLIENT_TRACKING_CACHING ) {
addReplyBulkCString ( c , " caching-yes " ) ;
numflags + + ;
}
}
if ( c - > flags & CLIENT_TRACKING_OPTOUT ) {
addReplyBulkCString ( c , " optout " ) ;
numflags + + ;
if ( c - > flags & CLIENT_TRACKING_CACHING ) {
addReplyBulkCString ( c , " caching-no " ) ;
numflags + + ;
}
}
if ( c - > flags & CLIENT_TRACKING_NOLOOP ) {
addReplyBulkCString ( c , " noloop " ) ;
numflags + + ;
}
if ( c - > flags & CLIENT_TRACKING_BROKEN_REDIR ) {
addReplyBulkCString ( c , " broken_redirect " ) ;
numflags + + ;
}
setDeferredSetLen ( c , arraylen_ptr , numflags ) ;
/* Redirect */
addReplyBulkCString ( c , " redirect " ) ;
if ( c - > flags & CLIENT_TRACKING ) {
addReplyLongLong ( c , c - > client_tracking_redirection ) ;
} else {
addReplyLongLong ( c , - 1 ) ;
}
/* Prefixes */
addReplyBulkCString ( c , " prefixes " ) ;
if ( c - > client_tracking_prefixes ) {
addReplyArrayLen ( c , raxSize ( c - > client_tracking_prefixes ) ) ;
raxIterator ri ;
raxStart ( & ri , c - > client_tracking_prefixes ) ;
raxSeek ( & ri , " ^ " , NULL , 0 ) ;
while ( raxNext ( & ri ) ) {
addReplyBulkCBuffer ( c , ri . key , ri . key_len ) ;
}
raxStop ( & ri ) ;
} else {
addReplyArrayLen ( c , 0 ) ;
}
2019-02-15 14:11:05 -05:00
} else {
2021-01-04 17:02:57 +02:00
addReplySubcommandSyntaxError ( c ) ;
2019-02-15 14:11:05 -05:00
}
}
2020-12-24 19:16:28 +08:00
/* HELLO [<protocol-version> [AUTH <user> <password>] [SETNAME <name>] ] */
2019-02-15 14:11:05 -05:00
void helloCommand ( client * c ) {
2020-12-24 13:13:25 +08:00
long long ver = 0 ;
2020-12-24 17:03:36 +08:00
int next_arg = 1 ;
2019-02-15 14:11:05 -05:00
2020-12-24 20:13:57 +08:00
if ( c - > argc > = 2 ) {
if ( getLongLongFromObjectOrReply ( c , c - > argv [ next_arg + + ] , & ver ,
2020-12-25 10:17:55 +08:00
" Protocol version is not an integer or out of range " ) ! = C_OK ) {
2020-12-24 20:13:57 +08:00
return ;
2020-12-25 10:17:55 +08:00
}
2018-12-04 12:46:16 +01:00
2020-12-24 20:13:57 +08:00
if ( ver < 2 | | ver > 3 ) {
addReplyError ( c , " -NOPROTO unsupported protocol version " ) ;
return ;
}
2019-02-15 14:11:05 -05:00
}
2020-12-24 17:03:53 +08:00
for ( int j = next_arg ; j < c - > argc ; j + + ) {
2019-02-25 16:55:16 +01:00
int moreargs = ( c - > argc - 1 ) - j ;
2019-03-02 18:07:18 -05:00
const char * opt = ( const char * ) ptrFromObj ( c - > argv [ j ] ) ;
2019-02-25 16:55:16 +01:00
if ( ! strcasecmp ( opt , " AUTH " ) & & moreargs > = 2 ) {
2021-03-15 22:00:29 -07:00
preventCommandLogging ( c ) ;
2019-02-25 16:55:16 +01:00
if ( ACLAuthenticateUser ( c , c - > argv [ j + 1 ] , c - > argv [ j + 2 ] ) = = C_ERR ) {
2020-08-18 01:59:24 -04:00
addReplyError ( c , " -WRONGPASS invalid username-password pair or user is disabled. " ) ;
2019-02-25 16:55:16 +01:00
return ;
}
j + = 2 ;
2019-02-25 16:56:58 +01:00
} else if ( ! strcasecmp ( opt , " SETNAME " ) & & moreargs ) {
if ( clientSetNameOrReply ( c , c - > argv [ j + 1 ] ) = = C_ERR ) return ;
j + + ;
2019-02-25 16:55:16 +01:00
} else {
addReplyErrorFormat ( c , " Syntax error in HELLO option '%s' " , opt ) ;
return ;
}
2019-02-15 14:11:05 -05:00
}
/* At this point we need to be authenticated to continue. */
if ( ! c - > authenticated ) {
addReplyError ( c , " -NOAUTH HELLO must be called with the client already "
" authenticated, otherwise the HELLO AUTH <user> <pass> "
" option can be used to authenticate the client and "
" select the RESP protocol version at the same time " ) ;
return ;
}
2019-02-25 16:40:58 +01:00
/* Let's switch to the specified RESP mode. */
2020-12-24 17:03:22 +08:00
if ( ver ) c - > resp = ver ;
2020-05-21 22:09:06 -04:00
addReplyMapLen ( c , 6 + ! g_pserver - > sentinel_mode ) ;
2019-02-15 14:11:05 -05:00
addReplyBulkCString ( c , " server " ) ;
addReplyBulkCString ( c , " redis " ) ;
addReplyBulkCString ( c , " version " ) ;
2019-04-19 19:57:11 -04:00
addReplyBulkCString ( c , KEYDB_SET_VERSION ) ;
2019-02-15 14:11:05 -05:00
addReplyBulkCString ( c , " proto " ) ;
2020-06-09 19:46:49 +08:00
addReplyLongLong ( c , c - > resp ) ;
2019-02-15 14:11:05 -05:00
addReplyBulkCString ( c , " id " ) ;
addReplyLongLong ( c , c - > id ) ;
addReplyBulkCString ( c , " mode " ) ;
2019-04-21 14:01:10 -04:00
if ( g_pserver - > sentinel_mode ) addReplyBulkCString ( c , " sentinel " ) ;
2020-05-21 22:09:06 -04:00
else if ( g_pserver - > cluster_enabled ) addReplyBulkCString ( c , " cluster " ) ;
2019-02-15 14:11:05 -05:00
else addReplyBulkCString ( c , " standalone " ) ;
2019-04-21 14:01:10 -04:00
if ( ! g_pserver - > sentinel_mode ) {
2019-02-15 14:11:05 -05:00
addReplyBulkCString ( c , " role " ) ;
2019-07-12 03:54:41 -04:00
addReplyBulkCString ( c , listLength ( g_pserver - > masters ) ?
g_pserver - > fActiveReplica ? " active-replica " : " replica "
: " master " ) ;
2019-02-15 14:11:05 -05:00
}
addReplyBulkCString ( c , " modules " ) ;
addReplyLoadedModules ( c ) ;
}
/* This callback is bound to POST and "Host:" command names. Those are not
* really commands , but are used in security attacks in order to talk to
* Redis instances via HTTP , with a technique called " cross protocol scripting "
* which exploits the fact that services like Redis will discard invalid
* HTTP headers and will process what follows .
*
* As a protection against this attack , Redis will terminate the connection
* when a POST or " Host: " header is seen , and will log the event from
* time to time ( to avoid creating a DOS as a result of too many logs ) . */
void securityWarningCommand ( client * c ) {
static time_t logged_time ;
time_t now = time ( NULL ) ;
2021-03-17 14:45:38 +01:00
if ( llabs ( now - logged_time ) > 60 ) {
2021-04-23 21:55:01 +00:00
serverLog ( LL_WARNING , " Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to KeyDB. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your KeyDB instance. Connection aborted. " ) ;
2019-02-15 14:11:05 -05:00
logged_time = now ;
}
freeClientAsync ( c ) ;
}
2020-11-10 13:50:03 -08:00
/* Keep track of the original command arguments so that we can generate
* an accurate slowlog entry after the command has been executed . */
static void retainOriginalCommandVector ( client * c ) {
/* We already rewrote this command, so don't rewrite it again */
if ( c - > original_argv ) return ;
c - > original_argc = c - > argc ;
2021-05-19 02:59:48 +00:00
c - > original_argv = ( robj * * ) zmalloc ( sizeof ( robj * ) * ( c - > argc ) ) ;
2020-11-10 13:50:03 -08:00
for ( int j = 0 ; j < c - > argc ; j + + ) {
c - > original_argv [ j ] = c - > argv [ j ] ;
incrRefCount ( c - > argv [ j ] ) ;
}
}
2019-02-15 14:11:05 -05:00
/* Rewrite the command vector of the client. All the new objects ref count
* is incremented . The old command vector is freed , and the old objects
* ref count is decremented . */
void rewriteClientCommandVector ( client * c , int argc , . . . ) {
va_list ap ;
int j ;
robj * * argv ; /* The new argument vector */
argv = ( robj * * ) zmalloc ( sizeof ( robj * ) * argc , MALLOC_LOCAL ) ;
va_start ( ap , argc ) ;
for ( j = 0 ; j < argc ; j + + ) {
robj * a ;
a = va_arg ( ap , robj * ) ;
argv [ j ] = a ;
incrRefCount ( a ) ;
}
2020-11-10 13:50:03 -08:00
replaceClientCommandVector ( c , argc , argv ) ;
2019-02-15 14:11:05 -05:00
va_end ( ap ) ;
}
/* Completely replace the client command vector with the provided one. */
void replaceClientCommandVector ( client * c , int argc , robj * * argv ) {
2020-10-05 11:15:36 +03:00
int j ;
2020-11-10 13:50:03 -08:00
retainOriginalCommandVector ( c ) ;
2019-02-15 14:11:05 -05:00
freeClientArgv ( c ) ;
zfree ( c - > argv ) ;
c - > argv = argv ;
c - > argc = argc ;
2020-10-05 11:15:36 +03:00
c - > argv_len_sum = 0 ;
for ( j = 0 ; j < c - > argc ; j + + )
if ( c - > argv [ j ] )
c - > argv_len_sum + = getStringObjectLen ( c - > argv [ j ] ) ;
2019-02-15 14:11:05 -05:00
c - > cmd = lookupCommandOrOriginal ( ( sds ) ptrFromObj ( c - > argv [ 0 ] ) ) ;
serverAssertWithInfo ( c , NULL , c - > cmd ! = NULL ) ;
}
/* Rewrite a single item in the command vector.
* The new val ref count is incremented , and the old decremented .
*
* It is possible to specify an argument over the current size of the
* argument vector : in this case the array of objects gets reallocated
* and c - > argc set to the max value . However it ' s up to the caller to
*
* 1. Make sure there are no " holes " and all the arguments are set .
* 2. If the original argument vector was longer than the one we
* want to end with , it ' s up to the caller to set c - > argc and
* free the no longer used objects on c - > argv . */
void rewriteClientCommandArgument ( client * c , int i , robj * newval ) {
robj * oldval ;
2020-11-10 13:50:03 -08:00
retainOriginalCommandVector ( c ) ;
2019-02-15 14:11:05 -05:00
if ( i > = c - > argc ) {
c - > argv = ( robj * * ) zrealloc ( c - > argv , sizeof ( robj * ) * ( i + 1 ) , MALLOC_LOCAL ) ;
c - > argc = i + 1 ;
c - > argv [ i ] = NULL ;
}
oldval = c - > argv [ i ] ;
2020-10-05 11:15:36 +03:00
if ( oldval ) c - > argv_len_sum - = getStringObjectLen ( oldval ) ;
if ( newval ) c - > argv_len_sum + = getStringObjectLen ( newval ) ;
2019-02-15 14:11:05 -05:00
c - > argv [ i ] = newval ;
incrRefCount ( newval ) ;
if ( oldval ) decrRefCount ( oldval ) ;
/* If this is the command name make sure to fix c->cmd. */
if ( i = = 0 ) {
c - > cmd = lookupCommandOrOriginal ( ( sds ) ptrFromObj ( c - > argv [ 0 ] ) ) ;
serverAssertWithInfo ( c , NULL , c - > cmd ! = NULL ) ;
}
}
2019-05-13 17:30:02 +02:00
/* This function returns the number of bytes that Redis is
2019-02-15 14:11:05 -05:00
* using to store the reply still not read by the client .
*
* Note : this function is very fast so can be called as many time as
* the caller wishes . The main usage of this function currently is
* enforcing the client output length limits . */
unsigned long getClientOutputBufferMemoryUsage ( client * c ) {
unsigned long list_item_size = sizeof ( listNode ) + sizeof ( clientReplyBlock ) ;
2020-10-15 23:10:17 +00:00
return c - > reply_bytes + ( list_item_size * listLength ( c - > reply ) ) + ( c - > replyAsync ? c - > replyAsync - > size : 0 ) ;
2019-02-15 14:11:05 -05:00
}
/* Get the class of a client, used in order to enforce limits to different
* classes of clients .
*
* The function will return one of the following :
* CLIENT_TYPE_NORMAL - > Normal client
2020-02-06 14:09:45 +05:30
* CLIENT_TYPE_SLAVE - > Slave
2019-02-15 14:11:05 -05:00
* CLIENT_TYPE_PUBSUB - > Client subscribed to Pub / Sub channels
* CLIENT_TYPE_MASTER - > The client representing our replication master .
*/
int getClientType ( client * c ) {
if ( c - > flags & CLIENT_MASTER ) return CLIENT_TYPE_MASTER ;
2020-02-06 14:09:45 +05:30
/* Even though MONITOR clients are marked as replicas, we
* want the expose them as normal clients . */
2019-02-15 14:11:05 -05:00
if ( ( c - > flags & CLIENT_SLAVE ) & & ! ( c - > flags & CLIENT_MONITOR ) )
return CLIENT_TYPE_SLAVE ;
if ( c - > flags & CLIENT_PUBSUB ) return CLIENT_TYPE_PUBSUB ;
return CLIENT_TYPE_NORMAL ;
}
int getClientTypeByName ( const char * name ) {
if ( ! strcasecmp ( name , " normal " ) ) return CLIENT_TYPE_NORMAL ;
else if ( ! strcasecmp ( name , " slave " ) ) return CLIENT_TYPE_SLAVE ;
else if ( ! strcasecmp ( name , " replica " ) ) return CLIENT_TYPE_SLAVE ;
else if ( ! strcasecmp ( name , " pubsub " ) ) return CLIENT_TYPE_PUBSUB ;
else if ( ! strcasecmp ( name , " master " ) ) return CLIENT_TYPE_MASTER ;
else return - 1 ;
}
const char * getClientTypeName ( int clientType ) {
switch ( clientType ) {
case CLIENT_TYPE_NORMAL : return " normal " ;
case CLIENT_TYPE_SLAVE : return " slave " ;
case CLIENT_TYPE_PUBSUB : return " pubsub " ;
case CLIENT_TYPE_MASTER : return " master " ;
default : return NULL ;
}
}
/* The function checks if the client reached output buffer soft or hard
* limit , and also update the state needed to check the soft limit as
* a side effect .
*
* Return value : non - zero if the client reached the soft or the hard limit .
* Otherwise zero is returned . */
int checkClientOutputBufferLimits ( client * c ) {
int soft = 0 , hard = 0 ;
unsigned long used_mem = getClientOutputBufferMemoryUsage ( c ) ;
int clientType = getClientType ( c ) ;
/* For the purpose of output buffer limiting, masters are handled
* like normal clients . */
if ( clientType = = CLIENT_TYPE_MASTER ) clientType = CLIENT_TYPE_NORMAL ;
2019-04-21 13:20:45 -04:00
if ( cserver . client_obuf_limits [ clientType ] . hard_limit_bytes & &
used_mem > = cserver . client_obuf_limits [ clientType ] . hard_limit_bytes )
2019-02-15 14:11:05 -05:00
hard = 1 ;
2019-04-21 13:20:45 -04:00
if ( cserver . client_obuf_limits [ clientType ] . soft_limit_bytes & &
used_mem > = cserver . client_obuf_limits [ clientType ] . soft_limit_bytes )
2019-02-15 14:11:05 -05:00
soft = 1 ;
/* We need to check if the soft limit is reached continuously for the
* specified amount of seconds . */
if ( soft ) {
if ( c - > obuf_soft_limit_reached_time = = 0 ) {
2019-04-21 14:01:10 -04:00
c - > obuf_soft_limit_reached_time = g_pserver - > unixtime ;
2019-02-15 14:11:05 -05:00
soft = 0 ; /* First time we see the soft limit reached */
} else {
2019-04-21 14:01:10 -04:00
time_t elapsed = g_pserver - > unixtime - c - > obuf_soft_limit_reached_time ;
2019-02-15 14:11:05 -05:00
if ( elapsed < =
2019-04-21 13:20:45 -04:00
cserver . client_obuf_limits [ clientType ] . soft_limit_seconds ) {
2019-02-15 14:11:05 -05:00
soft = 0 ; /* The client still did not reached the max number of
seconds for the soft limit to be considered
reached . */
}
}
} else {
c - > obuf_soft_limit_reached_time = 0 ;
}
return soft | | hard ;
}
/* Asynchronously close a client if soft or hard limit is reached on the
* output buffer size . The caller can check if the client will be closed
* checking if the client CLIENT_CLOSE_ASAP flag is set .
*
* Note : we need to close the client asynchronously because this function is
* called from contexts where the client can ' t be freed safely , i . e . from the
* lower level functions pushing data inside the client output buffers . */
void asyncCloseClientOnOutputBufferLimitReached ( client * c ) {
2019-09-12 10:56:54 +03:00
if ( ! c - > conn ) return ; /* It is unsafe to free fake clients. */
2019-02-15 14:11:05 -05:00
serverAssert ( c - > reply_bytes < SIZE_MAX - ( 1024 * 64 ) ) ;
if ( c - > reply_bytes = = 0 | | c - > flags & CLIENT_CLOSE_ASAP ) return ;
if ( checkClientOutputBufferLimits ( c ) ) {
sds client = catClientInfoString ( sdsempty ( ) , c ) ;
freeClientAsync ( c ) ;
serverLog ( LL_WARNING , " Client %s scheduled to be closed ASAP for overcoming of output buffer limits. " , client ) ;
sdsfree ( client ) ;
}
}
2020-09-15 23:16:01 -07:00
/* Helper function used by performEvictions() in order to flush slaves
2019-02-15 14:11:05 -05:00
* output buffers without returning control to the event loop .
* This is also called by SHUTDOWN for a best - effort attempt to send
* slaves the latest writes . */
void flushSlavesOutputBuffers ( void ) {
2019-03-07 19:13:01 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-15 14:11:05 -05:00
listIter li ;
listNode * ln ;
2021-01-31 02:30:28 +00:00
flushReplBacklogToClients ( ) ;
2019-04-21 14:01:10 -04:00
listRewind ( g_pserver - > slaves , & li ) ;
2019-02-15 14:11:05 -05:00
while ( ( ln = listNext ( & li ) ) ) {
2019-10-13 12:29:20 -04:00
client * replica = ( client * ) listNodeValue ( ln ) ;
2019-02-15 14:11:05 -05:00
2019-10-13 12:29:20 -04:00
if ( ! FCorrectThread ( replica ) )
2019-02-20 01:20:26 -05:00
continue ; // we cannot synchronously flush other thread's clients
2020-01-27 02:55:48 -05:00
int can_receive_writes = connHasWriteHandler ( replica - > conn ) | |
( replica - > flags & CLIENT_PENDING_WRITE ) ;
2012-02-06 16:56:42 +01:00
2019-08-31 14:46:21 +02:00
/* We don't want to send the pending data to the replica in a few
* cases :
*
* 1. For some reason there is neither the write handler installed
* nor the client is flagged as to have pending writes : for some
* reason this replica may not be set to receive data . This is
* just for the sake of defensive programming .
*
* 2. The put_online_on_ack flag is true . To know why we don ' t want
* to send data to the replica in this case , please grep for the
* flag for this flag .
*
* 3. Obviously if the slave is not ONLINE .
*/
2020-01-27 02:55:48 -05:00
if ( replica - > replstate = = SLAVE_STATE_ONLINE & &
2019-08-31 14:46:21 +02:00
can_receive_writes & &
2020-01-27 02:55:48 -05:00
! replica - > repl_put_online_on_ack & &
2019-10-13 12:29:20 -04:00
clientHasPendingReplies ( replica ) )
2019-02-15 14:11:05 -05:00
{
2020-01-27 02:55:48 -05:00
writeToClient ( replica , 0 ) ;
2019-02-15 14:11:05 -05:00
}
}
}
2021-01-07 23:36:54 -08:00
/* Pause clients up to the specified unixtime (in ms) for a given type of
* commands .
2019-02-15 14:11:05 -05:00
*
2021-01-07 23:36:54 -08:00
* A main use case of this function is to allow pausing replication traffic
* so that a failover without data loss to occur . Replicas will continue to receive
* traffic to faciliate this functionality .
*
2019-02-15 14:11:05 -05:00
* This function is also internally used by Redis Cluster for the manual
* failover procedure implemented by CLUSTER FAILOVER .
*
* The function always succeed , even if there is already a pause in progress .
2021-01-07 23:36:54 -08:00
* In such a case , the duration is set to the maximum and new end time and the
* type is set to the more restrictive type of pause . */
void pauseClients ( mstime_t end , pause_type type ) {
2021-05-19 02:59:48 +00:00
if ( type > serverTL - > client_pause_type ) {
serverTL - > client_pause_type = type ;
2021-01-07 23:36:54 -08:00
}
2021-05-19 02:59:48 +00:00
if ( end > g_pserver - > client_pause_end_time ) {
g_pserver - > client_pause_end_time = end ;
2019-11-14 20:14:24 -05:00
}
2019-02-15 14:11:05 -05:00
2021-01-07 23:36:54 -08:00
/* We allow write commands that were queued
* up before and after to execute . We need
* to track this state so that we don ' t assert
* in propagate ( ) . */
2021-05-19 02:59:48 +00:00
if ( serverTL - > in_exec ) {
g_pserver - > client_pause_in_transaction = 1 ;
2021-01-07 23:36:54 -08:00
}
2019-11-14 20:14:24 -05:00
}
2021-01-07 23:36:54 -08:00
/* Unpause clients and queue them for reprocessing. */
void unpauseClients ( void ) {
2019-11-14 20:14:24 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2021-01-07 23:36:54 -08:00
listNode * ln ;
listIter li ;
client * c ;
2021-05-19 02:59:48 +00:00
serverTL - > client_pause_type = CLIENT_PAUSE_OFF ;
2019-02-15 14:11:05 -05:00
2021-01-07 23:36:54 -08:00
/* Unblock all of the clients so they are reprocessed. */
2021-05-19 02:59:48 +00:00
listRewind ( g_pserver - > paused_clients , & li ) ;
2021-01-07 23:36:54 -08:00
while ( ( ln = listNext ( & li ) ) ! = NULL ) {
2021-05-19 02:59:48 +00:00
c = ( client * ) listNodeValue ( ln ) ;
2021-05-21 05:54:39 +00:00
std : : unique_lock < fastlock > ul ( c - > lock ) ;
2021-01-07 23:36:54 -08:00
unblockClient ( c ) ;
2014-02-04 15:52:09 +01:00
}
2021-01-07 23:36:54 -08:00
}
2019-02-15 14:11:05 -05:00
2021-01-07 23:36:54 -08:00
/* Returns true if clients are paused and false otherwise. */
int areClientsPaused ( void ) {
2021-05-19 02:59:48 +00:00
return serverTL - > client_pause_type ! = CLIENT_PAUSE_OFF ;
2021-01-07 23:36:54 -08:00
}
2019-02-15 14:11:05 -05:00
2021-01-07 23:36:54 -08:00
/* Checks if the current client pause has elapsed and unpause clients
* if it has . Also returns true if clients are now paused and false
* otherwise . */
int checkClientPauseTimeoutAndReturnIfPaused ( void ) {
2021-04-13 08:41:12 +03:00
if ( ! areClientsPaused ( ) )
return 0 ;
2021-05-19 02:59:48 +00:00
if ( g_pserver - > client_pause_end_time < g_pserver - > mstime ) {
2021-01-07 23:36:54 -08:00
unpauseClients ( ) ;
2019-02-15 14:11:05 -05:00
}
2021-01-07 23:36:54 -08:00
return areClientsPaused ( ) ;
2019-02-15 14:11:05 -05:00
}
/* This function is called by Redis in order to process a few events from
* time to time while blocked into some not interruptible operation .
* This allows to reply to clients with the - LOADING error while loading the
* data set at startup or after a full resynchronization with the master
* and so forth .
*
* It calls the event loop in order to process a few events . Specifically we
* try to call the event loop 4 times as long as we receive acknowledge that
* some event was processed , in order to go forward with the accept , read ,
* write , close sequence needed to serve a client .
*
* The function returns the total number of events processed . */
2020-05-22 16:45:18 -04:00
void processEventsWhileBlocked ( int iel ) {
2020-02-17 18:57:13 -05:00
serverAssert ( GlobalLocksAcquired ( ) ) ;
2019-02-15 14:11:05 -05:00
int iterations = 4 ; /* See the function top-comment. */
2019-02-18 23:52:21 -05:00
2020-03-19 15:28:39 -04:00
std : : vector < client * > vecclients ;
listIter li ;
listNode * ln ;
listRewind ( g_pserver - > clients , & li ) ;
2020-08-27 11:09:32 +03:00
/* Update our cached time since it is used to create and update the last
* interaction time with clients and for other important things . */
updateCachedTime ( 0 ) ;
2020-03-19 15:28:39 -04:00
// All client locks must be acquired *after* the global lock is reacquired to prevent deadlocks
// so unlock here, and save them for reacquisition later
while ( ( ln = listNext ( & li ) ) ! = nullptr )
2019-10-23 13:19:57 -04:00
{
2020-03-19 15:28:39 -04:00
client * c = ( client * ) listNodeValue ( ln ) ;
if ( c - > lock . fOwnLock ( ) ) {
serverAssert ( c - > flags & CLIENT_PROTECTED ) ; // If the client is not protected we have no gurantee they won't be free'd in the event loop
c - > lock . unlock ( ) ;
vecclients . push_back ( c ) ;
}
2019-10-23 13:19:57 -04:00
}
2020-03-19 15:28:39 -04:00
2020-10-28 04:55:56 +00:00
/* Since we're about to release our lock we need to flush the repl backlog queue */
bool fReplBacklog = g_pserver - > repl_batch_offStart > = 0 ;
if ( fReplBacklog ) {
flushReplBacklogToClients ( ) ;
g_pserver - > repl_batch_idxStart = - 1 ;
g_pserver - > repl_batch_offStart = - 1 ;
}
2020-02-17 18:57:13 -05:00
2021-05-21 05:54:39 +00:00
long long eventsCount = 0 ;
2019-10-23 13:19:57 -04:00
aeReleaseLock ( ) ;
2020-07-10 11:33:47 +03:00
serverAssert ( ! GlobalLocksAcquired ( ) ) ;
2020-02-17 18:57:13 -05:00
try
{
2021-05-19 02:59:48 +00:00
ProcessingEventsWhileBlocked = 1 ;
2020-02-17 18:57:13 -05:00
while ( iterations - - ) {
2020-05-22 16:45:18 -04:00
long long startval = g_pserver - > events_processed_while_blocked ;
long long ae_events = aeProcessEvents ( g_pserver - > rgthreadvar [ iel ] . el ,
AE_FILE_EVENTS | AE_DONT_WAIT |
AE_CALL_BEFORE_SLEEP | AE_CALL_AFTER_SLEEP ) ;
2021-05-19 02:59:48 +00:00
/* Note that g_pserver->events_processed_while_blocked will also get
2020-05-22 16:45:18 -04:00
* incremeted by callbacks called by the event loop handlers . */
2021-05-21 05:54:39 +00:00
eventsCount + = ae_events ;
long long events = eventsCount - startval ;
2020-02-17 18:57:13 -05:00
if ( ! events ) break ;
}
2021-05-19 02:59:48 +00:00
ProcessingEventsWhileBlocked = 0 ;
2020-02-17 18:57:13 -05:00
}
catch ( . . . )
{
// Caller expects us to be locked so fix and rethrow
2021-05-19 02:59:48 +00:00
ProcessingEventsWhileBlocked = 0 ;
2020-02-17 18:57:13 -05:00
AeLocker locker ;
2020-03-19 15:28:39 -04:00
locker . arm ( nullptr ) ;
2020-02-17 18:57:13 -05:00
locker . release ( ) ;
2020-03-19 15:28:39 -04:00
for ( client * c : vecclients )
c - > lock . lock ( ) ;
2020-02-17 18:57:13 -05:00
throw ;
2019-02-15 14:11:05 -05:00
}
2020-02-17 18:57:13 -05:00
2019-10-23 13:19:57 -04:00
AeLocker locker ;
2020-03-19 15:28:39 -04:00
locker . arm ( nullptr ) ;
2019-10-23 13:19:57 -04:00
locker . release ( ) ;
2020-05-24 01:56:23 -04:00
2021-05-21 05:54:39 +00:00
g_pserver - > events_processed_while_blocked + = eventsCount ;
2021-01-07 23:36:54 -08:00
2021-05-19 02:59:48 +00:00
whileBlockedCron ( ) ;
2020-12-22 12:24:20 +02:00
2020-10-28 04:55:56 +00:00
// Restore it so the calling code is not confused
if ( fReplBacklog ) {
g_pserver - > repl_batch_idxStart = g_pserver - > repl_backlog_idx ;
g_pserver - > repl_batch_offStart = g_pserver - > master_repl_offset ;
}
2020-03-19 15:28:39 -04:00
for ( client * c : vecclients )
c - > lock . lock ( ) ;
2020-05-24 01:56:23 -04:00
// If a different thread processed the shutdown we need to abort the lua command or we will hang
if ( serverTL - > el - > stop )
throw ShutdownException ( ) ;
2019-02-15 14:11:05 -05:00
}
2017-10-24 08:35:05 +02:00