forked from decred/dcrlnd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dcrlnd.go
76 lines (63 loc) · 2.22 KB
/
dcrlnd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package dcrlnd
import (
"errors"
"sync"
"time"
"github.com/decred/dcrlnd/lnrpc/initchainsyncrpc"
"github.com/decred/dcrlnd/signal"
"google.golang.org/grpc"
)
var errShutdownRequested = errors.New("shutdown requested")
// waitForInitialChainSync waits until the initial chain sync is completed
// before returning. It creates a gRPC service to listen to requests to provide
// the sync progress.
func waitForInitialChainSync(activeChainControl *chainControl,
serverOpts []grpc.ServerOption, getListeners rpcListeners) error {
// Start a gRPC server listening for HTTP/2 connections, solely used
// for showing the progress of the chain sync.
listeners, cleanup, err := getListeners()
if err != nil {
return err
}
defer cleanup()
// Set up a new ChainSyncProgressService, which will listen for requests
// to provide the initial chain sync progress.
grpcServer := grpc.NewServer(serverOpts...)
defer func() {
// Unfortunately the grpc lib does not offer any external
// method to check if there are existing connections and while
// it claims GracefulStop() will wait for outstanding RPC calls
// to finish, some client libraries (specifically: grpc-js used
// in nodejs/Electron apps) have trouble when the connection is
// closed before the response to the Unlock() call is
// completely processed. So we add a delay here to ensure
// there's enough time before closing the grpc listener for any
// clients to finish processing.
time.Sleep(100 * time.Millisecond)
grpcServer.GracefulStop()
}()
svc := initchainsyncrpc.New(activeChainControl.wallet)
initchainsyncrpc.RegisterInitialChainSyncServer(grpcServer, svc)
// wg marks when all listeners have started.
var wg sync.WaitGroup
for _, lis := range listeners {
wg.Add(1)
go func(lis *ListenerWithSignal) {
rpcsLog.Infof("initial chain sync RPC server listening on %s",
lis.Addr())
// Close the ready chan to indicate we are listening.
close(lis.Ready)
wg.Done()
grpcServer.Serve(lis)
}(lis)
}
// Wait for gRPC server to be up running.
wg.Wait()
// Wait until the initial sync is done.
select {
case <-signal.ShutdownChannel():
return errShutdownRequested
case <-activeChainControl.wallet.InitialSyncChannel():
}
return nil
}