Propagate write commands to slaves, and populate the replication backlog * as well. This function is used if the instance is a master: we use * the commands received by our clients in order to create the replication * stream. Instead if the instance is a slave and has sub-slaves attached, * we use replicationFeedSlavesFromMasterStream() */
| 214 | * stream. Instead if the instance is a slave and has sub-slaves attached, |
| 215 | * we use replicationFeedSlavesFromMasterStream() */ |
| 216 | void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc) { |
| 217 | listNode *ln; |
| 218 | listIter li; |
| 219 | int j, len; |
| 220 | char llstr[LONG_STR_SIZE]; |
| 221 | |
| 222 | /* If the instance is not a top level master, return ASAP: we'll just proxy |
| 223 | * the stream of data we receive from our master instead, in order to |
| 224 | * propagate *identical* replication stream. In this way this slave can |
| 225 | * advertise the same replication ID as the master (since it shares the |
| 226 | * master replication history and has the same backlog and offsets). */ |
| 227 | if (server.masterhost != NULL) return; |
| 228 | |
| 229 | /* If there aren't slaves, and there is no backlog buffer to populate, |
| 230 | * we can return ASAP. */ |
| 231 | if (server.repl_backlog == NULL && listLength(slaves) == 0) return; |
| 232 | |
| 233 | /* We can't have slaves attached and no backlog. */ |
| 234 | serverAssert(!(listLength(slaves) != 0 && server.repl_backlog == NULL)); |
| 235 | |
| 236 | /* Send SELECT command to every slave if needed. */ |
| 237 | if (server.slaveseldb != dictid) { |
| 238 | robj *selectcmd; |
| 239 | |
| 240 | /* For a few DBs we have pre-computed SELECT command. */ |
| 241 | if (dictid >= 0 && dictid < PROTO_SHARED_SELECT_CMDS) { |
| 242 | selectcmd = shared.select[dictid]; |
| 243 | } else { |
| 244 | int dictid_len; |
| 245 | |
| 246 | dictid_len = ll2string(llstr,sizeof(llstr),dictid); |
| 247 | selectcmd = createObject(OBJ_STRING, |
| 248 | sdscatprintf(sdsempty(), |
| 249 | "*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n", |
| 250 | dictid_len, llstr)); |
| 251 | } |
| 252 | |
| 253 | /* Add the SELECT command into the backlog. */ |
| 254 | if (server.repl_backlog) feedReplicationBacklogWithObject(selectcmd); |
| 255 | |
| 256 | /* Send it to slaves. */ |
| 257 | listRewind(slaves,&li); |
| 258 | while((ln = listNext(&li))) { |
| 259 | client *slave = ln->value; |
| 260 | |
| 261 | if (!canFeedReplicaReplBuffer(slave)) continue; |
| 262 | addReply(slave,selectcmd); |
| 263 | } |
| 264 | |
| 265 | if (dictid < 0 || dictid >= PROTO_SHARED_SELECT_CMDS) |
| 266 | decrRefCount(selectcmd); |
| 267 | } |
| 268 | server.slaveseldb = dictid; |
| 269 | |
| 270 | /* Write the command to the replication backlog if any. */ |
| 271 | if (server.repl_backlog) { |
| 272 | char aux[LONG_STR_SIZE+3]; |
| 273 |
no test coverage detected