cotcube-helpers 0.2.2.5 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7496f5774fbcb9b661dac0f9315081a4b5f4d30a8c89334ef13d0639b789ba73
4
- data.tar.gz: 596ab3ed0cc578c6321beb1b07b6400e109f4537d91cf0903a0c0542b9a962df
3
+ metadata.gz: 1d08ed5fa831283b0934d2ce7f86f9da0f1be5430d0d3164ee503b0aa7bac74f
4
+ data.tar.gz: ac59b5558432299e6906c8a93b4ddab8b7a57a7cac4b2c11239a8f41a8c05f4e
5
5
  SHA512:
6
- metadata.gz: 7447d4f4d2297c60eb37a815b8cd0c91ddd70d1c4af0d2f8bab89ada65c2ac0c328da6e6dd2e99f46d39d75cc765ee4d724598c3d9fdbf42cd15b6a7f30a22fc
7
- data.tar.gz: 348426b27122a2be123f93f4db63b7d57e032cf2451f6822a10fce94124d9d0f2cf6c9d3621b920daa651e80ec1b69a5e777d4d94a169cb03f6067f13d1d693f
6
+ metadata.gz: 8b3ce7871cbc2068523994caa155a2291512c0cce8c72398f51de275e56c6e1a75a94402327118f27ae0376ccbf70b148be3fb17d0f66326e019d21a639ae485
7
+ data.tar.gz: e17fe32e700a3441e5e54a4b521c0c3d20acedbfb45606cd8f3da6edb5041a7cbcab522729da6d9d0e784f739730972af1ad1210b5542e06cd879f70587d7b1e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.2.3 (December 30, 2021)
2
+ - merging conflict
3
+ - added bare josch_ and order_client s
4
+ - added bare js_ and order_client s
5
+
1
6
  ## 0.2.2.5 (December 23, 2021)
2
7
  - hash_ext: reworked keys_to_sym!
3
8
  - minor changes
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2.5
1
+ 0.2.3
@@ -227,4 +227,4 @@ begin
227
227
  }
228
228
  ensure
229
229
  client.stop
