Last active
October 6, 2020 20:39
-
-
Save matthewoestreich/c5d514706f6fc3257cb89f99f53427f7 to your computer and use it in GitHub Desktop.
Helping with https://stackoverflow.com/questions/64232012/pass-different-clients-to-generic-function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type JobReact struct { | |
name string | |
Duration time.Duration | |
Info interface{} | |
Error error | |
} | |
func (m *JobReact) Name() string { | |
return m.name | |
} | |
type GenClient struct { | |
ClientA http.Client | |
ClientB kubernetes.Clientset | |
} | |
type ResultList struct { | |
response http.Response | |
} | |
// Jobs holds job data | |
type Jobs struct { | |
Name string | |
Runner func(*GenClient) JobReact | |
} | |
func wrapper(timeDuration time.Duration, reacts chan JobReact, jobs Jobs, client *GenClient) func() { | |
contextWithTimeout, tc := context.WithTimeout(context.Background(), timeDuration) | |
return func() { | |
now := time.Now() | |
go func( | |
contx context.Context, | |
cancelFunc context.CancelFunc, | |
jobReacts chan JobReact, | |
jobs Jobs, | |
timer time.Time, | |
/**/ myclient *GenClient, /**/ // <-- You have to pass in your client | |
) { | |
runner := jobs.Runner(myclient) | |
runner.Duration = time.Since(timer) | |
runner.name = jobs.Name | |
if contextWithTimeout.Err() == nil { | |
jobReacts <- runner | |
} | |
cancelFunc() | |
}(contextWithTimeout, tc, reacts, jobs, now, /**/client/**/) // <-- You have to pass in your client | |
select { | |
case <-contextWithTimeout.Done(): | |
switch contextWithTimeout.Err() { | |
case context.DeadlineExceeded: | |
reacts <- JobReact{ | |
name: jobs.Name, | |
Error: context.DeadlineExceeded, | |
Duration: time.Since(now), | |
} | |
} | |
} | |
} | |
} | |
func main() { | |
// init clients | |
genClients := GenClient{ClientA: ClientA(), ClientB: ClientB()} | |
jobs := []Jobs{ | |
{ | |
Name: "job1", | |
Runner: func(gc *GenClient) JobReact { | |
// In this func I need to use client A | |
gc.ClientA | |
//... | |
}, | |
}, | |
{ | |
Name: "job2", | |
Runner: func(gc *GenClient) JobReact { | |
// In this func I need to use client b | |
gc.ClientB | |
//... | |
}, | |
}, | |
{ | |
Name: "job3", | |
Runner: func(gc *GenClient) JobReact { | |
// In this func I need to use Client A & client B | |
gc.ClientB | |
gc.ClientA | |
// ... | |
}, | |
}, | |
} | |
JobRes := make(chan JobReact, len(jobs)) | |
pool := workerpool.New(5) | |
for _, worker := range jobs { | |
pool.Submit(wrapper(time.Duration(time.Second * 10), JobRes, worker, genClients)) | |
} | |
pool.StopWait() | |
GetAllResponses(JobRes) | |
} | |
func GetAllResponses(wr chan JobReact) ResultList { | |
for jobChannel := range wr { | |
if jobChannel.Info != 200 { | |
fmt.Printf("job %s: took '%d' sec response: %s\n", jobChannel.Name(), jobChannel.Duration.Seconds(), jobChannel.Error) | |
return ResultList{response: http.Response{StatusCode: 500}} | |
} | |
fmt.Printf("job %s: took '%d' sec response: %s\n", jobChannel.Name(), jobChannel.Duration.Seconds(), jobChannel.Info) | |
} | |
return ResultList{response: http.Response{StatusCode: 200}} | |
} | |
func ClientA() http.Client { | |
c := &http.Client{} | |
return *c | |
} | |
func ClientB() kubernetes.Clientset { | |
// .... | |
return *clientset | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// *http.Client could be whateve client you need | |
// like `kubernetes.Clientset` or some custom client | |
// like `MyCustomClient` for example... | |
func makeSomeHTTPCall(c *http.Client) ReturnWhateverYouWant { | |
// res, err := c.Get(...) | |
// ...do whatever with client | |
} | |
/** | |
* The only reason you would need different clients, | |
* that I can think of, is because you needed each | |
* client to have a specific configuration. | |
* | |
* You already appear to be doing this.. | |
*/ | |
// client with long timeout | |
clientA := &http.Client{ | |
Timeout: time.Second * 240, | |
} | |
// client with short timeout | |
clientB := &http.Client{ | |
Timeout: time.Second * 10, | |
} | |
clientAResult := makeSomeHTTPCall(clientA) | |
clientBResult := makeSomeHTTPCall(clientB) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment