ib_ruby_proxy 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +77 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +143 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +130 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/generate_ruby_classes +13 -0
- data/bin/ibproxy +32 -0
- data/bin/setup +8 -0
- data/docs/diagrams.key +0 -0
- data/docs/images/architecture.png +0 -0
- data/examples/common.rb +14 -0
- data/examples/plain_req_historical_ticks.rb +19 -0
- data/examples/req_contract_details.rb +9 -0
- data/examples/req_historical_bars_data.rb +10 -0
- data/examples/req_historical_ticks.rb +10 -0
- data/examples/req_tick_by_tick_data.rb +9 -0
- data/ib_ruby_proxy.gemspec +43 -0
- data/lib/ib_ruby_proxy.rb +35 -0
- data/lib/ib_ruby_proxy/client/callbacks_response_handler.rb +135 -0
- data/lib/ib_ruby_proxy/client/client.rb +69 -0
- data/lib/ib_ruby_proxy/client/ib/bar.rb +36 -0
- data/lib/ib_ruby_proxy/client/ib/combo_leg.rb +36 -0
- data/lib/ib_ruby_proxy/client/ib/contract.rb +56 -0
- data/lib/ib_ruby_proxy/client/ib/contract_details.rb +100 -0
- data/lib/ib_ruby_proxy/client/ib/delta_neutral_contract.rb +26 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick.rb +26 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick_bid_ask.rb +32 -0
- data/lib/ib_ruby_proxy/client/ib/historical_tick_last.rb +32 -0
- data/lib/ib_ruby_proxy/client/ib/order.rb +262 -0
- data/lib/ib_ruby_proxy/client/ib/tick_attrib_bid_ask.rb +24 -0
- data/lib/ib_ruby_proxy/client/ib/tick_attrib_last.rb +24 -0
- data/lib/ib_ruby_proxy/client/ib_callbacks_observer.rb +25 -0
- data/lib/ib_ruby_proxy/config.yml +43 -0
- data/lib/ib_ruby_proxy/server/ext/array.rb +22 -0
- data/lib/ib_ruby_proxy/server/ext/enum.rb +20 -0
- data/lib/ib_ruby_proxy/server/ext/idempotent_types.rb +23 -0
- data/lib/ib_ruby_proxy/server/ib/bar.rb +21 -0
- data/lib/ib_ruby_proxy/server/ib/combo_leg.rb +21 -0
- data/lib/ib_ruby_proxy/server/ib/contract.rb +31 -0
- data/lib/ib_ruby_proxy/server/ib/contract_details.rb +53 -0
- data/lib/ib_ruby_proxy/server/ib/delta_neutral_contract.rb +16 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick.rb +16 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick_bid_ask.rb +19 -0
- data/lib/ib_ruby_proxy/server/ib/historical_tick_last.rb +19 -0
- data/lib/ib_ruby_proxy/server/ib/order.rb +134 -0
- data/lib/ib_ruby_proxy/server/ib/tick_attrib_bid_ask.rb +15 -0
- data/lib/ib_ruby_proxy/server/ib/tick_attrib_last.rb +15 -0
- data/lib/ib_ruby_proxy/server/ib_client_adapter.rb +51 -0
- data/lib/ib_ruby_proxy/server/ib_proxy_service.rb +85 -0
- data/lib/ib_ruby_proxy/server/ib_ruby_class_files_generator.rb +77 -0
- data/lib/ib_ruby_proxy/server/ib_ruby_class_source_generator.rb +155 -0
- data/lib/ib_ruby_proxy/server/ib_wrapper_adapter.rb +47 -0
- data/lib/ib_ruby_proxy/server/reflection/ib_class.rb +62 -0
- data/lib/ib_ruby_proxy/server/reflection/ib_field.rb +60 -0
- data/lib/ib_ruby_proxy/util/has_logger.rb +10 -0
- data/lib/ib_ruby_proxy/util/string_utils.rb +29 -0
- data/lib/ib_ruby_proxy/version.rb +3 -0
- data/lib/server.rb +4 -0
- data/sandbox/drb_performance/client.rb +46 -0
- data/sandbox/drb_performance/server.rb +26 -0
- data/vendor/TwsApi.jar +0 -0
- metadata +226 -0
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ib_ruby_proxy"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift './lib'
|
4
|
+
$LOAD_PATH.unshift File.join(__dir__, '..')
|
5
|
+
$LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
|
6
|
+
|
7
|
+
require 'ib_ruby_proxy'
|
8
|
+
require 'server'
|
9
|
+
|
10
|
+
client_code_dir = File.join(__dir__, '..', 'lib', 'ib_ruby_proxy', 'client', 'ib')
|
11
|
+
server_code_dir = File.join(__dir__, '..', 'lib', 'ib_ruby_proxy', 'server', 'ib')
|
12
|
+
IbRubyProxy::Server::IbRubyClassFilesGenerator.new(client_code_dir: client_code_dir, server_code_dir: server_code_dir).generate_all
|
13
|
+
|
data/bin/ibproxy
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'commander/import'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift './lib'
|
7
|
+
$LOAD_PATH.unshift File.join(__dir__, '..')
|
8
|
+
$LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
|
9
|
+
|
10
|
+
require 'ib_ruby_proxy'
|
11
|
+
require 'server'
|
12
|
+
|
13
|
+
program :name, 'ibproxy'
|
14
|
+
program :version, IbRubyProxy::VERSION
|
15
|
+
program :description, 'Invoke Interactive Brokers API from Ruby'
|
16
|
+
default_command :server
|
17
|
+
|
18
|
+
command :server do |c|
|
19
|
+
c.syntax = 'ibproxy server [options]'
|
20
|
+
c.summary = 'Start ibproxy server'
|
21
|
+
c.option '--ib-port PORT', Integer, "Interactive brokers client port. #{IbRubyProxy::Server::IbProxyService::DEFAULT_IB_GATEWAY_PORT} by default (Gateway). Default for TWS is whatever"
|
22
|
+
c.option '--drb-port PORT', Integer, "Port for the served drb endpoint. #{IbRubyProxy::Server::IbProxyService::DEFAULT_DRB_PORT} by default"
|
23
|
+
c.action do |args, options|
|
24
|
+
options.default ib_port: IbRubyProxy::Server::IbProxyService::DEFAULT_IB_GATEWAY_PORT,
|
25
|
+
drb_port: IbRubyProxy::Server::IbProxyService::DEFAULT_DRB_PORT
|
26
|
+
ib_port = options.ib_port
|
27
|
+
drb_port = options.drb_port
|
28
|
+
puts "Starting with ib port #{ib_port} and drb port #{drb_port}..."
|
29
|
+
IbRubyProxy::Server::IbProxyService.new(ib_port: ib_port, drb_port: drb_port).start
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/bin/setup
ADDED
data/docs/diagrams.key
ADDED
Binary file
|
Binary file
|
data/examples/common.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'drb'
|
2
|
+
require 'ib_ruby_proxy'
|
3
|
+
|
4
|
+
class Securities
|
5
|
+
class << self
|
6
|
+
def emini(expiration_month = '201909')
|
7
|
+
IbRubyProxy::Client::Ib::Contract.new symbol: 'ES',
|
8
|
+
sec_type: 'FUT',
|
9
|
+
currency: 'USD',
|
10
|
+
exchange: 'GLOBEX',
|
11
|
+
last_trade_date_or_contract_month: expiration_month
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative './common'
|
2
|
+
|
3
|
+
client = IbRubyProxy::Client::Client.from_drb
|
4
|
+
|
5
|
+
class CallbacksObserver < IbRubyProxy::Client::IbCallbacksObserver
|
6
|
+
def historical_ticks(_request_id, ticks, _done)
|
7
|
+
ap ticks
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
aapl = IbRubyProxy::Client::Ib::Contract.new symbol: 'AAPL',
|
12
|
+
sec_type: 'STK',
|
13
|
+
exchange: 'ISLAND'
|
14
|
+
|
15
|
+
client.add_ib_callbacks_observer CallbacksObserver.new
|
16
|
+
client.req_historical_ticks(18009, aapl, '20190304 12:00:00', nil, 100,
|
17
|
+
'MIDPOINT', 1, false, nil)
|
18
|
+
|
19
|
+
sleep
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative './common'
|
2
|
+
|
3
|
+
client = IbRubyProxy::Client::Client.from_drb
|
4
|
+
|
5
|
+
client.req_historical_ticks(18009, Securities.emini, nil, '20190304 17:00:00', 100,
|
6
|
+
'MIDPOINT', 1, false, nil) do |_callback, _request_id, ticks, _done|
|
7
|
+
ap ticks
|
8
|
+
end
|
9
|
+
|
10
|
+
sleep
|
@@ -0,0 +1,43 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'ib_ruby_proxy/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'ib_ruby_proxy'
|
7
|
+
spec.version = IbRubyProxy::VERSION
|
8
|
+
spec.authors = ['Jorge Manrubia']
|
9
|
+
spec.email = ['jorge.manrubia@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = 'Invoke IB Java API from Ruby'
|
12
|
+
spec.description = 'Invoke IB Java API from Ruby'
|
13
|
+
spec.homepage = 'https://github.com/jorgemanrubia/ib_ruby_proxy'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/jorgemanrubia/ib_ruby_proxy'
|
21
|
+
else
|
22
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
23
|
+
'public gem pushes.'
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
30
|
+
end
|
31
|
+
spec.bindir = 'exe'
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ['lib']
|
34
|
+
|
35
|
+
spec.add_dependency 'awesome_print'
|
36
|
+
spec.add_dependency 'commander'
|
37
|
+
spec.add_dependency 'concurrent-ruby'
|
38
|
+
spec.add_development_dependency 'bundler', '~> 2.0.1'
|
39
|
+
spec.add_development_dependency 'impersonator'
|
40
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
41
|
+
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
42
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ib_ruby_proxy/version'
|
2
|
+
require 'awesome_print'
|
3
|
+
require 'drb'
|
4
|
+
require 'logger'
|
5
|
+
require 'concurrent-ruby'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
Dir["#{__dir__}/ib_ruby_proxy/util/**/*.rb"].each { |file| require file }
|
9
|
+
Dir["#{__dir__}/ib_ruby_proxy/client/**/*.rb"].each { |file| require file }
|
10
|
+
|
11
|
+
module IbRubyProxy
|
12
|
+
LOGGER_LEVEL = Logger::DEBUG
|
13
|
+
|
14
|
+
# Gem logger
|
15
|
+
#
|
16
|
+
# @return [Logger]
|
17
|
+
def self.logger
|
18
|
+
@logger ||= Logger.new(STDOUT).tap do |logger|
|
19
|
+
logger.level = LOGGER_LEVEL
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configuration options parsed from +ib_ruby_proxy/config.yml+
|
24
|
+
#
|
25
|
+
# @return [Hash]
|
26
|
+
def self.config
|
27
|
+
@config ||= begin
|
28
|
+
file_path = File.join(__dir__, 'ib_ruby_proxy/config.yml')
|
29
|
+
YAML.load_file(file_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Error < StandardError
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module IbRubyProxy
|
2
|
+
module Client
|
3
|
+
# This class maps callbacks with method invocations that originated them so that
|
4
|
+
# a block can be passed to the api method and it will be invoked when a callback is
|
5
|
+
# received
|
6
|
+
class CallbacksResponseHandler
|
7
|
+
IB_CALLBACKS_MAPPING = {
|
8
|
+
req_historical_ticks: { callbacks: %i[historical_ticks historical_ticks_bid_ask
|
9
|
+
historical_ticks_last],
|
10
|
+
discriminate_by_argument_nth: 0 },
|
11
|
+
req_contract_details: { callbacks: %i[contract_details contract_details_end],
|
12
|
+
discriminate_by_argument_nth: 0 },
|
13
|
+
req_tick_by_tick_data: { callbacks: %i[tick_by_tick_bid_ask tick_by_tick_all_last
|
14
|
+
tick_by_tick_mid_point],
|
15
|
+
discriminate_by_argument_nth: 0 },
|
16
|
+
req_historical_data: { callbacks: %i[historical_data historical_data_end
|
17
|
+
historical_data_update],
|
18
|
+
discriminate_by_argument_nth: 0 }
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@method_handlers = {}
|
23
|
+
@callback_handlers = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# Handle invoked method
|
27
|
+
#
|
28
|
+
# @param [String, Symbol] method_name
|
29
|
+
# @param [Array<Object>] arguments
|
30
|
+
# @param [Proc] block
|
31
|
+
def method_invoked(method_name, *arguments, &block)
|
32
|
+
method_name = method_name.to_sym
|
33
|
+
method_handlers[method_name]&.method_invoked(*arguments, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Handle callback received: it will invoke the block passed in the corresponding
|
37
|
+
# {#method_invoked}, if any.
|
38
|
+
#
|
39
|
+
# @param [Symbol] callback_name
|
40
|
+
# @param [Array<Object>] arguments
|
41
|
+
def callback_received(callback_name, *arguments)
|
42
|
+
callback_name = callback_name.to_sym
|
43
|
+
callback_handlers[callback_name]&.callback_received(callback_name, *arguments)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @private
|
47
|
+
def self.for_ib
|
48
|
+
new.tap do |handler|
|
49
|
+
IbRubyProxy.config['mapped_callbacks'].each do |method, callback_config|
|
50
|
+
nth_argument = callback_config['discriminate_by_argument_nth']
|
51
|
+
handler.configure_block_callback method: method.to_sym,
|
52
|
+
callbacks: callback_config['callbacks'],
|
53
|
+
discriminate_by_argument_nth: nth_argument
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Configures a mapping between a method invocation and a received callback
|
59
|
+
#
|
60
|
+
# @param [String, Symbol] method
|
61
|
+
# @param [String, Symbol] callbacks
|
62
|
+
# @param [Integer, nil] discriminate_by_argument_nth The position of the argument that
|
63
|
+
# will be used to discriminate received callbacks and match them with invocation methods.
|
64
|
+
# +nil+ indicates no argument should be used for discriminating (default)
|
65
|
+
def configure_block_callback(method:, callbacks:, discriminate_by_argument_nth: nil)
|
66
|
+
validate_can_add_callback_on_method!(method)
|
67
|
+
|
68
|
+
handler = BlockCallbackHandler.new(discriminate_by_argument_nth)
|
69
|
+
|
70
|
+
configure_callbacks_handler(callbacks, handler)
|
71
|
+
configure_method_handler(method, handler)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
attr_reader :method_handlers, :callback_handlers
|
77
|
+
|
78
|
+
def configure_method_handler(method, handler)
|
79
|
+
method_handlers[method.to_sym] = handler
|
80
|
+
end
|
81
|
+
|
82
|
+
def configure_callbacks_handler(callbacks, handler)
|
83
|
+
callbacks << :error
|
84
|
+
callbacks.each do |callback_name|
|
85
|
+
callback_handlers[callback_name.to_sym] = handler
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_can_add_callback_on_method!(method)
|
90
|
+
raise "Already configured handler for #{method}" if method_handlers[method]
|
91
|
+
end
|
92
|
+
|
93
|
+
# b_proxy_service.rb:13@private
|
94
|
+
class BlockCallbackHandler
|
95
|
+
include IbRubyProxy::Util::HasLogger
|
96
|
+
|
97
|
+
attr_reader :discriminate_by_argument_nth, :block
|
98
|
+
|
99
|
+
def initialize(discriminate_by_argument_nth)
|
100
|
+
@discriminate_by_argument_nth = discriminate_by_argument_nth
|
101
|
+
@blocks_by_discriminator = {}
|
102
|
+
end
|
103
|
+
|
104
|
+
def method_invoked(*arguments, &block)
|
105
|
+
if @discriminate_by_argument_nth
|
106
|
+
discrminator = arguments[@discriminate_by_argument_nth]
|
107
|
+
unless discrminator
|
108
|
+
raise "No argument #{@discriminate_by_argument_nth} to discriminate with?"\
|
109
|
+
" #{arguments.inspect}"
|
110
|
+
end
|
111
|
+
|
112
|
+
@blocks_by_discriminator[discrminator] = block
|
113
|
+
else
|
114
|
+
@block = block
|
115
|
+
end
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
def callback_received(callback_name, *arguments)
|
120
|
+
if callback_name.to_s == 'error'
|
121
|
+
raise StandardError, arguments.join('. ')
|
122
|
+
else
|
123
|
+
block = if @discriminate_by_argument_nth
|
124
|
+
@blocks_by_discriminator[arguments[@discriminate_by_argument_nth]]
|
125
|
+
else
|
126
|
+
@block
|
127
|
+
end
|
128
|
+
|
129
|
+
block&.call(callback_name, *arguments)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'drb/timeridconv'
|
2
|
+
|
3
|
+
module IbRubyProxy
|
4
|
+
module Client
|
5
|
+
# A client for interacting with the DRb service
|
6
|
+
#
|
7
|
+
# If can be instantiated directly from the DRb service with {.create_drb_ib_client}
|
8
|
+
#
|
9
|
+
# It offers the same interface than a {IbRubyProxy::Server::IbClientAdapter} and, also,
|
10
|
+
# configures a {CallbacksResponseHandler} so that you can use Ruby blocks to capture
|
11
|
+
# callbacks invocations based on the semantics of the invoked methods.
|
12
|
+
#
|
13
|
+
# @see CallbacksResponseHandler
|
14
|
+
class Client
|
15
|
+
attr_reader :ib_client
|
16
|
+
|
17
|
+
# @return [Client]
|
18
|
+
# @param [String] host DRb host +localhost+ by default
|
19
|
+
# @param [Object] port DRb port +1992+ by default
|
20
|
+
def self.from_drb(host: 'localhost', port: 1992)
|
21
|
+
new(create_drb_ib_client(host: host, port: port))
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [IbRubyProxy::Server::IbClientAdapter] ib_client
|
25
|
+
def initialize(ib_client)
|
26
|
+
@ib_client = ib_client
|
27
|
+
@promises_by_request_id = {}
|
28
|
+
@callbacks_response_handler = CallbacksResponseHandler.for_ib
|
29
|
+
@ib_client.add_ib_callbacks_observer ResponseHandleObserver.new(@callbacks_response_handler)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @private
|
33
|
+
def self.create_drb_ib_client(host:, port:)
|
34
|
+
drb_ib_client = DRbObject.new(nil, "druby://#{host}:#{port}")
|
35
|
+
DRb::DRbServer.verbose = true
|
36
|
+
DRb.install_id_conv ::DRb::TimerIdConv.new 60
|
37
|
+
DRb.start_service
|
38
|
+
drb_ib_client
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def respond_to_missing?(name, include_private = false)
|
44
|
+
@ib_client.respond_to?(name, include_private)
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(method, *arguments, &block)
|
48
|
+
@ib_client.public_send(method, *arguments, &block)
|
49
|
+
@callbacks_response_handler.method_invoked method, *arguments, &block
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# An observer that will delegate callbacks to a {CallbacksResponseHandler}
|
54
|
+
#
|
55
|
+
# @private
|
56
|
+
class ResponseHandleObserver
|
57
|
+
include DRb::DRbUndumped
|
58
|
+
|
59
|
+
def initialize(callbacks_response_handler)
|
60
|
+
@callbacks_response_handler = callbacks_response_handler
|
61
|
+
end
|
62
|
+
|
63
|
+
def update(*params)
|
64
|
+
method, *arguments = params
|
65
|
+
@callbacks_response_handler.callback_received(method, *arguments)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|