Skip to content

Commit 95f6c52

Browse files
committed
Set max sessions
1 parent f9a0135 commit 95f6c52

File tree

3 files changed

+70
-16
lines changed

3 files changed

+70
-16
lines changed

internal/provider/provider.go

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ func New(version string) func() *schema.Provider {
3939
ResourcesMap: map[string]*schema.Resource{
4040
"remotefile": resourceRemotefile(),
4141
},
42-
Schema: map[string]*schema.Schema{},
42+
Schema: map[string]*schema.Schema{
43+
"max_sessions": {
44+
Type: schema.TypeInt,
45+
Optional: true,
46+
Default: 3,
47+
Description: "Maximum number of open sessions in each host connection.",
48+
},
49+
},
4350
}
4451

4552
p.ConfigureContextFunc = configure(version, p)
@@ -49,15 +56,19 @@ func New(version string) func() *schema.Provider {
4956
}
5057

5158
type apiClient struct {
52-
mux *sync.Mutex
53-
remoteClients map[string]*RemoteClient
59+
mux *sync.Mutex
60+
remoteClients map[string]*RemoteClient
61+
activeSessions map[string]int
62+
maxSessions int
5463
}
5564

5665
func configure(version string, p *schema.Provider) func(context.Context, *schema.ResourceData) (interface{}, diag.Diagnostics) {
5766
return func(c context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
5867
client := apiClient{
59-
mux: &sync.Mutex{},
60-
remoteClients: map[string]*RemoteClient{},
68+
maxSessions: d.Get("max_sessions").(int),
69+
mux: &sync.Mutex{},
70+
remoteClients: map[string]*RemoteClient{},
71+
activeSessions: map[string]int{},
6172
}
6273

6374
return &client, diag.Diagnostics{}
@@ -66,21 +77,45 @@ func configure(version string, p *schema.Provider) func(context.Context, *schema
6677

6778
func (c *apiClient) getRemoteClient(d *schema.ResourceData) (*RemoteClient, error) {
6879
connectionID := resourceConnectionHash(d)
69-
c.mux.Lock()
7080
defer c.mux.Unlock()
81+
for {
82+
c.mux.Lock()
83+
84+
client, ok := c.remoteClients[connectionID]
85+
if ok {
86+
if c.activeSessions[connectionID] >= c.maxSessions {
87+
c.mux.Unlock()
88+
continue
89+
}
90+
c.activeSessions[connectionID] += 1
91+
92+
return client, nil
93+
}
7194

72-
client, ok := c.remoteClients[connectionID]
73-
if ok {
95+
client, err := RemoteClientFromResource(d)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
c.remoteClients[connectionID] = client
101+
c.activeSessions[connectionID] = 1
74102
return client, nil
75103
}
104+
}
105+
106+
func (c *apiClient) closeRemoteClient(d *schema.ResourceData) error {
107+
connectionID := resourceConnectionHash(d)
108+
c.mux.Lock()
109+
defer c.mux.Unlock()
76110

77-
client, err := RemoteClientFromResource(d)
78-
if err != nil {
79-
return nil, err
111+
c.activeSessions[connectionID] -= 1
112+
if c.activeSessions[connectionID] == 0 {
113+
client := c.remoteClients[connectionID]
114+
delete(c.remoteClients, connectionID)
115+
return client.Close()
80116
}
81117

82-
c.remoteClients[connectionID] = client
83-
return client, nil
118+
return nil
84119
}
85120

86121
func RemoteClientFromResource(d *schema.ResourceData) (*RemoteClient, error) {

internal/provider/remote_client.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ func NewRemoteClient(host string, clientConfig ssh.ClientConfig) (*RemoteClient,
166166
}, nil
167167
}
168168

169+
func (c *RemoteClient) Close() error {
170+
return c.sshClient.Close()
171+
}
172+
169173
func (c *RemoteClient) GetSSHClient() *ssh.Client {
170174
return c.sshClient
171175
}

internal/provider/resource_remotefile.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func resourceRemotefileCreate(ctx context.Context, d *schema.ResourceData, meta
100100

101101
client, err := meta.(*apiClient).getRemoteClient(d)
102102
if err != nil {
103-
return diag.Errorf(err.Error())
103+
return diag.Errorf("error while opening remote client: %s", err.Error())
104104
}
105105

106106
sudo, ok := d.GetOk("conn.0.sudo")
@@ -120,6 +120,11 @@ func resourceRemotefileCreate(ctx context.Context, d *schema.ResourceData, meta
120120
}
121121
}
122122

123+
err = meta.(*apiClient).closeRemoteClient(d)
124+
if err != nil {
125+
return diag.Errorf("error while closing remote client: %s", err.Error())
126+
}
127+
123128
return diag.Diagnostics{}
124129
}
125130

@@ -128,7 +133,7 @@ func resourceRemotefileRead(ctx context.Context, d *schema.ResourceData, meta in
128133

129134
client, err := meta.(*apiClient).getRemoteClient(d)
130135
if err != nil {
131-
return diag.Errorf(err.Error())
136+
return diag.Errorf("error while opening remote client: %s", err.Error())
132137
}
133138

134139
sudo, ok := d.GetOk("conn.0.sudo")
@@ -152,6 +157,11 @@ func resourceRemotefileRead(ctx context.Context, d *schema.ResourceData, meta in
152157
}
153158
}
154159

160+
err = meta.(*apiClient).closeRemoteClient(d)
161+
if err != nil {
162+
return diag.Errorf("error while closing remote client: %s", err.Error())
163+
}
164+
155165
return diag.Diagnostics{}
156166
}
157167

@@ -162,7 +172,7 @@ func resourceRemotefileUpdate(ctx context.Context, d *schema.ResourceData, meta
162172
func resourceRemotefileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
163173
client, err := meta.(*apiClient).getRemoteClient(d)
164174
if err != nil {
165-
return diag.Errorf(err.Error())
175+
return diag.Errorf("error while opening remote client: %s", err.Error())
166176
}
167177

168178
sudo, ok := d.GetOk("conn.0.sudo")
@@ -186,5 +196,10 @@ func resourceRemotefileDelete(ctx context.Context, d *schema.ResourceData, meta
186196
}
187197
}
188198

199+
err = meta.(*apiClient).closeRemoteClient(d)
200+
if err != nil {
201+
return diag.Errorf("error while closing remote client: %s", err.Error())
202+
}
203+
189204
return diag.Diagnostics{}
190205
}

0 commit comments

Comments
 (0)