Capturing net.Listener passed to http.Server.Serve - go

I'd like to extend the http.Server functionality by performing a graceful shutdown and some other gadgets that I would share across my HTTP services. Currently my code says more or less:
type MyServer struct {
server *http.Server
// ...
}
func (s *MyServer) ListenAndServe() {
// Create listener and pass to s.server.Serve()
}
This works great, but requires exposing all necessary methods and variables of http.Server manually.
Wrapping most of the methods wouldn't be a big problem, but I can't find a sensible way to expose access to http.Server.ListenAndServeTLS without actually copying implementation from the source. The last line in the method says srv.Serve(tlsListener) and I'd love to provide my own Serve method, so modification of net.Listener is possible before passing it to http.Server.Serve.
I started to pencil my wrapper by putting simply:
type MyServer struct {
http.Server
}
func (s *MyServer) Serve(l net.Listener) {
// Wrap l with MyListener, pass to s.Server.Serve()
}
but obviously neither http.ListenAndServe nor http.ListenAndServeTLS would start using my implementation of Serve. And I'd like to ask them to... Is there any way I can tackle the problem or does the design of http.Server effectively prevent me from solving this?
Hacks welcome: even if I don't use them in production, I'll gain some knowledge.

The http.ListenAndServe* methods will work on the embedded type. The other way around works:
type MyServer struct {
http.Server
// ...
}
func (s *MyServer) ListenAndServe() error {
// create listener
// s.Server.Serve(s.listener)
}
func (s *MyServer) ListenAndServeTLS() error {
// create listener
// s.Server.Serve(s.tlsListener)
}

Related

How do I improve the testability of go library methods

I'm writing some code that uses a library called Vault. In this library we have a Client. My code makes use of this Client but I want to be able to easily test the code that uses it. I use only a couple methods from the library so I ended up creating an interface:
type VaultClient interface {
Logical() *api.Logical
SetToken(v string)
NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)
}
Now if my code is pointed at this interface everything is easily testable.. Except let's look at the Logical() method. It returns a struct here. My issue is that this Logical struct also has methods on it that allow you to Read, Write, ex:
func (c *Logical) Read(path string) (*Secret, error) {
return c.ReadWithData(path, nil)
}
and these are being used in my project as well to do something like:
{{ VaultClient defined above }}.Logical().Write("something", something)
Here is the issue. The Logical returned from the call to .Logical() has a .Write and .Read method that I can't reach to mock. I don't want all the logic within those methods to run in my tests.
Ideally I'd like to be able to do something similar to what I did above and create an interface for Logical as well. I'm relatively new to Golang, but I'm struggling with the best approach here. From what I can tell that's not possible. Embedding doesn't work like inheritance so it seems like I have to return a Logical. That leaves my code unable to be tested as simply as I would like because all the logic within a Logical's methods can't be mocked.
I'm sort of at a loss here. I have scoured Google for an answer to this but nobody ever talks about this scenario. They only go as far as I went with the initial interface for the client.
Is this a common scenario? Other libraries I've used don't return structs like Logical. Instead they typically just return a bland struct that holds data and has no methods.
package usecasevaultclient
// usecase.go
type VaultClient interface {
Logical() *api.Logical
SetToken(v string)
NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)
}
type vaultClient struct {
repo RepoVaultClient
}
// create new injection
func NewVaultClient(repo RepoVaultClient) VaultClient {
return &vaultClient{repo}
}
func(u *vaultClient) Logical() *api.Logical {
// do your logic and call the repo of
u.repo.ReadData()
u.repo.WriteData()
}
func(u *vaultClient) SetToken(v string) {}
func(u *vaultClient) NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)
// interfaces.go
type RepoVaultClient interface {
ReadData() error
WriteData() error
}
// repo_vaultclient_mock.go
import "github.com/stretchr/testify/mock"
type MockRepoVaultClient struct {
mock.Mock
}
func (m *MockRepoVaultClient) ReadData() error {
args := m.Called()
return args.Error(0)
}
func (m *MockRepoVaultClient) WriteData() error {
args := m.Called()
return args.Error(0)
}
// vaultClient_test.go
func TestLogicalShouldBeSuccess(t *testing.T) {
mockRepoVaultClient = &MockRepoVaultClient{}
useCase := NewVaultClient(mockRepoVaultClient)
mockRepoVaultClient.On("ReadData").Return(nil)
mockRepoVaultClient.On("WriteData").Return(nil)
// your logics gonna make this response as actual what u implemented
response := useCase.Logical()
assert.Equal(t, expected, response)
}
if you want to test the interface of Logical you need to mock the ReadData and WriteData , with testify/mock so u can defined the respond of return of those methods and you can compare it after you called the new injection of your interface

Typical way to clean up background work in a user-facing component

Assuming I want to return an instance of a "stateful" component to a user, what is the typical way I can cleanup/join background work within that instance? And are there any patterns to avoid viral propagation of explicit cleanup functions all the way to the root code?
For example, let's assume I am returning a client to a database to the user. In this client, I have a loop that periodically polls the server for updates. Now any time this exists within an ownership DAG (like as a member variable in another struct, or as a list in another struct). Requiring an explicit Close() will bubble up virally throughout the call stack. As each upwards link in the DAG will require a Close() as well. All the way to the function that owns the root instance (eg. main() will be required to call Close() on the root server instance, which will require an implementation of Close() so it cleans up background behind itself, etc). Something like the below
type DbClient struct { ... }
func Cleanup(client DbClient) { ... }
type Component struct {
client DbClient
...
}
func Cleanup(component Component) { ... }
type Server struct {
component Component
...
}
func Cleanup(server Server) { ... }
Is there any other way to handle these cases? Or is an explicit Close() function the recommendation for such stateful components?
I guess the problem you mentiond: "upwards link in the DAG will require a Close()" & "all the way to the func that owns root instance.
Go has struct embedding feature. Go favors composition over inheritance.
There's an important way in which embedding differs from subclassing. When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.
package main
import "fmt"
type DbClient struct{}
func (client *DbClient) Cleanup() {
fmt.Println("Closed called on client")
}
type Component struct {
*DbClient
}
type Server struct {
*Component
}
func main() {
client := DbClient{}
component := Component{&client}
server := Server{&component}
server.Cleanup()
}

