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

Redis object #3

Closed
WeiChihChern opened this issue Dec 13, 2018 · 12 comments
Closed

Redis object #3

WeiChihChern opened this issue Dec 13, 2018 · 12 comments

Comments

@WeiChihChern
Copy link

WeiChihChern commented Dec 13, 2018

Hello, is there any way of creating a sw::redis::Redis object without passing anything, and then connect the object to redis afterward?

sw::redis::Redis *redis = new sw::redis::Redis(config) <- this run np on mac os with clang, but have bad_alloc issue on ubuntu with g++.

Also, is there any way to check the connection result? Thank you.

@sewenew
Copy link
Owner

sewenew commented Dec 13, 2018

By now, no such interface.

Can you show me your complete code for constructing Redis, and the complete error message?

Also please tell me your gcc version, and hiredis version. Thanks!

@sewenew
Copy link
Owner

sewenew commented Dec 14, 2018

My dev environment is: Ubuntu 18.04.1 LTS \n \l, gcc version 7.3.0, with latest hiredis and Redis-plus-plus. I CANNOT reproduce your problem with the following code:

try {
    ConnectionOptions config;
    config.host = "127.0.0.1";
    sw::redis::Redis *redis = new sw::redis::Redis(config);
    cout << redis->ping() << endl;
    delete redis;
} catch (const Error &err) {
    cout << "redis error: " << err.what() << endl;
} catch (const exception &e) {
    cout << "std error: " << e.what() << endl;
}

Since you get a bad_alloc problem, you might need to check if you still have enough memory to run your code.

@sewenew
Copy link
Owner

sewenew commented Dec 14, 2018

Also, is there any way to check the connection result? Thank you.

There's no such interface. The connection is lazily created. The constructor won't create a connection to Redis. Instead, only when the first time you send command with Redis object, it creates a connection to Redis, and reuses the connection for subsequent commands.

If it fails to connect to Redis or the connection is broken, it will throw an exception, i.e. sw::redis::Error. The next time you try to send command with the same Redis object, it will automatically try to reconnect to the server. So normally, if the connection is broken you don't need to create a new Redis object, but just retry the command.

@WeiChihChern
Copy link
Author

The next time you try to send command with the same Redis object, it will automatically try to reconnect to the server. So normally, if the connection is broken you don't need to create a new Redis object, but just retry the command.

Does that mean, using the same Redis object for sending stuff (i.e. redis.set()) will automatically reconnect to redis if connection failed (will redis.set() try to resume connection)?
My current workaround is to create a new object and connect to redis every time when I want to send something to redis (i.e. redis.set() & redis.publish()). But I'm worried this is going to be expensive?
I will definitely try your code, and use the newer g++ to see if it worked.

Thanks

@sewenew
Copy link
Owner

sewenew commented Dec 14, 2018

using the same Redis object for sending stuff (i.e. redis.set()) will automatically reconnect to redis if connection failed (will redis.set() try to resume connection)?

YES. When you call Redis::set or other methods, it will get a connection from the underlying connection pool, and check if the connection is broken. If it's NOT broken, it will send the command to Redis. Otherwise, it will try to reconnect to the server. If it reconnects successfully, it sends the command, and return the new connection to the connection pool, so that subsequent call can reuse the connection. On the other hand, if it fails to reconnect, it throws an exception.

But I'm worried this is going to be expensive?

YES, it's very expensive. You should NOT do that. Instead, you should create a Redis object, and reuse it.

auto redis = Redis("tcp://127.0.0.1");
for (int i = 0; i != 100; ++i) {
    auto key = to_string(i);
    try {
        redis.set(key, "value");    // reuse Redis object.
    } catch (const Error &e) {
        // Something bad happens. However, if the connection is broken,
        // next call to Redis::set will try to reconnect the server automatically.
        // So we just log the error, and continue.
        continue;
    }
}

I'll add a specific exception class to distinguish connection broken error and other errors.

@WeiChihChern
Copy link
Author

WeiChihChern commented Dec 14, 2018

Can I have a snippet of you makefile where you link libredis++ & libhiredis? I think I might have not correctly linked them. I know path will be different, but just want to double check in link everything needed. Thanks

It's weird that no compile issue when only has sw::redis::Redis *redis = new sw::redis::Redis(config), but an error of undefined reference to redis->ping() occurred when adding redis->ping() for testing.

Update: I keep getting undefined reference to `sw::redis::Redis::ping()' error. If removed Redis::ping() it compiled without error, but like I said it's still not linked correctly and that's probably why I got bad_alloc in the first place.

@sewenew
Copy link
Owner

sewenew commented Dec 15, 2018

app : app.o
    g++ -std=c++11 -o app app.o /home/user/install/hiredis/lib/libhiredis.a /home/user/install/redis-plus-plus/lib/libredis++.a

app.o : app.cpp
    g++ -std=c++11 -c app.cpp -I/home/user/install/redis-plus-plus/include -I/home/user/install/hiredis/include

You can show me your code, the path of the installed hiredis & redis++, and your makefile. So that I might figure out the problem.

@WeiChihChern
Copy link
Author

Also, do you remember which header files of your redis-plus-plus pull the hiredis's hiredis.h

@sewenew
Copy link
Owner

sewenew commented Dec 18, 2018

When compiling hiredis, the make install command will install all required headers. Check your install path.

@sewenew
Copy link
Owner

sewenew commented Dec 21, 2018

Hi @WeiChihChern ,

Have you solved the problem?

Recently I found redis-plus-plus is NOT compatible with some old version hiredis. I've fixed the problem. Now the minimum version requirement for hiredis is v0.12.1.

If you still have the problem, you can update redis-plus-plus and try again.

Regards

@WeiChihChern
Copy link
Author

Somehow I just can't link your lib to my project. But, linking hiredis is working. Since I'm only using few functions from hiredis, I did my own implementation for it.

Thank you for the assistance you have offered, appreciated!

@sewenew
Copy link
Owner

sewenew commented Dec 25, 2018

These days I CANNOT reproduce your problem with different gcc and clang versions on ubuntu, centos and macos. So I'll close the issue.

However, if you want to retry redis-plus-plus in the future, you are always welcomed to reopen this issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants