@@ -18,7 +18,9 @@ import (
18
18
"berty.tech/go-orbit-db/cache/cacheleveldown"
19
19
"berty.tech/go-orbit-db/iface"
20
20
_ "berty.tech/go-orbit-db/internal/buildconstraints" // fail for bad go version
21
- "berty.tech/go-orbit-db/stores"
21
+ "berty.tech/go-orbit-db/messagemarshaler"
22
+ "berty.tech/go-orbit-db/pubsub"
23
+ "berty.tech/go-orbit-db/pubsub/oneonone"
22
24
"berty.tech/go-orbit-db/utils"
23
25
cid "github.com/ipfs/go-cid"
24
26
datastore "github.com/ipfs/go-datastore"
@@ -108,7 +110,7 @@ type orbitDB struct {
108
110
cache cache.Interface
109
111
logger * zap.Logger
110
112
tracer trace.Tracer
111
- directChannelFactory iface.DirectChannelFactory
113
+ directChannel iface.DirectChannel
112
114
messageMarshaler iface.MessageMarshaler
113
115
114
116
// emitters
@@ -178,17 +180,36 @@ func (o *orbitDB) setStore(address string, store iface.Store) {
178
180
o .stores [address ] = store
179
181
}
180
182
181
- func (o * orbitDB ) closeAllStores ( ) {
183
+ func (o * orbitDB ) deleteStore ( address string ) {
182
184
o .muStores .Lock ()
183
185
defer o .muStores .Unlock ()
184
186
187
+ delete (o .stores , address )
188
+ }
189
+
190
+ func (o * orbitDB ) getStore (address string ) (iface.Store , bool ) {
191
+ o .muStores .RLock ()
192
+ defer o .muStores .RUnlock ()
193
+
194
+ store , ok := o .stores [address ]
195
+
196
+ return store , ok
197
+ }
198
+
199
+ func (o * orbitDB ) closeAllStores () {
200
+ stores := []Store {}
201
+
202
+ o .muStores .Lock ()
185
203
for _ , store := range o .stores {
204
+ stores = append (stores , store )
205
+ }
206
+ o .muStores .Unlock ()
207
+
208
+ for _ , store := range stores {
186
209
if err := store .Close (); err != nil {
187
210
o .logger .Error ("unable to close store" , zap .Error (err ))
188
211
}
189
212
}
190
-
191
- o .stores = map [string ]Store {}
192
213
}
193
214
194
215
func (o * orbitDB ) closeCache () {
@@ -200,6 +221,12 @@ func (o *orbitDB) closeCache() {
200
221
}
201
222
}
202
223
224
+ func (o * orbitDB ) closeDirectConnections () {
225
+ if err := o .directChannel .Close (); err != nil {
226
+ o .logger .Error ("unable to close connection" , zap .Error (err ))
227
+ }
228
+ }
229
+
203
230
func (o * orbitDB ) closeKeyStore () {
204
231
o .muKeyStore .Lock ()
205
232
defer o .muKeyStore .Unlock ()
@@ -314,6 +341,16 @@ func newOrbitDB(ctx context.Context, is coreapi.CoreAPI, identity *idp.Identity,
314
341
options .EventBus = eventbus .NewBus ()
315
342
}
316
343
344
+ if options .DirectChannelFactory == nil {
345
+ options .DirectChannelFactory = oneonone .NewChannelFactory (is )
346
+ }
347
+ directConnections , err := makeDirectChannel (ctx , options .EventBus , options .DirectChannelFactory , & iface.DirectChannelOptions {
348
+ Logger : options .Logger ,
349
+ })
350
+ if err != nil {
351
+ return nil , fmt .Errorf ("unable to create a direct connection with peer: %w" , err )
352
+ }
353
+
317
354
k , err := is .Key ().Self (ctx )
318
355
if err != nil {
319
356
return nil , err
@@ -324,6 +361,10 @@ func newOrbitDB(ctx context.Context, is coreapi.CoreAPI, identity *idp.Identity,
324
361
options .PeerID = id
325
362
}
326
363
364
+ if options .MessageMarshaler == nil {
365
+ options .MessageMarshaler = & messagemarshaler.JSONMarshaler {}
366
+ }
367
+
327
368
if options .Cache == nil {
328
369
options .Cache = cacheleveldown .New (& cache.Options {Logger : options .Logger })
329
370
}
@@ -344,7 +385,7 @@ func newOrbitDB(ctx context.Context, is coreapi.CoreAPI, identity *idp.Identity,
344
385
directory : * options .Directory ,
345
386
eventBus : options .EventBus ,
346
387
stores : map [string ]Store {},
347
- directChannelFactory : options . DirectChannelFactory ,
388
+ directChannel : directConnections ,
348
389
closeKeystore : options .CloseKeystore ,
349
390
storeTypes : map [string ]iface.StoreConstructor {},
350
391
accessControllerTypes : map [string ]iface.AccessControllerConstructor {},
@@ -354,10 +395,15 @@ func newOrbitDB(ctx context.Context, is coreapi.CoreAPI, identity *idp.Identity,
354
395
}
355
396
356
397
// set new heads as stateful, so newly subscriber can replay last event in case they missed it
357
- odb .emitters .newHeads , err = options .EventBus .Emitter (new (stores. EventExchangeHeads ), eventbus .Stateful )
398
+ odb .emitters .newHeads , err = options .EventBus .Emitter (new (EventExchangeHeads ), eventbus .Stateful )
358
399
if err != nil {
359
400
return nil , fmt .Errorf ("unable to create global emitter: %w" , err )
360
401
}
402
+
403
+ if err := odb .monitorDirectChannel (ctx , options .EventBus ); err != nil {
404
+ return nil , fmt .Errorf ("unable to monitor direct channel: %w" , err )
405
+ }
406
+
361
407
return odb , nil
362
408
}
363
409
@@ -430,9 +476,14 @@ func NewOrbitDB(ctx context.Context, ipfs coreapi.CoreAPI, options *NewOrbitDBOp
430
476
431
477
func (o * orbitDB ) Close () error {
432
478
o .closeAllStores ()
479
+ o .closeDirectConnections ()
433
480
o .closeCache ()
434
481
o .closeKeyStore ()
435
482
483
+ if err := o .emitters .newHeads .Close (); err != nil {
484
+ o .logger .Warn ("unable to close emitter" , zap .Error (err ))
485
+ }
486
+
436
487
o .cancel ()
437
488
return nil
438
489
}
@@ -718,23 +769,35 @@ func (o *orbitDB) createStore(ctx context.Context, storeType string, parsedDBAdd
718
769
}
719
770
}
720
771
772
+ if options .Logger == nil {
773
+ options .Logger = o .logger
774
+ }
775
+
776
+ if options .CloseFunc == nil {
777
+ options .CloseFunc = func () {}
778
+ }
779
+ closeFunc := func () {
780
+ options .CloseFunc ()
781
+ o .deleteStore (parsedDBAddress .String ())
782
+ }
783
+
721
784
store , err := storeFunc (o .IPFS (), identity , parsedDBAddress , & iface.NewStoreOptions {
722
- EventBus : options .EventBus ,
723
- AccessController : accessController ,
724
- Cache : options .Cache ,
725
- Replicate : options .Replicate ,
726
- Directory : * options .Directory ,
727
- SortFn : options .SortFn ,
728
- CacheDestroy : func () error { return o .cache .Destroy (o .directory , parsedDBAddress ) },
729
- Logger : o . logger ,
730
- Tracer : o .tracer ,
731
- IO : options .IO ,
732
- StoreSpecificOpts : options .StoreSpecificOpts ,
733
- PubSub : o .pubsub ,
734
- MessageMarshaler : o .messageMarshaler ,
735
- PeerID : o .id ,
736
- DirectChannelFactory : o . directChannelFactory ,
737
- NewHeadsEmitter : o . emitters . newHeads ,
785
+ EventBus : options .EventBus ,
786
+ AccessController : accessController ,
787
+ Cache : options .Cache ,
788
+ Replicate : options .Replicate ,
789
+ Directory : * options .Directory ,
790
+ SortFn : options .SortFn ,
791
+ CacheDestroy : func () error { return o .cache .Destroy (o .directory , parsedDBAddress ) },
792
+ Logger : options . Logger ,
793
+ Tracer : o .tracer ,
794
+ IO : options .IO ,
795
+ StoreSpecificOpts : options .StoreSpecificOpts ,
796
+ PubSub : o .pubsub ,
797
+ MessageMarshaler : o .messageMarshaler ,
798
+ PeerID : o .id ,
799
+ DirectChannel : o . directChannel ,
800
+ CloseFunc : closeFunc ,
738
801
})
739
802
if err != nil {
740
803
return nil , fmt .Errorf ("unable to instantiate store: %w" , err )
@@ -749,4 +812,56 @@ func (o *orbitDB) EventBus() event.Bus {
749
812
return o .eventBus
750
813
}
751
814
815
+ func (o * orbitDB ) monitorDirectChannel (ctx context.Context , bus event.Bus ) error {
816
+ sub , err := bus .Subscribe (new (iface.EventPubSubPayload ), eventbus .BufSize (128 ))
817
+ if err != nil {
818
+ return fmt .Errorf ("unable to init pubsub subscriber: %w" , err )
819
+ }
820
+
821
+ go func () {
822
+ for {
823
+ var e interface {}
824
+ select {
825
+ case <- ctx .Done ():
826
+ return
827
+ case e = <- sub .Out ():
828
+ }
829
+
830
+ evt := e .(iface.EventPubSubPayload )
831
+
832
+ msg := iface.MessageExchangeHeads {}
833
+ if err := o .messageMarshaler .Unmarshal (evt .Payload , & msg ); err != nil {
834
+ o .logger .Error ("unable to unmarshal message payload" , zap .Error (err ))
835
+ continue
836
+ }
837
+
838
+ store , ok := o .getStore (msg .Address )
839
+ if ! ok {
840
+ o .logger .Error ("unable to get store from address" , zap .Error (err ))
841
+ continue
842
+ }
843
+
844
+ if err := o .handleEventExchangeHeads (ctx , & msg , store ); err != nil {
845
+ o .logger .Error ("unable to handle pubsub payload" , zap .Error (err ))
846
+ continue
847
+ }
848
+
849
+ if err := o .emitters .newHeads .Emit (NewEventExchangeHeads (evt .Peer , & msg )); err != nil {
850
+ o .logger .Warn ("unable to emit new heads" , zap .Error (err ))
851
+ }
852
+ }
853
+ }()
854
+
855
+ return nil
856
+ }
857
+
858
+ func makeDirectChannel (ctx context.Context , bus event.Bus , df iface.DirectChannelFactory , opts * iface.DirectChannelOptions ) (iface.DirectChannel , error ) {
859
+ emitter , err := pubsub .NewPayloadEmitter (bus )
860
+ if err != nil {
861
+ return nil , fmt .Errorf ("unable to init pubsub emitter: %w" , err )
862
+ }
863
+
864
+ return df (ctx , emitter , opts )
865
+ }
866
+
752
867
var _ BaseOrbitDB = & orbitDB {}
0 commit comments