@@ -11,18 +11,18 @@ import (
11
11
"net"
12
12
"os"
13
13
"strings"
14
+ "sync"
14
15
"time"
15
16
17
+ "github.com/ipfs/go-log"
16
18
"github.com/libp2p/go-libp2p/core/peer"
17
19
"github.com/mudler/LocalAI/pkg/utils"
20
+ "github.com/mudler/edgevpn/pkg/config"
18
21
"github.com/mudler/edgevpn/pkg/node"
19
22
"github.com/mudler/edgevpn/pkg/protocol"
23
+ "github.com/mudler/edgevpn/pkg/services"
20
24
"github.com/mudler/edgevpn/pkg/types"
21
25
"github.com/phayes/freeport"
22
-
23
- "github.com/ipfs/go-log"
24
- "github.com/mudler/edgevpn/pkg/config"
25
- "github.com/mudler/edgevpn/pkg/services"
26
26
zlog "github.com/rs/zerolog/log"
27
27
28
28
"github.com/mudler/edgevpn/pkg/logger"
@@ -34,6 +34,15 @@ func GenerateToken() string {
34
34
return newData .Base64 ()
35
35
}
36
36
37
+ func IsP2PEnabled () bool {
38
+ return true
39
+ }
40
+
41
+ func nodeID () string {
42
+ hostname , _ := os .Hostname ()
43
+ return hostname
44
+ }
45
+
37
46
func allocateLocalService (ctx context.Context , node * node.Node , listenAddr , service string ) error {
38
47
39
48
zlog .Info ().Msgf ("Allocating service '%s' on: %s" , service , listenAddr )
@@ -53,16 +62,16 @@ func allocateLocalService(ctx context.Context, node *node.Node, listenAddr, serv
53
62
10 * time .Second ,
54
63
func () {
55
64
// Retrieve current ID for ip in the blockchain
56
- _ , found := ledger .GetKey (protocol .UsersLedgerKey , node .Host ().ID ().String ())
65
+ // _, found := ledger.GetKey(protocol.UsersLedgerKey, node.Host().ID().String())
57
66
// If mismatch, update the blockchain
58
- if ! found {
59
- updatedMap := map [string ]interface {}{}
60
- updatedMap [node .Host ().ID ().String ()] = & types.User {
61
- PeerID : node .Host ().ID ().String (),
62
- Timestamp : time .Now ().String (),
63
- }
64
- ledger .Add (protocol .UsersLedgerKey , updatedMap )
67
+ //if !found {
68
+ updatedMap := map [string ]interface {}{}
69
+ updatedMap [node .Host ().ID ().String ()] = & types.User {
70
+ PeerID : node .Host ().ID ().String (),
71
+ Timestamp : time .Now ().String (),
65
72
}
73
+ ledger .Add (protocol .UsersLedgerKey , updatedMap )
74
+ // }
66
75
},
67
76
)
68
77
@@ -142,28 +151,41 @@ func LLamaCPPRPCServerDiscoverer(ctx context.Context, token string) error {
142
151
if err != nil {
143
152
return err
144
153
}
145
-
154
+ // TODO: discoveryTunnels should return all the nodes that are available?
155
+ // In this way we updated availableNodes here instead of appending
156
+ // e.g. we have a LastSeen field in NodeData that is updated in discoveryTunnels
157
+ // each time the node is seen
158
+ // In this case the below function should be idempotent and just keep track of the nodes
146
159
go func () {
147
- totalTunnels := []string {}
148
160
for {
149
161
select {
150
162
case <- ctx .Done ():
151
163
zlog .Error ().Msg ("Discoverer stopped" )
152
164
return
153
165
case tunnel := <- tunnels :
166
+ AddNode (tunnel )
154
167
155
- totalTunnels = append (totalTunnels , tunnel )
156
- os .Setenv ("LLAMACPP_GRPC_SERVERS" , strings .Join (totalTunnels , "," ))
157
- zlog .Debug ().Msgf ("setting LLAMACPP_GRPC_SERVERS to %s" , strings .Join (totalTunnels , "," ))
168
+ var tunnelAddresses []string
169
+ for _ , v := range nodes {
170
+ if v .IsOnline () {
171
+ tunnelAddresses = append (tunnelAddresses , v .TunnelAddress )
172
+ }
173
+ }
174
+ tunnelEnvVar := strings .Join (tunnelAddresses , "," )
175
+
176
+ os .Setenv ("LLAMACPP_GRPC_SERVERS" , tunnelEnvVar )
177
+ zlog .Debug ().Msgf ("setting LLAMACPP_GRPC_SERVERS to %s" , tunnelEnvVar )
178
+
179
+ zlog .Info ().Msgf ("Node %s available" , tunnel .ID )
158
180
}
159
181
}
160
182
}()
161
183
162
184
return nil
163
185
}
164
186
165
- func discoveryTunnels (ctx context.Context , token string ) (chan string , error ) {
166
- tunnels := make (chan string )
187
+ func discoveryTunnels (ctx context.Context , token string ) (chan NodeData , error ) {
188
+ tunnels := make (chan NodeData )
167
189
168
190
nodeOpts , err := newNodeOpts (token )
169
191
if err != nil {
@@ -184,8 +206,14 @@ func discoveryTunnels(ctx context.Context, token string) (chan string, error) {
184
206
}
185
207
186
208
// get new services, allocate and return to the channel
209
+
210
+ // TODO:
211
+ // a function ensureServices that:
212
+ // - starts a service if not started, if the worker is Online
213
+ // - checks that workers are Online, if not cancel the context of allocateLocalService
214
+ // - discoveryTunnels should return all the nodes and addresses associated with it
215
+ // - the caller should take now care of the fact that we are always returning fresh informations
187
216
go func () {
188
- emitted := map [string ]bool {}
189
217
for {
190
218
select {
191
219
case <- ctx .Done ():
@@ -196,19 +224,15 @@ func discoveryTunnels(ctx context.Context, token string) (chan string, error) {
196
224
zlog .Debug ().Msg ("Searching for workers" )
197
225
198
226
data := ledger .LastBlock ().Storage ["services_localai" ]
199
- for k := range data {
227
+ for k , v := range data {
200
228
zlog .Info ().Msgf ("Found worker %s" , k )
201
- if _ , found := emitted [k ]; ! found {
202
- emitted [k ] = true
203
- //discoveredPeers <- k
204
- port , err := freeport .GetFreePort ()
205
- if err != nil {
206
- fmt .Print (err )
207
- }
208
- tunnelAddress := fmt .Sprintf ("127.0.0.1:%d" , port )
209
- go allocateLocalService (ctx , n , tunnelAddress , k )
210
- tunnels <- tunnelAddress
229
+ nd := & NodeData {}
230
+ if err := v .Unmarshal (nd ); err != nil {
231
+ zlog .Error ().Msg ("cannot unmarshal node data" )
232
+ continue
211
233
}
234
+ ensureService (ctx , n , nd , k )
235
+ tunnels <- * nd
212
236
}
213
237
}
214
238
}
@@ -217,6 +241,41 @@ func discoveryTunnels(ctx context.Context, token string) (chan string, error) {
217
241
return tunnels , err
218
242
}
219
243
244
+ type nodeServiceData struct {
245
+ NodeData NodeData
246
+ CancelFunc context.CancelFunc
247
+ }
248
+
249
+ var service = map [string ]nodeServiceData {}
250
+ var muservice sync.Mutex
251
+
252
+ func ensureService (ctx context.Context , n * node.Node , nd * NodeData , sserv string ) {
253
+ muservice .Lock ()
254
+ defer muservice .Unlock ()
255
+ if ndService , found := service [nd .Name ]; ! found {
256
+ newCtxm , cancel := context .WithCancel (ctx )
257
+ service [nd .Name ] = nodeServiceData {
258
+ NodeData : * nd ,
259
+ CancelFunc : cancel ,
260
+ }
261
+ // Start the service
262
+ port , err := freeport .GetFreePort ()
263
+ if err != nil {
264
+ fmt .Print (err )
265
+ }
266
+ tunnelAddress := fmt .Sprintf ("127.0.0.1:%d" , port )
267
+ nd .TunnelAddress = tunnelAddress
268
+ go allocateLocalService (newCtxm , n , tunnelAddress , sserv )
269
+ } else {
270
+ // Check if the service is still alive
271
+ // if not cancel the context
272
+ if ! ndService .NodeData .IsOnline () {
273
+ ndService .CancelFunc ()
274
+ delete (service , nd .Name )
275
+ }
276
+ }
277
+ }
278
+
220
279
// This is the P2P worker main
221
280
func BindLLamaCPPWorker (ctx context.Context , host , port , token string ) error {
222
281
llger := logger .New (log .LevelFatal )
@@ -248,16 +307,20 @@ func BindLLamaCPPWorker(ctx context.Context, host, port, token string) error {
248
307
249
308
ledger .Announce (
250
309
ctx ,
251
- 10 * time .Second ,
310
+ 20 * time .Second ,
252
311
func () {
253
312
// Retrieve current ID for ip in the blockchain
254
- _ , found := ledger .GetKey ("services_localai" , name )
313
+ // _, found := ledger.GetKey("services_localai", name)
255
314
// If mismatch, update the blockchain
256
- if ! found {
257
- updatedMap := map [string ]interface {}{}
258
- updatedMap [name ] = "p2p"
259
- ledger .Add ("services_localai" , updatedMap )
315
+ //if !found {
316
+ updatedMap := map [string ]interface {}{}
317
+ updatedMap [name ] = & NodeData {
318
+ Name : name ,
319
+ LastSeen : time .Now (),
320
+ ID : nodeID (),
260
321
}
322
+ ledger .Add ("services_localai" , updatedMap )
323
+ // }
261
324
},
262
325
)
263
326
0 commit comments