230
- e,nd
230
+ end
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bunny'
5
+ require 'json'
6
+
7
+ module Cotcube
8
+ module Helpers
9
+ class JoSchClient
10
+ SECRETS_DEFAULT = {
11
+ 'josch_mq_proto' => 'http',
12
+ 'josch_mq_user' => 'guest',
13
+ 'josch_mq_password' => 'guest',
14
+ 'josch_mq_host' => 'localhost',
15
+ 'josch_mq_port' => '15672',
16
+ 'josch_mq_vhost' => '%2F'
17
+ }.freeze
18
+
19
+ SECRETS = SECRETS_DEFAULT.merge(
20
+ lambda {
21
+ begin
22
+ YAML.safe_load(File.read(Cotcube::Helpers.init[:secrets_file]))
23
+ rescue StandardError
24
+ {}
25
+ end
26
+ }.call
27
+ )
28
+
29
+ def initialize
30
+ @connection = Bunny.new(user: SECRETS['josch_mq_user'],
31
+ password: SECRETS['josch_mq_password'],
32
+ vhost: SECRETS['josch_mq_vhost'])
33
+ @connection.start
34
+
35
+ @commands = connection.create_channel
36
+ @exchange = commands.direct('josch_commands')
37
+ @requests = {}
38
+ @debug = false
39
+ setup_reply_queue
40
+ end
41
+
42
+ # command acts a synchronizer: it sends the command and waits for the response
43
+ # otherwise times out --- the counterpart here is the subscription within
44
+ # setup_reply_queue
45
+ #
46
+ def command(command, timeout: 10)
47
+ command = { command: command.to_s } unless command.is_a? Hash
48
+ command[:timestamp] ||= (Time.now.to_f * 1000).to_i
49
+ request_id = Digest::SHA256.hexdigest(command.to_json)[..6]
50
+ requests[request_id] = {
51
+ request: command,
52
+ id: request_id,
53
+ lock: Mutex.new,
54
+ condition: ConditionVariable.new
55
+ }
56
+
57
+ exchange.publish(command.to_json,
58
+ routing_key: 'josch_commands',
59
+ correlation_id: request_id,
60
+ reply_to: reply_queue.name)
61
+
62
+ # wait for the signal to continue the execution
63
+ #
64
+ requests[request_id][:lock].synchronize do
65
+ requests[request_id][:condition].wait(requests[request_id][:lock], timeout)
66
+ end
67
+
68
+ # if we reached timeout, we will return nil, just for explicity
69
+ response = requests[request_id][:response].dup
70
+ requests.delete(request_id)
71
+ response
72
+ end
73
+
74
+ alias_method :send_command, :command
75
+
76
+ attr_accessor :response
77
+ attr_reader :lock, :condition
78
+
79
+ private
80
+
81
+ attr_reader :call_id, :connection, :requests, :persistent,
82
+ :commands, :server_queue_name, :reply_queue, :exchange
83
+
84
+ def setup_reply_queue
85
+ @reply_queue = commands.queue('', exclusive: true, auto_delete: true)
86
+ @reply_queue.bind(commands.exchange('josch_replies'), routing_key: @reply_queue.name)
87
+
88
+ reply_queue.subscribe do |delivery_info, properties, payload|
89
+ __id__ = properties[:correlation_id]
90
+
91
+ if __id__.nil?
92
+ puts "Received without __id__: #{delivery_info.map { |k, v| "#{k}\t#{v}" }.join("\n")
93
+ }\n\n#{properties.map { |k, v| "#{k}\t#{v}" }.join("\n")
94
+ }\n\n#{JSON.parse(payload).map { |k, v| "#{k}\t#{v}" }.join("\n")}" if @debug
95
+
96
+ elsif requests[__id__].nil?
97
+ puts "Received non-matching response, maybe previously timed out: \n\n#{delivery_info}\n\n#{properties}\n\n#{payload}\n."[..620].scan(/.{1,120}/).join(' '*30 + "\n") if @debug
98
+ else
99
+ # save the payload and send the signal to continue the execution of #command
100
+ # need to rescue the rare case, where lock and condition are destroyed right in parallel by timeout
101
+ begin
102
+ puts "Received result for #{__id__}" if @debug
103
+ requests[__id__][:response] = payload
104
+ requests[__id__][:lock].synchronize { requests[__id__][:condition].signal }
105
+ rescue nil
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ JoschClient = JoSchClient
112
+ end
113
+ end
114
+
115
+ __END__
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bunny'
5
+ require 'json'
6
+
7
+ module Cotcube
8
+ module Helpers
9
+ class OrderClient
10
+ SECRETS_DEFAULT = {
11
+ 'orderproxy_mq_proto' => 'http',
12
+ 'orderproxy_mq_user' => 'guest',
13
+ 'orderproxy_mq_password' => 'guest',
14
+ 'orderproxy_mq_host' => 'localhost',
15
+ 'orderproxy_mq_port' => '15672',
16
+ 'orderproxy_mq_vhost' => '%2F'
17
+ }.freeze
18
+
19
+ SECRETS = SECRETS_DEFAULT.merge(
20
+ lambda {
21
+ begin
22
+ YAML.safe_load(File.read(Cotcube::Helpers.init[:secrets_file]))
23
+ rescue StandardError
24
+ {}
25
+ end
26
+ }.call
27
+ )
28
+
29
+ def initialize
30
+ @connection = Bunny.new(user: SECRETS['orderproxy_mq_user'],
31
+ password: SECRETS['orderproxy_mq_password'],
32
+ vhost: SECRETS['orderproxy_mq_vhost'])
33
+ @connection.start
34
+
35
+ @commands = connection.create_channel
36
+ @exchange = commands.direct('orderproxy_commands')
37
+ @requests = {}
38
+ @persistent = { depth: {}, realtimebars: {}, ticks: {} }
39
+ @debug = false
40
+ setup_reply_queue
41
+ end
42
+
43
+ # command acts a synchronizer: it sends the command and waits for the response
44
+ # otherwise times out --- the counterpart here is the subscription within
45
+ # setup_reply_queue
46
+ #
47
+ def command(command, timeout: 10)
48
+ command = { command: command.to_s } unless command.is_a? Hash
49
+ command[:timestamp] ||= (Time.now.to_f * 1000).to_i
50
+ request_id = Digest::SHA256.hexdigest(command.to_json)[..6]
51
+ requests[request_id] = {
52
+ request: command,
53
+ id: request_id,
54
+ lock: Mutex.new,
55
+ condition: ConditionVariable.new
56
+ }
57
+
58
+ exchange.publish(command.to_json,
59
+ routing_key: 'orderproxy_commands',
60
+ correlation_id: request_id,
61
+ reply_to: reply_queue.name)
62
+
63
+ # wait for the signal to continue the execution
64
+ #
65
+ requests[request_id][:lock].synchronize do
66
+ requests[request_id][:condition].wait(requests[request_id][:lock], timeout)
67
+ end
68
+
69
+ # if we reached timeout, we will return nil, just for explicity
70
+ response = requests[request_id][:response].dup
71
+ requests.delete(request_id)
72
+ response
73
+ end
74
+
75
+ alias_method :send_command, :command
76
+
77
+ def stop
78
+ commands.close
79
+ connection.close
80
+ end
81
+
82
+ def get_contracts(symbol:)
83
+ send_command({ command: :get_contracts, symbol: symbol })
84
+ end
85
+
86
+ attr_accessor :response
87
+ attr_reader :lock, :condition
88
+
89
+ private
90
+
91
+ attr_reader :call_id, :connection, :requests, :persistent,
92
+ :commands, :server_queue_name, :reply_queue, :exchange
93
+
94
+ def setup_reply_queue
95
+ @reply_queue = commands.queue('', exclusive: true, auto_delete: true)
96
+ @reply_queue.bind(commands.exchange('orderproxy_replies'), routing_key: @reply_queue.name)
97
+
98
+ reply_queue.subscribe do |delivery_info, properties, payload|
99
+ __id__ = properties[:correlation_id]
100
+
101
+ if __id__.nil?
102
+ puts "Received without __id__: #{delivery_info.map { |k, v| "#{k}\t#{v}" }.join("\n")
103
+ }\n\n#{properties.map { |k, v| "#{k}\t#{v}" }.join("\n")
104
+ }\n\n#{JSON.parse(payload).map { |k, v| "#{k}\t#{v}" }.join("\n")}" if @debug
105
+
106
+ elsif requests[__id__].nil?
107
+ puts "Received non-matching response, maybe previously timed out: \n\n#{delivery_info}\n\n#{properties}\n\n#{payload}\n."[..620].scan(/.{1,120}/).join(' '*30 + "\n") if @debug
108
+ else
109
+ # save the payload and send the signal to continue the execution of #command
110
+ # need to rescue the rare case, where lock and condition are destroyed right in parallel by timeout
111
+ begin
112
+ puts "Received result for #{__id__}" if @debug
113
+ requests[__id__][:response] = payload
114
+ requests[__id__][:lock].synchronize { requests[__id__][:condition].signal }
115
+ rescue nil
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ __END__
125
+ begin
126
+ client = OrderClient.new
127
+ reply = client.send_command( { command: 'ping' } )
128
+ puts reply.nil? ? 'nil' : JSON.parse(reply)
129
+ ensure
130
+ client.stop
131
+ end
@@ -53,5 +53,6 @@ module Cotcube
53
53
  end
54
54
  end
55
55
 
56
- require_relative 'cotcube-helpers/data_client'
57
- require_relative 'cotcube-helpers/cache_client'
56
+ %w[ data cache order josch ].each do |part|
57
+ require_relative "cotcube-helpers/#{part}_client"
58
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cotcube-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2.5
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin L. Tischendorf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-23 00:00:00.000000000 Z
11
+ date: 2021-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,7 +108,9 @@ files:
108
108
  - lib/cotcube-helpers/ib_contracts.rb
109
109
  - lib/cotcube-helpers/init.rb
110
110
  - lib/cotcube-helpers/input.rb
111
+ - lib/cotcube-helpers/josch_client.rb
111
112
  - lib/cotcube-helpers/numeric_ext.rb
113
+ - lib/cotcube-helpers/order_client.rb
112
114
  - lib/cotcube-helpers/orderclient.rb
113
115
  - lib/cotcube-helpers/output.rb
114
116
  - lib/cotcube-helpers/parallelize.rb