@@ -11,9 +11,9 @@ import (
1111 "encoding/base64"
1212 "encoding/json"
1313 "fmt"
14- "sync"
1514 "time"
1615
16+ "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/lazy"
1717 "github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
1818 "github.com/hyperledger-labs/fabric-token-sdk/token"
1919 "github.com/hyperledger-labs/fabric-token-sdk/token/services/logging"
@@ -394,49 +394,60 @@ func (n *Network) Connect(ns string) ([]token.ServiceOption, error) {
394394
395395// Provider returns an instance of network provider
396396type Provider struct {
397- lock sync.Mutex
398- networks map [string ]* Network
399- drivers []driver.Driver
397+ networks lazy.Provider [netId , * Network ]
398+ networkProvider * networkProvider
399+ }
400+
401+ type netId struct {
402+ network , channel string
403+ }
404+
405+ func key (id netId ) string {
406+ return id .network + id .channel
400407}
401408
402409// NewProvider returns a new instance of network provider
403410func NewProvider () * Provider {
404- ms := & Provider {
405- networks : map [string ]* Network {},
406- drivers : make ([]driver.Driver , 0 ),
411+ ms := & networkProvider {drivers : make ([]driver.Driver , 0 )}
412+
413+ return & Provider {
414+ networkProvider : ms ,
415+ networks : lazy .NewProviderWithKeyMapper (key , ms .newNetwork ),
407416 }
408- return ms
409417}
410418
411419func (np * Provider ) RegisterDriver (driver driver.Driver ) {
412- np .drivers = append ( np . drivers , driver )
420+ np .networkProvider . registerDriver ( driver )
413421}
414422
415423// GetNetwork returns a network instance for the given network and channel
416424func (np * Provider ) GetNetwork (network string , channel string ) (* Network , error ) {
417- np .lock .Lock ()
418- defer np .lock .Unlock ()
419-
420425 logger .Debugf ("GetNetwork: [%s:%s]" , network , channel )
426+ return np .networks .Get (netId {network : network , channel : channel })
427+ }
421428
422- key := network + channel
423- service , ok := np .networks [key ]
424- if ! ok {
425- var err error
426- service , err = np .newNetwork (network , channel )
427- if err != nil {
428- logger .Errorf ("failed to get network: [%s:%s] %s" , network , channel , err )
429- return nil , err
430- }
431- np .networks [key ] = service
429+ func (np * Provider ) Normalize (opt * token.ServiceOptions ) (* token.ServiceOptions , error ) {
430+ if opt == nil {
431+ return nil , errors .New ("no service options provided" )
432432 }
433+ n , err := np .GetNetwork (opt .Network , opt .Channel )
434+ if err != nil {
435+ return nil , errors .WithMessagef (err , "failed to get network [%s:%s]" , opt .Network , opt .Channel )
436+ }
437+ return n .Normalize (opt )
438+ }
433439
434- logger .Debugf ("GetNetwork: [%s:%s], returning..." , network , channel )
440+ // networkProvider instantiates new networks based on the registered drivers
441+ type networkProvider struct {
442+ drivers []driver.Driver
443+ }
435444
436- return service , nil
445+ func (np * networkProvider ) registerDriver (driver driver.Driver ) {
446+ np .drivers = append (np .drivers , driver )
437447}
438448
439- func (np * Provider ) newNetwork (network string , channel string ) (* Network , error ) {
449+ func (np * networkProvider ) newNetwork (netId netId ) (* Network , error ) {
450+ network , channel := netId .network , netId .channel
440451 var errs []error
441452 for _ , d := range np .drivers {
442453 nw , err := d .New (network , channel )
@@ -450,17 +461,6 @@ func (np *Provider) newNetwork(network string, channel string) (*Network, error)
450461 return nil , errors .Errorf ("no network driver found for [%s:%s], errs [%v]" , network , channel , errs )
451462}
452463
453- func (np * Provider ) Normalize (opt * token.ServiceOptions ) (* token.ServiceOptions , error ) {
454- if opt == nil {
455- return nil , errors .New ("no service options provided" )
456- }
457- n , err := np .GetNetwork (opt .Network , opt .Channel )
458- if err != nil {
459- return nil , errors .WithMessagef (err , "failed to get network [%s:%s]" , opt .Network , opt .Channel )
460- }
461- return n .Normalize (opt )
462- }
463-
464464// GetInstance returns a network instance for the given network and channel
465465func GetInstance (sp token.ServiceProvider , network , channel string ) * Network {
466466 n , err := GetProvider (sp ).GetNetwork (network , channel )
0 commit comments