Class: BSV::Network::Provider

Inherits:
Object
  • Object
show all
Defined in:
lib/bsv/network/provider.rb

Overview

Provider is a named configuration container that hosts one or more Protocol instances and dispatches commands to the appropriate protocol.

Protocols are registered via a block DSL or by calling #protocol directly after construction. For each command symbol, the first-registered protocol that serves it wins (first-registered-wins, no warning on duplicates).

Example

gorillapool = BSV::Network::Provider.new('GorillaPool') do |p|
  p.protocol Protocols::ARC,         base_url: 'https://arcade.gorillapool.io'
  p.protocol Protocols::Chaintracks, base_url: 'https://arcade.gorillapool.io'
  p.protocol Protocols::Ordinals,    base_url: 'https://ordinals.gorillapool.io'
end

result = gorillapool.call(:broadcast, tx)
result.success?  # => true

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Provider

Returns a new instance of Provider.

Parameters:

  • name (String)

    human-readable provider name (e.g. ‘GorillaPool’)

  • block (Proc)

    optional configuration block — yields self



29
30
31
32
33
34
# File 'lib/bsv/network/provider.rb', line 29

def initialize(name, &block)
  @name           = name
  @protocols      = []
  @command_index  = {}
  block&.call(self)
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



25
26
27
# File 'lib/bsv/network/provider.rb', line 25

def name
  @name
end

Instance Method Details

#call(command_name, *args, **kwargs) ⇒ Result::Success, ...

Dispatches a command to the first-registered protocol that serves it.

Parameters:

  • command_name (Symbol, String)

    command to invoke

  • args (Array)

    positional arguments forwarded to the protocol

  • kwargs (Hash)

    keyword arguments forwarded to the protocol

Returns:

Raises:

  • (ArgumentError)

    when no registered protocol serves the command



114
115
116
117
118
119
120
# File 'lib/bsv/network/provider.rb', line 114

def call(command_name, *args, **kwargs)
  sym      = command_name.to_sym
  instance = @command_index[sym]
  raise ArgumentError, "#{@name} does not provide command :#{sym}" unless instance

  instance.call(sym, *args, **kwargs)
end

#capability_matrixHash{Protocol => Array<Symbol>}

Returns a hash mapping each protocol instance to the sorted list of commands it actually serves within this provider (respecting first-registered-wins — a protocol that lost a command to an earlier registration is not listed for that command).

Protocols that serve no commands in this provider are omitted.

Returns:



89
90
91
92
93
94
95
96
# File 'lib/bsv/network/provider.rb', line 89

def capability_matrix
  matrix = {}
  @protocols.each do |proto|
    served = proto.class.commands.select { |cmd| @command_index[cmd] == proto }
    matrix[proto] = served.sort unless served.empty?
  end
  matrix
end

#commandsSet<Symbol>

Returns the set of all command symbols available on this provider.

Returns:

  • (Set<Symbol>)


68
69
70
# File 'lib/bsv/network/provider.rb', line 68

def commands
  Set.new(@command_index.keys)
end

#protocol(klass, **kwargs) ⇒ Protocol

Registers a protocol class with the provider.

The class is instantiated with the supplied kwargs. Its commands are indexed: each command not yet in the index is mapped to this instance. Commands already in the index are left unchanged (first-registered wins).

The provider remains mutable — protocol may be called after block execution.

Parameters:

  • klass (Class)

    a Protocol subclass

  • kwargs (Hash)

    keyword arguments forwarded to klass.new

Returns:

  • (Protocol)

    the newly created protocol instance



48
49
50
51
52
53
54
55
# File 'lib/bsv/network/provider.rb', line 48

def protocol(klass, **kwargs)
  instance = klass.new(**kwargs)
  @protocols << instance
  klass.commands.each do |cmd|
    @command_index[cmd] ||= instance
  end
  instance
end

#protocol_for(command_name) ⇒ Protocol?

Returns the protocol instance that serves a given command, or nil if no registered protocol handles it.

Parameters:

  • command_name (Symbol, String)

Returns:



77
78
79
# File 'lib/bsv/network/provider.rb', line 77

def protocol_for(command_name)
  @command_index[command_name.to_sym]
end

#protocolsArray<Protocol>

Returns a frozen copy of the registered protocol instances, in registration order.

Returns:



61
62
63
# File 'lib/bsv/network/provider.rb', line 61

def protocols
  @protocols.dup.freeze
end

#to_sString Also known as: inspect

Returns a human-readable representation of the provider.

Returns:

  • (String)


101
102
103
104
# File 'lib/bsv/network/provider.rb', line 101

def to_s
  protocol_summary = @protocols.map { |p| p.class.name&.split('::')&.last || p.class.to_s }.join(', ')
  "#<#{self.class} name=#{@name.inspect} protocols=[#{protocol_summary}]>"
end