bool Redox::connectUnix(const string &path, function<void(int)> connection_callback) { path_ = path; user_connection_callback_ = connection_callback; if (!initEv()) return false; // Connect over unix sockets ctx_ = redisAsyncConnectUnix(path.c_str()); if (!initHiredis()) return false; event_loop_thread_ = thread([this] { runEventLoop(); }); // Block until connected and running the event loop, or until // a connection error happens and the event loop exits { unique_lock<mutex> ul(running_lock_); running_waiter_.wait(ul, [this] { unique_lock<mutex> ul(connect_lock_); return running_.load() || connect_state_ == CONNECT_ERROR; }); } // Return if succeeded { unique_lock<mutex> ul(connect_lock_); return connect_state_ == CONNECTED; } }
static client createClient(void) { client c = zmalloc(sizeof(struct _client)); if (config.unixSocket){ c->context = redisAsyncConnectUnix(config.unixSocket); }else{ c->context = redisAsyncConnect(config.hostip,config.hostport); } c->context->data = c; redisAsyncSetDisconnectCallback(c->context,clientDisconnected); if (c->context->err) { fprintf(stderr,"Connect: %s\n",c->context->errstr); exit(1); } redisAeAttach(config.el,c->context); listAddNodeTail(config.clients,c); issueRequest(c); return c; }
static PHP_METHOD(swoole_redis, connect) { char *host; zend_size_t host_len; long port; zval *callback; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz", &host, &host_len, &port, &callback) == FAILURE) { RETURN_FALSE; } if (host_len <= 0) { swoole_php_error(E_WARNING, "redis server host is empty."); RETURN_FALSE; } swRedisClient *redis = swoole_get_object(getThis()); redisAsyncContext *context; if (strncasecmp(host, ZEND_STRL("unix:/")) == 0) { context = redisAsyncConnectUnix(host + 5); } else { if (port <= 1 || port > 65535) { swoole_php_error(E_WARNING, "redis server port is invalid."); RETURN_FALSE; } context = redisAsyncConnect(host, (int) port); } if (context->err) { swoole_php_error(E_WARNING, "failed to connect to the redis-server[%s:%d], Erorr: %s[%d]", host, (int) port, context->errstr, context->err); RETURN_FALSE; } php_swoole_check_reactor(); if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS)) { SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_READ, swoole_redis_onRead); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_WRITE, swoole_redis_onWrite); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_ERROR, swoole_redis_onError); } redisAsyncSetConnectCallback(context, swoole_redis_onConnect); redisAsyncSetDisconnectCallback(context, swoole_redis_onClose); zend_update_property_long(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("sock"), context->c.fd TSRMLS_CC); zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), callback TSRMLS_CC); redis->context = context; context->ev.addRead = swoole_redis_event_AddRead; context->ev.delRead = swoole_redis_event_DelRead; context->ev.addWrite = swoole_redis_event_AddWrite; context->ev.delWrite = swoole_redis_event_DelWrite; context->ev.cleanup = swoole_redis_event_Cleanup; context->ev.data = redis; zend_update_property_string(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("host"), host TSRMLS_CC); zend_update_property_long(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("port"), port TSRMLS_CC); if (SwooleG.main_reactor->add(SwooleG.main_reactor, redis->context->c.fd, PHP_SWOOLE_FD_REDIS | SW_EVENT_WRITE) < 0) { swoole_php_fatal_error(E_WARNING, "swoole_event_add failed. Erorr: %s[%d].", redis->context->errstr, redis->context->err); RETURN_FALSE; } if (redis->timeout > 0) { php_swoole_check_timer((int) (redis->timeout * 1000)); redis->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, redis, swoole_redis_onTimeout); } sw_zval_add_ref(&redis->object); swConnection *conn = swReactor_get(SwooleG.main_reactor, redis->context->c.fd); conn->object = redis; }
/* Internal host connect - Sync or Async */ static int _host_connect( host_t *h, eredis_reader_t *r ) { redisContext *c; if (r) { /* Sync - not in EV context */ c = (h->port) ? redisConnect( h->target, h->port ) : redisConnectUnix( h->target ); if (! c) { fprintf(stderr, "eredis: error: connect sync %s NULL\n", h->target); return 0; } if (c->err) { #if EREDIS_VERBOSE>0 printf( "eredis: error: connect sync %s %d\n", h->target, c->err); #endif redisFree( c ); return 0; } r->ctx = c; r->host = h; } else { redisAsyncContext *ac; /* ASync - in EV context */ ac = (h->port) ? redisAsyncConnect( h->target, h->port ) : redisAsyncConnectUnix( h->target ); if (! ac) { printf( "eredis: error: connect async %s undef\n", h->target); return 0; } if (ac->err) { #if EREDIS_VERBOSE>0 printf( "eredis: error: connect async %s %d\n", h->target, ac->err); #endif redisAsyncFree( ac ); return 0; } h->async_ctx = ac; /* data for _redis_*_cb */ ac->data = h; /* Order is important here */ /* attach */ redisLibevAttach( h->e->loop, ac ); /* set callbacks */ redisAsyncSetDisconnectCallback( ac, _redis_disconnect_cb ); redisAsyncSetConnectCallback( ac, _redis_connect_cb ); c = (redisContext*) ac; } /* Apply keep-alive */ #ifdef HOST_TCP_KEEPALIVE if (h->port) { redisEnableKeepAlive( c ); if (r && (h->e->sync_to.tv_sec||h->e->sync_to.tv_usec)) { redisSetTimeout( c, h->e->sync_to ); } } #endif /* Override the maxbuf */ c->reader->maxbuf = EREDIS_READER_MAX_BUF; return 1; }