-
Notifications
You must be signed in to change notification settings - Fork 60
Add context support #173
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 context support #173
Conversation
ffa9009
to
6ced96d
Compare
I have considered two options of API with context support: First of all I see this as anywhere in go: req := NewSelectRequest(spaceNo).
Index(indexNo)
conn.Do(ctx context.Context, req requestObj) Also there is an option to use the request object and pass the context with some method like: req := NewSelectRequest(spaceNo).
Index(indexNo).
WithCtx(context.Background())
conn.Do(req) I like the first one due to its native "go" spirit. Also I don't see the way to implement the second option |
4164a29
to
e7de5a1
Compare
Tried to speed up |
a45284f
to
a5ae500
Compare
An overhead of communicating with the Tarantool instance is much bigger than the effect of such optimizations. It's expected results. |
Yes, that seems to be truth, maybe we should consider the creating some mock package for tarantool for getting more clean results. @Totktonada your thoughts? See, for example, the mock package for Redis https://github.com/go-redis/redismock. |
Go has examples of using |
Thank you for the links, I've missed that http package uses the similar approach with requests objects. |
d81c1c9
to
0eb34cd
Compare
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.
Thanks for this pull request! I think you need to move the Context handling from the Future to the Connection, but we can discuss it in the notes.
0eb34cd
to
40302db
Compare
d2e155b
to
c01e004
Compare
What we should got as a result if a Connection object receive response in |
When we call fut.Get(), we got closed channel |
Yes, in the current implementation. But shouldn't the request be canceled after 1s? |
3169baa
to
9cd532f
Compare
I've reviewed a Connection.reader() goroutine - I'm ok with the current implementation. |
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.
Nothing critical, just few possible improvements.
9cd532f
to
6e11534
Compare
6e11534
to
1595398
Compare
98bc358
to
6cc18d9
Compare
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.
Thank you for the great work! I'm still confused by two counters for request ids, but it is not critical.
You can improve the commit message. Proposal
looks strange here + 72-characters per a commit message body line. It may be something like that:
@@ -1,9 +1,8 @@
-api: proposal to add the context support
+api: context support
-This patch adds the support of using context in API.
-The proposed API is based on using request objects.
-Added tests that cover almost all cases of using the context
-in a query. Added benchamrk tests are equivalent to other,
-that use the same query but without any context.
+This patch adds the support of using context in API. The API is based
+on using request objects. Added tests that cover almost all cases of
+using the context in a query. Added benchamrk tests are equivalent to
+other, that use the same query but without any context.
Closes #48
In general, I am happy with the pull request, you can not expect new conversations from me.
6cc18d9
to
cd1c932
Compare
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.
AFAIU, two request lists are used to support adding or removing context in the runtime. Is that right?
Two requests list are needed to avoid the influence of timeouts-goroutine on requests with context. |
0e0594d
to
b539f85
Compare
b539f85
to
107692d
Compare
So now we don't support any timeouts with context requests? Is it reflected anywhere (like in doc)? |
107692d
to
1ecc707
Compare
Added now, thank you for noting this. |
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 be LGTM after resolving remaining comments.
This patch adds the support of using context in API. The API is based on using request objects. Added tests that cover almost all cases of using the context in a query. Added benchamrk tests are equivalent to other, that use the same query but without any context. Closes #48
1ecc707
to
e96f16b
Compare
This patch removes the padding field in a connection shard structure. The _pad field is unused in the code and there is no sense to keep it anymore. Closes #197
What has been done? Why? What problem is being solved?
This patch adds the support of using context in API. The API is based
on using request objects. Added tests that cover almost all cases of
using the context in a query. Added benchamrk tests are equivalent to
other, that use the same query but without any context.
Closes #48
I didn't forget about (remove if it is not applicable):
Related issues:
#48
Context support
Context support supposes a mechanism of canceling requests to instance.
The canceling happens when the timeout/deadline is over or the cancel function is called.
Also contexts may keep key-value inside.
API
There are two ways of representing context in API.
Standard
http
package supports it inside the Request object.For outgoing client requests, the context controls cancellation.
For incoming server requests, the context is canceled when the client's connection closes,
the request is canceled (with HTTP/2), or when the ServeHTTP method returns.
The second approach.
The interface package
database/sql
supposes the next way of passing contexts.The proposal for API:
It is decided to use request objects due to their flexibility and comfortability.
There is also no need to add similar methods to the common API with only difference, that
the first argument is a context.
Example:
Implementation
Let's consider the next points before discussing the implementation of adding context support.
is come or the context is done.
The architecture of the internal queue
Proposal
We will keep a context inside the
Future
object, so it is associated with the request lifetime.We add a goroutine that scans all the queues of
Future
objects and removes each Future that has an expiredcontext.
We keep two queues for Futures with context not nil and other Futures. So each goroutine has the responsibility
over it's own type of Futures. (Consider side effects later)
When we have already removed the Future due to it's cancelled context, we can get a response from the instance
for that Future, then we log a message that have received an unexpected response from the instance. We assume that
it is expected behavior.
We also check if the context is cancelled:
.Get()
(sync call) for the Future.This approach let us almost the full control over the Future lifetime.
Problems
contexts
-goroutine work.Premature optimization.
One of the reasons to leave the context inside the Future object, was to avoid
the need to check context only with this goroutine every nanosecond(or some other time).
I would like to have this goroutine as a garbage collector just for cleaning up the queue when it is needed.
I also had an idea to have an internal atomic counter of a Futures count inside and run this goroutine when
this count is critical (we could configure this critical number and have a dependency from GOMAXPROC by default).
Benchmarks
Environment:
Setup:
Comparing between two queries:
and
50 testing goroutines
100 testing goroutines
500 testing goroutines
1000 testing goroutines
Alternative way
Let us keep the context only inside the request object and check if the context or the future is "done"
in a separated goroutine.
The API is the same one:
The goroutine that scans ready channels:
Benchmarks
Environment:
Setup:
Comparing between two queries:
and
50 testing goroutines:
100 testing goroutines:
500 testing goroutines:
1000 testing goroutines: