master
go 131 lines 3.64 KB
Raw
1 package routing
2
3 import (
4 "context"
5 "errors"
6
7 "github.com/ipfs/go-cid"
8 routinghelpers "github.com/libp2p/go-libp2p-routing-helpers"
9 "github.com/libp2p/go-libp2p/core/peer"
10 "github.com/libp2p/go-libp2p/core/routing"
11 "github.com/multiformats/go-multihash"
12 )
13
14 var (
15 _ routinghelpers.ProvideManyRouter = &Composer{}
16 _ routing.Routing = &Composer{}
17 )
18
19 type Composer struct {
20 GetValueRouter routing.Routing
21 PutValueRouter routing.Routing
22 FindPeersRouter routing.Routing
23 FindProvidersRouter routing.Routing
24 ProvideRouter routing.Routing
25 }
26
27 func (c *Composer) Provide(ctx context.Context, cid cid.Cid, provide bool) error {
28 log.Debug("composer: calling provide: ", cid)
29 err := c.ProvideRouter.Provide(ctx, cid, provide)
30 if err != nil {
31 log.Debug("composer: calling provide: ", cid, " error: ", err)
32 }
33
34 return err
35 }
36
37 func (c *Composer) ProvideMany(ctx context.Context, keys []multihash.Multihash) error {
38 log.Debug("composer: calling provide many: ", len(keys))
39 pmr, ok := c.ProvideRouter.(routinghelpers.ProvideManyRouter)
40 if !ok {
41 log.Debug("composer: provide many is not implemented on the actual router")
42 return nil
43 }
44
45 err := pmr.ProvideMany(ctx, keys)
46 if err != nil {
47 log.Debug("composer: calling provide many error: ", err)
48 }
49
50 return err
51 }
52
53 func (c *Composer) Ready() bool {
54 log.Debug("composer: calling ready")
55 pmr, ok := c.ProvideRouter.(routinghelpers.ReadyAbleRouter)
56 if !ok {
57 return true
58 }
59
60 ready := pmr.Ready()
61
62 log.Debug("composer: calling ready result: ", ready)
63
64 return ready
65 }
66
67 func (c *Composer) FindProvidersAsync(ctx context.Context, cid cid.Cid, count int) <-chan peer.AddrInfo {
68 log.Debug("composer: calling findProvidersAsync: ", cid)
69 return c.FindProvidersRouter.FindProvidersAsync(ctx, cid, count)
70 }
71
72 func (c *Composer) FindPeer(ctx context.Context, pid peer.ID) (peer.AddrInfo, error) {
73 log.Debug("composer: calling findPeer: ", pid)
74 addr, err := c.FindPeersRouter.FindPeer(ctx, pid)
75 if err != nil {
76 log.Debug("composer: calling findPeer error: ", pid, addr.String(), err)
77 }
78 return addr, err
79 }
80
81 func (c *Composer) PutValue(ctx context.Context, key string, val []byte, opts ...routing.Option) error {
82 log.Debug("composer: calling putValue: ", key, len(val))
83 err := c.PutValueRouter.PutValue(ctx, key, val, opts...)
84 if err != nil {
85 log.Debug("composer: calling putValue error: ", key, len(val), err)
86 }
87
88 return err
89 }
90
91 func (c *Composer) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) {
92 log.Debug("composer: calling getValue: ", key)
93 val, err := c.GetValueRouter.GetValue(ctx, key, opts...)
94 if err != nil {
95 log.Debug("composer: calling getValue error: ", key, len(val), err)
96 }
97
98 return val, err
99 }
100
101 func (c *Composer) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) {
102 log.Debug("composer: calling searchValue: ", key)
103 ch, err := c.GetValueRouter.SearchValue(ctx, key, opts...)
104
105 // avoid nil channels on implementations not supporting SearchValue method.
106 if errors.Is(err, routing.ErrNotFound) && ch == nil {
107 out := make(chan []byte)
108 close(out)
109 return out, err
110 }
111
112 if err != nil {
113 log.Debug("composer: calling searchValue error: ", key, err)
114 }
115
116 return ch, err
117 }
118
119 func (c *Composer) Bootstrap(ctx context.Context) error {
120 log.Debug("composer: calling bootstrap")
121 errfp := c.FindPeersRouter.Bootstrap(ctx)
122 errfps := c.FindProvidersRouter.Bootstrap(ctx)
123 errgv := c.GetValueRouter.Bootstrap(ctx)
124 errpv := c.PutValueRouter.Bootstrap(ctx)
125 errp := c.ProvideRouter.Bootstrap(ctx)
126 err := errors.Join(errfp, errfps, errgv, errpv, errp)
127 if err != nil {
128 log.Debug("composer: calling bootstrap error: ", err)
129 }
130 return err
131 }