Return a migrateCachedSocket containing a TCP socket connected with the * target instance, possibly returning a cached one. * * This function is responsible of sending errors to the client if a * connection can't be established. In this case -1 is returned. * Otherwise on success the socket is returned, and the caller should not * attempt to free it after usage. * * If the caller detects a
| 5240 | * should be called so that the connection will be created from scratch |
| 5241 | * the next time. */ |
| 5242 | migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long timeout) { |
| 5243 | connection *conn; |
| 5244 | sds name = sdsempty(); |
| 5245 | migrateCachedSocket *cs; |
| 5246 | |
| 5247 | /* Check if we have an already cached socket for this ip:port pair. */ |
| 5248 | name = sdscatlen(name,host->ptr,sdslen(host->ptr)); |
| 5249 | name = sdscatlen(name,":",1); |
| 5250 | name = sdscatlen(name,port->ptr,sdslen(port->ptr)); |
| 5251 | cs = dictFetchValue(server.migrate_cached_sockets,name); |
| 5252 | if (cs) { |
| 5253 | sdsfree(name); |
| 5254 | cs->last_use_time = server.unixtime; |
| 5255 | return cs; |
| 5256 | } |
| 5257 | |
| 5258 | /* No cached socket, create one. */ |
| 5259 | if (dictSize(server.migrate_cached_sockets) == MIGRATE_SOCKET_CACHE_ITEMS) { |
| 5260 | /* Too many items, drop one at random. */ |
| 5261 | dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets); |
| 5262 | cs = dictGetVal(de); |
| 5263 | connClose(cs->conn); |
| 5264 | zfree(cs); |
| 5265 | dictDelete(server.migrate_cached_sockets,dictGetKey(de)); |
| 5266 | } |
| 5267 | |
| 5268 | /* Create the socket */ |
| 5269 | conn = server.tls_cluster ? connCreateTLS() : connCreateSocket(); |
| 5270 | if (connBlockingConnect(conn, c->argv[1]->ptr, atoi(c->argv[2]->ptr), timeout) |
| 5271 | != C_OK) { |
| 5272 | addReplyError(c,"-IOERR error or timeout connecting to the client"); |
| 5273 | connClose(conn); |
| 5274 | sdsfree(name); |
| 5275 | return NULL; |
| 5276 | } |
| 5277 | connEnableTcpNoDelay(conn); |
| 5278 | |
| 5279 | /* Add to the cache and return it to the caller. */ |
| 5280 | cs = zmalloc(sizeof(*cs)); |
| 5281 | cs->conn = conn; |
| 5282 | |
| 5283 | cs->last_dbid = -1; |
| 5284 | cs->last_use_time = server.unixtime; |
| 5285 | dictAdd(server.migrate_cached_sockets,name,cs); |
| 5286 | return cs; |
| 5287 | } |
| 5288 | |
| 5289 | /* Free a migrate cached connection. */ |
| 5290 | void migrateCloseSocket(robj *host, robj *port) { |
no test coverage detected