-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add managers layer to client #44
Add managers layer to client #44
Conversation
ff63182
to
12dcaba
Compare
Signed-off-by: Yury-Fridlyand <[email protected]>
3b5d20b
to
1bff530
Compare
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
|
||
private final ClientState.ReadOnlyClientState clientState; | ||
|
||
/** Unique request ID (callback ID). Thread-safe and overflow-safe. */ | ||
private final AtomicInteger requestId = new AtomicInteger(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we not use CONNECTION_PROMISE_ID in the constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ok, since registerConnection
calls to registerRequest
and share the same future array
var future = new CompletableFuture<Response>(); | ||
responses.put(callbackId, future); | ||
return Pair.of(callbackId, future); | ||
} | ||
|
||
public CompletableFuture<Response> registerConnection() { | ||
return connectionPromise; | ||
var res = registerRequest(); | ||
if (res.getKey() != CONNECTION_PROMISE_ID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, to protect vs re-using a client for another connection
if (callbackId == 0) { | ||
connectionPromise.completeAsync(() -> response); | ||
int callbackId = | ||
clientState.isInitializing() ? response.getCallbackIdx() : CONNECTION_PROMISE_ID; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a comment to say that connection responses don't return a callbackIdx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 647d802.
connectionPromise.completeAsync(() -> response); | ||
int callbackId = | ||
clientState.isInitializing() ? response.getCallbackIdx() : CONNECTION_PROMISE_ID; | ||
var future = responses.get(callbackId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we avoid using var
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here or everywhere?
responses.get(callbackId).completeAsync(() -> response); | ||
responses.remove(callbackId); | ||
// TODO: log an error. | ||
// probably a response was received after shutdown or `registerRequest` call was missing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only really happen after shutdown...? should we check the state and just log that a response was completed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a part of logging task
* | ||
* @param key The key name | ||
*/ | ||
public CompletableFuture<String> get(String key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this - we only need submitNewRequest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which class should call get
/set
? Should I do submitNewRequest
public then?
* @param key The key name | ||
* @param value The value to set | ||
*/ | ||
public CompletableFuture<String> set(String key, String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can remove
} else if (response.hasRespPointer()) { | ||
return RedisValueResolver.valueFromPointer(response.getRespPointer()).toString(); | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this doesn't happen, we should throw Exception instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 647d802
"Unexpected response data: " | ||
+ RedisValueResolver.valueFromPointer(response.getRespPointer())); | ||
} | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only if something went completely wrong on rust side. Surprising, protobuf allows to build such response object with no complains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in 647d802
import redis_request.RedisRequestOuterClass.Routes; | ||
import redis_request.RedisRequestOuterClass.SimpleRoutes; | ||
|
||
public class RequestBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be RedisRequestBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, we have 2 types of requests: RedisRequest
and ConnectionRequest
and this guy builds both.
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
java/client/src/main/java/babushka/connectors/handlers/CallbackDispatcher.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
synchronized (responses) { | ||
if (callbackId == null) { | ||
long size = responses.mappingCount(); | ||
callbackId = (int) (size < Integer.MAX_VALUE ? size : -(size - Integer.MAX_VALUE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just protect if this wraps around and re-creates zero... but this scenario would be rare and seriously bad.
68b42a5
into
java/integ_yuryf_client_part2
Part 2 of client implementation. See part 1 in #43/valkey-io#670
The tracking task: https://github.com/orgs/Bit-Quill/projects/4/views/9?pane=issue&itemId=48023248
Proposed usage in
Client
class:And
Awaiter
: