EulerianTechnologies / eredis

Fast and light Redis C client library built over Hiredis, thread-safe, write replication, auto-reconnect, sync pool, async libev.
BSD 3-Clause "New" or "Revised" License
81 stars 38 forks source link

eredis connects but does not SET anything via async connection #13

Closed gencer closed 6 years ago

gencer commented 6 years ago
e = eredis_new();
eredis_timeout( e, 200 );
eredis_r_max( e, 50 );
eredis_r_retry( e, 1 );

eredis_host_add( e, "127.0.0.1", 6379 );

eredis_pc_cmd( e, "AUTH passwd" );
eredis_pc_cmd( e, "SELECT 1");
eredis_run_thr( e );
eredis_w_cmd( e, "SET testkey 10" );

With this snippet (I trimmed variable declarations, by the way) I am able to connect redis-server as I checked via connection tools and also by redis itself. However, testkey does not SET. The most interesting thing is, sometimes (randomly) I see that this teskey declared successfully without reason. Like redis get the key but do some delay. However, this is not simply a delay. It happens randomly. After few minutes maybe that key will be set.

Is there any reason to have such behavior on my end? Redis server is v4.

guillaumef commented 6 years ago

The possible reason could be your binary is ending just after the w_cmd (even if you make a eredis_free just after). The write process and eredis_free is non-blocking by design. It means that if the process stops, a batch of write request(s) can be lost before having any chance to be sent and reach a redis server.

Try to add a sleep(1) after the eredis_w_cmd, you should see your key inserted.

gencer commented 6 years ago

@guillaumef, I've tweaked threads in my app and initialized eredis based on thread model. It just works as expected now even without sleep(1);

Thank you for the reply.

guillaumef commented 6 years ago

Yes, you need to maintain the eredis_t alive across your threads. It is how it is designed and efficient. w commands are thread-safe, non-blocking. You can call them accross threads on the same eredis_t. r commands are reentrant per eredis_r. You can also get the number of writes in queue with eredis_w_pending() if you need to wait for all writes to terminate before calling eredis_free and exit.