8784: Fix test for latest firefox.
[arvados.git] / sdk / go / arvadosclient / pool.go
1 package arvadosclient
2
3 import (
4         "sync"
5 )
6
7 // A ClientPool is a pool of ArvadosClients. This is useful for
8 // applications that make API calls using a dynamic set of tokens,
9 // like web services that pass through their own clients'
10 // credentials. See arvados-git-httpd for an example, and sync.Pool
11 // for more information about garbage collection.
12 type ClientPool struct {
13         // Initialize new clients by coping this one.
14         Prototype *ArvadosClient
15
16         pool      *sync.Pool
17         lastErr   error
18         setupOnce sync.Once
19 }
20
21 // MakeClientPool returns a new empty ClientPool, using environment
22 // variables to initialize the prototype.
23 func MakeClientPool() *ClientPool {
24         proto, err := MakeArvadosClient()
25         return &ClientPool{
26                 Prototype: proto,
27                 lastErr:   err,
28         }
29 }
30
31 func (p *ClientPool) setup() {
32         p.pool = &sync.Pool{New: func() interface{} {
33                 if p.lastErr != nil {
34                         return nil
35                 }
36                 c := *p.Prototype
37                 return &c
38         }}
39 }
40
41 // Err returns the error that was encountered last time Get returned
42 // nil.
43 func (p *ClientPool) Err() error {
44         return p.lastErr
45 }
46
47 // Get returns an ArvadosClient taken from the pool, or a new one if
48 // the pool is empty. If an existing client is returned, its state
49 // (including its ApiToken) will be just as it was when it was Put
50 // back in the pool.
51 func (p *ClientPool) Get() *ArvadosClient {
52         p.setupOnce.Do(p.setup)
53         c, ok := p.pool.Get().(*ArvadosClient)
54         if !ok {
55                 return nil
56         }
57         return c
58 }
59
60 // Put puts an ArvadosClient back in the pool.
61 func (p *ClientPool) Put(c *ArvadosClient) {
62         p.setupOnce.Do(p.setup)
63         p.pool.Put(c)
64 }