-
Notifications
You must be signed in to change notification settings - Fork 99
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
Semi-RFC: Consolidate http behavior #272
Conversation
pkg/transport/client_low.go
Outdated
|
||
// Base headers | ||
req.Header.Set("Content-Type", contentType) | ||
req.Header.Set("Content-Encoding", encoding) |
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.
Encoding and type could be enums for a little bit more type safety. Currently there is a risk to pass two strings in swapped positions.
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.
Swapping is definitely a hazard, but I don't know how to prevent it. Go lacks enums (near as I can tell), and will happily promote a string to an alias of it, breaking the type safety: https://play.golang.org/p/lzAsJ8gGB_O
I could do a sanity check for valid values, but that seems overkill. Is there something I'm 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.
Yeah, what we are seeing in that example is the behavior of "untyped literals". This does not compile though because x
is typed vs untyped literal. https://play.golang.org/p/wiCUwuQqj5g
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.
Ahh! I see now. https://play.golang.org/p/xItV45OW49V
I'll fix it up in the cleanup commit (waiting on other feedback, I know the team is busy atm)
- 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.
https://blog.golang.org/constants see the String constants
section
pkg/transport/helpers.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
json.ReturnStream(stream) |
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.
So if there was an error we don't return the stream? This line should be after Flush
?
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.
Good catch!
- this
backoff, err := util.GetRetryFromViper(sub) | ||
if err != nil { | ||
tp.logger.WithField("name", name).WithError(err).Error("failed to load retry policy") | ||
return nil, err |
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 there a reason to both log and return the error? Ideally should only return it
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.
Not specifically. Depending on the call stack it could actually end up dropping a few duplicate logs - they're all fatal though (fail early), so it's something I didn't put a lot of thought in to.
For preference I'd actually make it a .Fatal()
. I've been slowly pushing to remove errors from the code (eg, this whole refactor is fire and forget) with a view to either fail-fast on startup, or handle runtime errors immediately when there's maximum context available.
Ultimately a lot of the error paths just pop out somewhere high level with a log line, and they lose context that could be supplied by an immediate log (such as the transport name in this case).
There's an argument to be made for more strongly typed errors to provide context, but a) I'm lazy, and b) the only way to expose that context is through error.Error()
which means it's not exposed as structured log data.
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.
Ok, I see your point. I think this code can be improved further if config parsing is moved into NewTransportPool()
and viper is no longed referenced/used. I don't know if it's easy to do this. Also, just terminating the program in the middle of the pooling code would be weird. Testing and reusing this code becomes harder.
pkg/transport/pool.go
Outdated
@@ -80,16 +139,37 @@ func (tp *TransportPool) newClient(name string) (*Client, error) { | |||
return nil, err | |||
} | |||
|
|||
headers := map[string]string{} | |||
headerKeys := []string{} |
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.
Could pre-allocate the exact size for both
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
retryPolicy := v.GetString(paramRetryPolicy) | ||
|
||
if retryInterval <= 0 { | ||
return nil, errors.New(paramRetryInterval + " must be positive") |
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.
Could use fmt.Errorf()
here and below for consistency with other places where things are not strings. Not a big deal.
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.
My main thought was it should turn it in to a static string at compile time rather than runtime. I don't know if that will actually occur with either "" + ""
or fmt.Sprintf("%s", "")
, but that was the intent.
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestSemaphoreUnlimited(t *testing.T) { |
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.
t.Parallel()
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
d4cb6bc
to
e1cbdba
Compare
Rebased off master, fixed the issues mentioned. Last commit is a bit derpy because I did a |
This adds a richer retry policy framework configurable through Viper, allowing more centralisation and consistency.
There's also a null semaphore which lets anything in, which can be used to provide unbound access without extra logic.
…mplement high level constructs
7fd4aeb
to
c24cca1
Compare
Hey @tiedotguy , you currently have a merge conflict on this, would you be able to resolve this? |
No merge conflicts, simply happy accidents. This branch will return later. |
This is the next change in the whole transport refactor saga, leading towards streaming (#10, #84, #159), InfluxDB (#14), and clustering. Nothing here is consumed currently, it's just the primitives. As it's getting rather large already, I wanted to minimize the review size. Commits are relatively stand-alone.
This PR is not expected to be merged yet, because there's documentation mismatches (due to lack of consumption). I'll be working on updating consumers in a subsequent PR, but didn't want to get too deep in to that in case there's feedback on the API (I'm not a huge fan of the
TransportOptions
for example)