I want to make a copy of a context object - a request context to be exact, and make use of it later on in a separate go routine.
Problem is if I derive the request context using context.WithCancel(reqCtx) once the HTTP handler for this request is finished, not only will the original request context be cancelled, but also the copy of the request context will also be canceled.
I'd like to be able to copy the original request context and not have it canceled by the original context after the HTTP handler has finished executing.
Here's how to make a context that uses values from some other context, but not cancelation:
type valueOnlyContext struct{ context.Context }
func (valueOnlyContext) Deadline() (deadline time.Time, ok bool) { return }
func (valueOnlyContext) Done() <-chan struct{} { return nil }
func (valueOnlyContext) Err() error { return nil }
Use it like this:
ctx := valueOnlyContext{reqCtx}
Using the values without cancelation is probably outside the design intent of the context package. If the designers of the package thought this is a good thing, I would have expected them to bundle up the above in a context package function.
Related
I am having difficulty writing tests for this 3rd party library I am importing. I think this is because I want my CustomClient struct to have a client interface instead of the *banker.Client. This is making testing very difficult because it's hard to mock a *banker.Client. Any ideas how I can correctly turn this into an interface? So I can easily write mock tests against it and set up a fake client?
type CustomClient struct {
client *banker.Client //I want to change this to an interface
name string
address string
}
func (c *CustomClient) SetHttpClient(httpClient *banker.Client) { //I want to accept an interface so I can easily mock this.
c.client = httpClient
}
The problem is that banker.Client is a third party client I am importing with many structs and other fields inside of it. It looks like this:
type Client struct {
*restclient.Client
Monitor *Monitors
Pricing *Pricing
Verifications *Verifications
}
The end result is that my code looks like this:
func (c *CustomClient) RequestMoney() {
_, err := v.client.Verifications.GetMoney("fakeIDhere")
}
Given methods over fields on the struct, it sure wouldn't be a simple solution. However, we can try to minimize the lengthy test cases on the current package.
Add another layer (package) between your working package and banker. Simplifying the code in example to explain.
Let's say your banker package has the following code:
type Client struct {
Verification *Verification
}
type Verification struct{}
func (v Verification) GetMoney(s string) (int, error) {
...
}
Create another package that imports the banker and has interface defined, say bankops package:
type Bank struct {
BankClient *banker.Client
}
type Manager interface {
GetMoney(s string) (int, error)
}
func (b *Bank) GetMoney(s string) (int, error) {
return b.BankClient.Verification.GetMoney(s)
}
Note: The actual issue (test without interface) is still here in bankops package, but this is easier to test as we are only forwarding the result. Serves the purpose of unit tests.
Finally, in the current package (for me, it is main package), we can
type CustomClient struct {
client bankops.Manager
}
func (c *CustomClient) RequestMoney() {
_, err := c.client.GetMoney("fakeIDhere")
...
}
func main() {
client := &CustomClient{
client: &bankops.Bank{
BankClient: &banker.Client{
Verification: &banker.Verification{},
},
},
}
client.RequestMoney()
}
For working example, check in Playground.
You may add the setters or builders pattern as you were doing in your original code snippet to make the fields (like BankerClient) unexported.
I think it is impossible to make it into interface directly
because we should use the member variables of the Client.
How about making its member into interface?
For example,
for _, test := []struct{}{
testVerification VerificationInterface
}{{
testVerification: v.Client.Verifications
},{
testVerification: VerficationMock
}}{
// test code here
}
My understanding of the uses of pointer receiver and value receiver is rather weak. Here's a scenario where I can't decide between the two:
I recently learned to re-use http.Client objects already created instead of creating a new http.Client each time, in order to benefit from connection pooling. So I did something like this:
type MailClient struct {
HTTPClient *http.Client
// ... bunch of other stuff
}
func newMailClient( // ... arguments for initializing stuff ) *MailClient {
return &MailClient{
HTTPClient: &http.Client{},
// ... init other stuff
}
}
func (c *MailClient) SendMail( // ... arguments that form a email request ) {
// ... prepare the email request
httpResp, err := c.HTTPClient.Do( // ... args for sending )
if err != nil {
// ... handle error
}
defer httpResp.Body.Close()
// ...
}
This way, as long as SendMail() is called on the same MailClient, I expect the connection pool to kick in (I understand the default MaxIdleConnsPerHost of the http.Transport is default to 2 without customization).
But notice I defined SendMail() to use a pointer receiver? Yup, I don't really know why I did it. I'm just hoping by using a pointer receiver, each time the method is called, it's the same instance of MailClient that's doing the work, and not a copy of it. I also thought the fact that value receiver prevents modifying the receiver is because it's a copy.
I also cautiously defined the HTTPClient field in the MailClient struct to be a pointer of http.Client, for the same reason - I don't know how value pointer works.
So here's to summarise my question:
Will value receivers result in a copy of the receiver being used in the method?
Will changing the receiver type to MailClient affect the connection pooling behavior?
Will changing the HTTPClient field to a http.Client affect the connection pooling behavior?
Connection pooling is implemented in http.Transport. Your application uses the default transport because the application does not set the client transport field.
No matter what the application does with pointer vs value receivers, there is no impact on connection pooling because the application uses the default transport.
The most important part to remember is that method calls translate to function calls with receivers. All rules that apply to function calls apply to method calls with the correspondent type of receiver (value or reference). A good way to see this is by using the following syntax
type XType struct {
A int
B *int
}
func (x XType) Mutate() {
x.A = 1
*x.B = 2
}
func (x *XType) MutateRef() {
x.A = 2
*x.B = 3
}
func main() {
i := 5
x1 := XType{
A: 9999,
B: &i,
}
//calling Mutate as a function passing the receiver by value
XType.Mutate(x1)
log.Printf("%#v", x1)
log.Printf("%#v", *x1.B)
//calling MutateRef as a function passing the receiver by reference
(*XType).MutateRef(&x1)
log.Printf("%#v", x1)
log.Printf("%#v", *x1.B)
}
Another thing to note is that when structs are passed by value, all fields are copied, imagine a pointer as an int, so a copy will still hold the same address value.
Now, it's easy to follow the answers for your questions:
Will value receivers result in a copy of the receiver being used in the method?
Yes, because is the same thing as calling a function passing a value, same rules apply
Will changing the receiver type to MailClient affect the connection pooling behavior
Not really, since the client is a pointer. Even if you call the method using a value receiver, you will still be using the client pointed by the value in your copy
Will changing the HTTPClient field to a http.Client affect the connection pooling behavior?
I don't think so, as the http.Transport is in charge of connection pooling and it is set by reference to the http.Client. Still, your best bet is to go with a pointer to a client
The situation I have now is the same as was asked about in this thread: Meaning of a struct with embedded anonymous interface?
type A interface {
Foo() string
}
type B struct {
A
bar string
}
Idiomatically, coming from a backround in OOP languages, what it looks like this pattern is "trying to say" to me is that B must implement interface A. But I get by now that "Go is different". So, rather than the compile-time check I expected at first, this is happy to compile with or without a
func (B) Foo() string { .... }
present. As the above question points out (paraphrased): "using embedded interfaces in structs is great for when you only want to implement /part/ of an interface".
Presumably, this is because what is happening with this embed is just like in every other case - a value of type B would have an anonymous interface value of type A, as a field. Personally while I find that orthogonality comforting, I also find it confusing that the reflection package would then let me get methods of A directly from B's type this way, and not error/nil if no method with receiver B is present. But - this question isn't about the thinking behind that - it is about how that interface value is initialized after b := B{}:
func main() {
bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
val := res[0].Interface()
fmt.Println(val)
} else {
fmt.Println("DOESNT HAS IT")
}
}
When this is run, it causes a horrible panic
HAS IT: func
panic: runtime error: invalid memory address or nil pointer dereference
... or doesn't - depending on if the compiler/runtime was able to find the above method. So: How can I detect that situation before I trigger it?
That is - is there something about the bMeth value I can use to see that there is no "real" implementation present in the reflection-returned returned Method and func values? Is that more precisely something like "is the pointer to the function in the function table of the anonymous interface value in zero", or what exactly is going on with methods you pull from an interface with reflection where there is no implementation?
Wrapping the whole thing in a goroutine and attempting to run the function under defer/panic isn't the answer - not only because of the expense of the panic/defer but because the function in general might, if it does exist, have side effects I don't want right now...
Do I want something like a run-time implementation that mirrors the compiler's type check? Or is there an easier way? Am I thinking about this incorrectly?
Above example in a Go playground
You needn't reflection to my mind
method_in_table := B.Foo
fmt.Printf("%T \n", method_in_table)
will output you
func(main.B) string
Interface type A initialized at predeclared nil which has no dynamic type
var a A
if a==nil{
fmt.Printf("It's nil")
}
a.Foo()
will give you same error. So practical check can be just
if b.A != nil { b.Foo()}
This question is old with some good answers, but none presents the possibility that this can be done.
Before presenting the solution: I think it's not your job to make sure the implementation does not panic because it fails to set an embedded interface field. Someone could pass an implementation which explicitly defines the methods in which
panic() is called explicitly. You could not detect that case, yet, that implementation wouldn't be any better than a nil embedded interface field.
OK, so how to tell if a method cannot be called because it would panic due to the implementation not being available because the embedded interface field is nil?
You said you can't / don't want to call the method and recover from a panic because if the method is available, this would call it and have its side effect.
The fact is that we don't have to call it. We can just refer to the method via an instance (not type), and then the actual receiver has to be resolved. Of course if the receiver would be the dynamic value of an embedded interface, and if that interface is nil, the resolving will cause a runtime panic, but the method will not be called even if the embedded interface is not nil. Note that this is in fact a Method value, and obtaining a method value evaluates and saves the receiver. This receiver evaluation is what will fail.
Let's see an example:
type A interface {
Foo() string
}
type B struct {
A
}
func (b B) Int() int {
fmt.Println("B.Int() called")
return 0
}
func main() {
b := B{}
_ = b.Int
fmt.Println("We got this far, b.Int is realized")
}
What will this program output? Only "We got this far, b.Int is realized". Because the Int() method is explicitly defined for the B type, and so b.Int can be resolved. And since it's not called, "B.Int() called" will not be printed.
What if we do this:
_ = b.Foo
Since Foo is a promoted method from B.A embedded interface, and b.A is nil, resolving b.Foo will fail at runtime, and produce a runtime error, something like this:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47d382]
goroutine 1 [running]:
main.main()
/tmp/sandbox877757882/prog.go:24 +0x2
But we can recover from this:
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
fmt.Println("This means b.Foo is not realized!")
}
}()
_ = b.Foo
This will output:
Recovered: runtime error: invalid memory address or nil pointer dereference
This means b.Foo is not realized!
Try the examples on the Go Playground.
Let me put my two cents in, after you've already received good answers for your question.
Presumably, this is because what is happening with this embed is just like in every other case - a value of type B would have an anonymous interface value of type A, as a field.
You've basically solved the problem here. This is just a field, but because it's anonymous all its methods are being promoted and you can use them directly on the struct. This is not only related to interfaces, but the problem you've pointed to exists within ordinary structures as well:
package main
type A struct {
}
func (a A) Foo() {
}
type B struct {
*A
}
func main() {
B{}.Foo()
}
This will cause panic. I believe this is expected: we're saying B embeds *A, but then leave it uninitialised, so what am I thinking? We could try to find an analogy here with, for example, C++ and find out it is similar to a null pointer in C++ – how do we deal with it there? We either expect it to be non-null (by a contract) or need to check before using. The latter it what Uvelichitel suggested in the accepted answer and it's by no means correct and there is no better solution I think. Although it's not very plausible. We do expect the caller to know the method they're calling is a promoted method of an anonymous field which is a pointer (or interface) type and as such can be nil. As an author of such code I would either need to make sure it's never nil (contract) or state it clearly in documentation that a caller needs to check it (but why would I embed this type then instead of having normal field, I'm not sure).
It bothers me with interfaces though, because looking back at your example and making A an interface, we have a following problem:
package main
import "fmt"
type A interface {
Foo()
}
type B struct {
A
}
func main() {
var b interface{}
b = &B{}
// Nicely check whether interface is implemented
if a, ok := b.(A); ok {
a.Foo()
}
}
Whoops, panic. I explicitly don't use reflect package here to indicate your problem exists within "normal" language usage. I have an interface object b and want to check whether it implements interface A. The answer is yes, but I'm getting panic. Who is to blame? I would feel much more comforting saying the creator of object behind the interface b who advertise some functionality, but don't care to provide the implementation. As such I would like it to call a bad practice or at least force it to be clearly stated in the documentation rather than assuming ok in the above type assertion means actually ok.
It's getting too long and off topic I think. My answer to your question is then a mixture of already given answers: directly check A is not null and if it's not possible (you don't know the exact field promoting the method), hope for the best and blame someone else.
I don't think this is possible. From what I can see in reflect's documentation and code, there is no way to know, whether a method is defined on the type or promoted. Seems like panic-recover is the best you can do here.
There are 3 questions here.
An embedded interface does not mean "implements A". It's exactly the same as embedding any other type of object. If you want to implement A, just make a method: func (b B) Foo() string.
When you say:
using embedded interfaces in structs is great for when you only want to
implement /part/ of an interface
That does work, but you have to make sure to create the object properly. Think of it like wrapping an existing object:
type MyReadCloser struct {
io.ReadCloser
}
func (mrc *MyReadCloser) Read(p []byte) (int64, error) {
// do your custom read logic here
}
// you get `Close` for free
func main() {
// assuming we have some reader
var rc io.ReadCloser
// you have to build the object like this:
myReader := MyReadCloser{rc}
}
I'm not sure how Go does it internally, but conceptually it's as if it creates a Close method for you:
func (mrc *MyReadCloser) Close() error {
return mrc.ReadCloser.Close()
}
The panic is because A is nil. If you had:
type concrete string
func (c concrete) Foo() string {
return string(c)
}
func main() {
b := B{A: c("test")}
// etc...
}
It would work. In other words when you call:
bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
That's:
B{}.Foo()
Which is:
B{}.A.Foo()
And A is nil so you get a panic.
As to the question about how to get only the methods directly implemented by an object (not methods implemented by an embedded field), I wasn't able to see a way using the reflect library. MethodByName gives no indication:
<func(main.B) string Value>
Internally that's basically a function like this:
func(b B) string {
return b.A.Foo()
}
And I don't think there's anything in reflect that allows you to peer into the internals of a function. I tried looping over the fields, grabbing their methods and comparing the two, but that doesn't work either.
Within an api I'm writing I have an error struct which marshals to json. When the api has an error it returns the struct and I set the http response code to be the appropriate value.
type PodsError struct {
ErrorCode int `json:"error_code"`
CallingFunction string `json:"calling_function"`
Message string `json:"error_message"`
}
type PodsErrorWrapper struct {
Error PodsError `json:"error"`
}
Right now every time I write the struct I also write a header, but I don't like the amount of duplicate code I am seeing.
error := PodsError{http.StatusNotFound, "Calling Func", "Message"}
response.WriteHeader(error.ErrorCode)
response.WriteEntity(PodsErrorWrapper{error})
Is it possible to move the WriteHeader call to something that gets called whenever I pass the error to WriteEntity()? I figure there has to be a function I could implement for a PodsErrorWapper where I could just set the http status to be whatever the ErrorCode field is.
Edit: Sorry I forgot to mention, I am using the go-restful package (github.com/emicklei/go-restful)
You can make your own function:
func writeEntity(r *restful.Response, value interface{}) error {
// if value is an error
if perr, ok := value.(PodsError); ok {
r.WriteHeader(perr.ErrorCode)
// reassign value so it gets wrapped: `{"error": value}`
value = struct {
Error PodsError `json:"error"`
}{perr}
}
return r.WriteEntity(value)
}
Then just always call that instead of response.WriteEntity:
writeEntity(response, PodsError{http.StatusNotFound, "Calling Func", "Message"})
With the following being defined as is noted in the http library:
func Handle(pattern string, handler Handler)
type Handler interface { ServeHTTP(*Conn, *Request) }
How can I improve upon an existing handler (say, websocket.Draft75Handler for instance) by giving it an additional argument (and tell it what to do with the argument)?
I'm trying to create a handler that contains within it one end of a channel. It will use that channel to talk to some other part of the program. How can I get that channel into the the handler function?
Apologies if this is a silly question. I'm new at go and decided to learn by reading the tutorial and then jumping right into code. Thanks for any help!
If the type is a function, like websocket.Draft75Handler, you could wrap it in a closure:
func MyHandler(arg interface{}) websocket.Draft75Handler {
return func(c *http.ConnConn) {
// handle request
}
}
func main() {
http.Handle("/echo", MyHandler("argument"))
err := http.ListenAndServe(":12345", nil)
if err != nil {
panic("ListenAndServe: " + err.String())
}
}