Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

##Use a custom connection policy when IP port cannot be obtained directly## #421

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,38 @@ connection_options.socket_timeout = std::chrono::milliseconds(200);
// Connect to Redis server with a single connection.
Redis redis1(connection_options);

// ... Other codes.
// We can use custom connect policy as follows.
// First, we define a function which can connect to redis server.
redisContext* customConnect(void *arg) {
if (!arg) {
// It is not necessary to throw an exception.
// Because you do not need any parameters to obtain.
throw Error("myConnectTCP parameter is invalid");
}

// If you need a parameter, type conversion is necessary when you know it's not nullptr.
CustomConfType someConf = *(reinterpret_cast<CustomConfType*>(arg));

// Do something as you need.
// For example, obtain the real IP address through service discovery.
doSomething();

// Create a redisContext instance and return it's address.
// Maybe you can refer to the following function.
return redisConnect(hostIP.c_str(), hostPort);

}
// ... Other codes.
// Parameter to be passed to the custom function.
CustomConfType myConf;
connection_options.type = ConnectionType::CUSTOM; // It's required if you want to use custom connect policy.
connection_options.customConnect = customConnect; // It's required if you want to use custom connect policy.
connection_options.customConnectArg = &(myConf); // Optional. The default is nullptr.

// Connect to Redis server with a single connection and customize connect policy.
Redis redis2(connection_options);

ConnectionPoolOptions pool_options;
pool_options.size = 3; // Pool size, i.e. max number of connections.

Expand All @@ -654,7 +686,7 @@ pool_options.wait_timeout = std::chrono::milliseconds(100);
pool_options.connection_lifetime = std::chrono::minutes(10);

// Connect to Redis server with a connection pool.
Redis redis2(connection_options, pool_options);
Redis redis3(connection_options, pool_options);
```

**NOTE**: if you set `ConnectionOptions::socket_timeout`, and try to call blocking commands, e.g. `Redis::brpop`, `Redis::blpop`, `Redis::bzpopmax`, `Redis::bzpopmin`, you must ensure that `ConnectionOptions::socket_timeout` is larger than the timeout specified with these blocking commands. Otherwise, you might get `TimeoutError`, and lose messages.
Expand Down
8 changes: 7 additions & 1 deletion src/sw/redis++/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,13 @@ Connection::ContextUPtr Connection::Connector::_connect() const {
case ConnectionType::UNIX:
context = _connect_unix();
break;

case ConnectionType::CUSTOM:
if (_opts.customConnectFn != nullptr) {
context = _opts.customConnectFn(_opts.customConnectArg);
} else {
throw Error("Function customConnectFn is invalid");
}
break;
default:
// Never goes here.
throw Error("Unknown connection type");
Expand Down
12 changes: 11 additions & 1 deletion src/sw/redis++/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ namespace redis {

enum class ConnectionType {
TCP = 0,
UNIX
UNIX,
CUSTOM
};

struct ConnectionOptions {
Expand Down Expand Up @@ -82,6 +83,15 @@ struct ConnectionOptions {
// RESP version.
int resp = 2;

// if specify the `type` is ConnectionType::CUSTOM, it will use the customConnectFn create a
// connection to redis server. This allows users to implement their own connection logic.
// After all, in many cases, the domain name or IP address is not given directly.
// For example, in the scenario of deploying some Redis instances with a microservice mode, a service name is given
redisContext* (*customConnectFn)(void *arg) = nullptr;

// parameter of custom functions
void *customConnectArg = nullptr;

private:
ConnectionOptions _parse_uri(const std::string &uri) const;

Expand Down