openresty / lua-resty-redis

Lua redis client driver for the ngx_lua based on the cosocket API
1.9k stars 449 forks source link

[Feature Request] Pipeline coroutine safety #278

Open StarlightIbuki opened 2 months ago

StarlightIbuki commented 2 months ago

When using a pipeline combined with a coroutine, some commands might get mixed into the pipeline. Please consider introducing pipeline objects, e.g.:

local pipe = red:start_pipeline()
pipe:set(...)
-- ...
for result in ipairs(pipe:commit()) do
  -- ...
end
spacewander commented 2 months ago

In the current implementation, the underlay connection and the red object is 1:1. The pipeline in Redis will occupy the connection. So red:start_pipeline() is probably a syntax sugar which creates another redis connection with the current configuration of red.

StarlightIbuki commented 2 months ago

In the current implementation, the underlay connection and the red object is 1:1. The pipeline in Redis will occupy the connection. So red:start_pipeline() is probably a syntax sugar which creates another redis connection with the current configuration of red.

or we can block the connection only when committing the pipeline, and let the user decide whether to create another connection?

spacewander commented 2 months ago

What do you mean by "block the connection only when committing the pipeline"?

StarlightIbuki commented 2 months ago

What do you mean by "block the connection only when committing the pipeline"?

Instead of creating a new connection, we lock the connection until the pipeline finishes

spacewander commented 2 months ago

IMHO, it would make thing complex if we put the connection management inside the redis client. If we ensure there is only one coroutine that can write to a cosocket, then we can implement pipeline safety in a lock-free way. This mechanism can be put outside a client so it can be used as a general solution, instead of being a complex and hard-to-maintain code inside a library.

StarlightIbuki commented 2 months ago

IMHO, it would make thing complex if we put the connection management inside the redis client. If we ensure there is only one coroutine that can write to a cosocket, then we can implement pipeline safety in a lock-free way. This mechanism can be put outside a client so it can be used as a general solution, instead of being a complex and hard-to-maintain code inside a library.

I agree. I'm now using a strategy to clone if the connection is doing a pipeline.