I made a sketch to this feature.
First of all, since we already have Pipeline, I'm trying to respect its usage.
By user side, it would be equal to current Pipeline.
```
// assume JedisCluster named "cluster" is initialized
ClusterPipeline p = cluster.pipelined();
Response<String> string = p.get("string{1}");
Response<String> list = p.lpop("list{1}");
// ...
p.sync();
String stringVal = string.get();
String listVal = list.get();
// ...
```
By ClusterPipeline, it has a queue storing commands (transformed to raw, byte[]) and Response<?> for building.
Since we should treat MOVED, and ASK, and we should resend all commands when MOVED and ASK occur, so we cannot use current strategy for Pipeline. (adding commands to OutputStream and flush it when sync() called)
When ClusterPipeline.cmdxxx() (ex. set()) is called,
1. check slot number
2. convert command with arguments to raw byte[] .
3. generate Response<?> with getResponse(Builder), traditional approach.
4. push (1, 2, 3) to queue
5. return 3 (generated, but not built Response<?>)
When ClusterPipeline.sync() is called, (assume ClusterPipeline has reference of JedisCluster instance)
1. Check all command's slots
1.a. If slots count is 2 or upper, it throws JedisClusterCrossSlotException from #687 currently waiting for merge.
2. Get a connection related to slot
2.a. If it doesn't exist from slot-node cache, get a random connection
3. Send all commands at once, by joining all byte[]s to one.
4. Build responses
5. Check first response
5.a. If first response contains MOVED or ASK, update slot-node cache and go to 2. (with increasing redirect count)
6. Return (Responses should be built, so users can play with them.)
Please review my sketch, and let me know there're sth. to add, or sth. to be fixed.
Regards.
Jungtaek Lim (HeartSaVioR)
2014년 11월 4일 화요일 오전 7시 21분 47초 UTC+9, 임정택 님의 말: