11package ssh
22
33import (
4+ "sync"
5+
46 "github.com/git-lfs/git-lfs/config"
57 "github.com/git-lfs/git-lfs/subprocess"
68 "github.com/git-lfs/pktline"
79)
810
911type SSHTransfer struct {
10- conn * PktlineConnection
12+ lock * sync.RWMutex
13+ conn []* PktlineConnection
14+ osEnv config.Environment
15+ gitEnv config.Environment
16+ meta * SSHMetadata
17+ operation string
1118}
1219
1320func NewSSHTransfer (osEnv config.Environment , gitEnv config.Environment , meta * SSHMetadata , operation string ) (* SSHTransfer , error ) {
21+ conn , err := startConnection (osEnv , gitEnv , meta , operation )
22+ if err != nil {
23+ return nil , err
24+ }
25+ return & SSHTransfer {
26+ lock : & sync.RWMutex {},
27+ osEnv : osEnv ,
28+ gitEnv : gitEnv ,
29+ meta : meta ,
30+ operation : operation ,
31+ conn : []* PktlineConnection {conn },
32+ }, nil
33+ }
34+
35+ func startConnection (osEnv config.Environment , gitEnv config.Environment , meta * SSHMetadata , operation string ) (* PktlineConnection , error ) {
1436 exe , args := GetLFSExeAndArgs (osEnv , gitEnv , meta , "git-lfs-transfer" , operation )
1537 cmd := subprocess .ExecCommand (exe , args ... )
1638 r , err := cmd .StdoutPipe ()
@@ -37,14 +59,63 @@ func NewSSHTransfer(osEnv config.Environment, gitEnv config.Environment, meta *S
3759 pl : pl ,
3860 }
3961 err = conn .Start ()
40- if err != nil {
41- return nil , err
62+ return conn , err
63+ }
64+
65+ // Connection returns the nth connection (starting from 0) in this transfer
66+ // instance or nil if there is no such item.
67+ func (tr * SSHTransfer ) Connection (n int ) * PktlineConnection {
68+ tr .lock .RLock ()
69+ defer tr .lock .RUnlock ()
70+ if n >= len (tr .conn ) {
71+ return nil
4272 }
43- return & SSHTransfer {
44- conn : conn ,
45- }, nil
73+ return tr .conn [n ]
4674}
4775
48- func (tr * SSHTransfer ) Connection () * PktlineConnection {
49- return tr .conn
76+ // ConnectionCount returns the number of connections this object has.
77+ func (tr * SSHTransfer ) ConnectionCount () int {
78+ tr .lock .RLock ()
79+ defer tr .lock .RUnlock ()
80+ return len (tr .conn )
81+ }
82+
83+ // SetConnectionCount sets the number of connections to the specified number.
84+ func (tr * SSHTransfer ) SetConnectionCount (n int ) error {
85+ tr .lock .Lock ()
86+ defer tr .lock .Unlock ()
87+ return tr .setConnectionCount (n )
88+ }
89+
90+ // SetConnectionCountAtLeast sets the number of connections to be not less than
91+ // the specified number.
92+ func (tr * SSHTransfer ) SetConnectionCountAtLeast (n int ) error {
93+ tr .lock .Lock ()
94+ defer tr .lock .Unlock ()
95+ count := len (tr .conn )
96+ if n <= count {
97+ return nil
98+ }
99+ return tr .setConnectionCount (n )
100+ }
101+
102+ func (tr * SSHTransfer ) setConnectionCount (n int ) error {
103+ count := len (tr .conn )
104+ if n < count {
105+ for _ , item := range tr .conn [n :count ] {
106+ if err := item .End (); err != nil {
107+ return err
108+ }
109+ }
110+ tr .conn = tr .conn [0 :n ]
111+ } else if n > count {
112+ for i := count ; i < n ; i ++ {
113+ conn , err := startConnection (tr .osEnv , tr .gitEnv , tr .meta , tr .operation )
114+ if err != nil {
115+ return err
116+ }
117+ tr .conn = append (tr .conn , conn )
118+ }
119+ }
120+ return nil
50121}
0 commit comments