Dependency injection with http Handler in Go

I am trying to wrap my head around dependency injection in Go, but really stuck here. Here's a (drastically simplified) app which should serve as an example:
package main
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
mux := mux.NewRouter()
mux.Handle("/", myHandler()).Methods("GET")
http.ListenAndServe(":9000", mux)
}
type myObject interface {
Start()
}
type Object struct {
}
func (o *Object) Start() {
// Something wild here, for example sending out an email,
// query an external DB or something similar..
}
func myHandler() http.Handler {
// Inject myObject-like struct somewhere here?
o := Object{}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
o.Start()
w.Write([]byte("Started Object"))
})
}
I have a problem with testing the Object struct. What I usually do is create an interface which can be used in testing by setting up a test struct. For instance, if I had a DB connection handler, in testing I can create a mock which satisfies the handler interface and pass this to the "myHandler" call as a parmeter.
Unfortunately this only works if the struct is already instantiated when the "mux.Handle" call is made. I simply don't see any simple way to test the myHandler function with an Object struct which can be injected in tests, since it will be created after the handler gets called.
Any hints or ideas on how to get this done? Maybe I have to rethink my testing approach, but I would really like to unit-test the Object struct, but also test the http handler separately (as this handler may perform more tasks than just creating the Object).

Defining an interface method with interface return type

TLDR Here is a playground that demonstrates the issue if you try to run it: https://play.golang.org/p/myQtUVg1iq
I am making a REST API and have many types of resources that can be retrieved via a GET request
GET http://localhost/api/users
GET http://localhost/api/groups
I have a models package which abstracts how the different resources are implemented:
func(m *UserManager) Get() []Users {
// Internal logic, assume returns correct results
}
func(m *GroupManager) Get() []Groups {
// Internal logic, assume returns correct results
}
A routes file setups all the routes and handlers:
users := models.UserManager{}
groups := models.GroupManager{}
func GetUsersHandler (w http.ResponseWriter, r *http.Request) {
users := users.Get()
// Implementation details, writing to w as JSON
}
func GetGroupsHandler (w http.ResponseWriter, r *http.Request) {
groups := groups.Get()
// Implementation details, writing to w as JSON
}
func registerRoutes(r *mux.Router) {
r.handleFunc("/api/users", GetUsersHandler).Method("GET")
r.handleFunc("/api/groups", GetGroupsHandler).Method("GET")
}
I am trying to make this more generic by creating an interface and then only needing a single GetHandler. Something like this:
type Getter interface {
Get() []interface{}
}
func GetHandler(g Getter) {
return func(w http.ResponseWriter, r *http.Request) {
results := g.Get()
// Implementation details, writing to w as JSON
}
}
func registerRoutes(r *mux.Router) {
r.handleFunc("/api/users", GetHandler(&users)).Method("GET")
r.handleFunc("/api/groups", GetHandler(&groups)).Method("GET")
}
This is really close to working, the only problem is the return type from the models is a specific object type, but the interface just uses the interface return type. Is there any way to solve this without making the models return []interface{}?
https://play.golang.org/p/myQtUVg1iq
Try not to approach the problem like you would other OOP languages. You can't have covariant containers in Go, so you either have to use an empty interface{}, or you have to structure your program differently.
If your Get methods are different and you want to group types in an interface, use another method (sometimes we even have noop methods just for interfaces), or just pass in users or groups as an interface{}. You'll need to do a type switch or assertion at some point in the call chain anyway, and once you know what type it is you can handle it accordingly.
It's hard to tell without more code, but in this case, the easiest path may just be to have each type be an http.Handler itself, and it can dispatch accordingly.
I ended up avoiding this problem entirely and instead of trying to reduce the amount of code I am using the new go generate feature in Go 1.4 to create the code that is necessary for each resource.

How can I invoke a variable method on a struct

I want to invoke a variable method on a struct like this example
type controller struct{}
func (c *controller) Index() {
fmt.Println("index controller")
}
func invokeIt(action string) {
(&controller{}).action // don't work duh
(&controller{})["action"] // this is Go not js
// how can I invoke it?
}
thx for the replies.
DHH, are you porting Rails to Go :) ?
Jokes aside, this is exactly what reflect is for. For example:
type Foo struct{}
func (Foo) FooM() { fmt.Println("Foom") }
func main() {
foo := Foo{}
reflect.ValueOf(foo).MethodByName("FooM").Call(nil)
}
Playground: http://play.golang.org/p/5ZGwlHLEmj
EDIT: A more idiomatic way to do it would be to use interfaces, (as someone else had proposed, but then have deleted their answer). So if you want to, say, define something that can do CRUD, in Go you'd usually go with
type Resources interface {
Index()
New()
Show(id int)
// ...
}
And maybe an Invoke method in order to invoke non-standard methods on this thing using reflect like above. reflect is very powerful and also a good way to shoot yourself in the foot, so it's never a good idea to overuse it.

Resources