t-tech-investments 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20123e15a4902951a5ee22661123c8a69ec7a55573203f505ec3f2ffd0016fc4
4
- data.tar.gz: 24cd3848684453f36079b82c8398c9f69e8d29d422375e6396654b2b55eadd09
3
+ metadata.gz: 4bf8867c825875c3ae7f360a619639d0a4625a9f32f3a068e1c3636f649fbff5
4
+ data.tar.gz: c062acc25e8df6ffe8503331b054a481390e051c0be0cb99a895d7dbf8bd2be8
5
5
  SHA512:
6
- metadata.gz: 4c2ab86b84b0303698ccb523c981e1437da6d0efb7a111971f7682db44e8bb855c26b1582a977b047ff2c111683f718fcd08ddb88956df32745fa620de39191d
7
- data.tar.gz: 63a2b49c538d2b9c95f204e517325630de7ac26f9e5397002a81cf8cc6f15a991f99904195241bbbc21f84faa8324a688a0bcf8c3a6664d9bb68dc42ece6143c
6
+ metadata.gz: b9e479135ca5169147c694d1c0e10369a5dda50d81e783b1a0ddb18c5cf385734e40ff1ffe31b3df12db2d9033e23ef2ebd80389d1733161b6028ff93d04d08d
7
+ data.tar.gz: d808c48241f5af9c48ce21709443c44555d9efec9719947c32a6aded19cb862b9611559ceaa4ed354dc83e7e9db433f661c9f932aa2f8ece215cb93cbb7de48f
@@ -15,7 +15,7 @@ alwaysApply: true
15
15
 
16
16
  - `Services` не вызывают gRPC stub напрямую — только через `Transport`.
17
17
  - Публичный API не возвращает protobuf по умолчанию (только `raw:`/debug, если нужен).
18
- - `Transport` без бизнес-логики; только: metadata, deadlines, retries-policy, error mapping.
18
+ - `Transport` без бизнес-логики; только: metadata, deadlines, error mapping. Retry и управление состоянием соединения — **не** зона ответственности библиотеки; пользователь сам реализует повторные попытки при необходимости.
19
19
  - `Coercers/Mappers` — чистые и детерминированные (без IO/сети).
20
20
 
21
21
  ## Контракты (invest-contracts)
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.2] - Unreleased
4
+
5
+ - Version bump for next development cycle
6
+
7
+ ## [0.2.1] - 2026-02-06
8
+
9
+ - ProtoLoader: harden loading order and market data signatures; add specs
10
+ - Docs: clarify retry responsibility and client cleanup; remove stray gem artifact
11
+
3
12
  ## [0.2.0] - 2026-02-06
4
13
 
5
14
  - Client: services exposed via Registry (method_missing), no hardcoded list; facades (e.g. market_data) discovered dynamically
data/README.md CHANGED
@@ -142,6 +142,8 @@ client = T::Tech::Investments.client(
142
142
  - **Prod vs Sandbox**: distinguish environments only by the endpoint from the docs:
143
143
  - **Prod**: `invest-public-api.tbank.ru:443`
144
144
  - **Sandbox**: `sandbox-invest-public-api.tbank.ru:443`
145
+ - **Retries and connection state**: the library does not retry failed calls. The application is responsible for retries, reconnects, and connection state; implement retry logic in your code if needed.
146
+ - **Long-lived processes**: when shutting down or discarding a client, call `client.transport.close` to release gRPC channel and stubs.
145
147
 
146
148
  ### Unary requests (data fetch)
147
149
 
@@ -8,22 +8,65 @@ module T
8
8
  module ProtoLoader
9
9
  PROTO_DIR = File.expand_path("proto", __dir__)
10
10
 
11
- module_function
12
-
13
- def load!
14
- return if @loaded
15
-
16
- $LOAD_PATH.unshift(PROTO_DIR) unless $LOAD_PATH.include?(PROTO_DIR)
17
- pb_files = Dir[File.join(PROTO_DIR, "*_pb.rb")]
18
- .reject { |f| f.end_with?("_services_pb.rb") }
19
- .map { |f| File.basename(f, ".rb") }
20
- .sort
21
- services_files = Dir[File.join(PROTO_DIR, "*_services_pb.rb")]
22
- .map { |f| File.basename(f, ".rb") }
23
- .sort
24
- pb_files = pb_files.partition { |f| f == "common_pb" }.flatten
25
- (pb_files + services_files).each { |f| require f }
26
- @loaded = true
11
+ @load_mutex = Mutex.new
12
+ @load_cv = ConditionVariable.new
13
+ @loaded = false
14
+ @loading = false
15
+ @loading_thread = nil
16
+ @load_error = nil
17
+
18
+ class << self
19
+ def load!
20
+ @load_mutex.synchronize do
21
+ return if @loaded
22
+
23
+ if @loading
24
+ if @loading_thread == Thread.current
25
+ raise RuntimeError, "ProtoLoader.load! re-entrant call while loading"
26
+ end
27
+ @load_cv.wait(@load_mutex) while @loading
28
+ return if @loaded
29
+ raise @load_error if @load_error
30
+ end
31
+
32
+ @load_error = nil
33
+ @loading = true
34
+ @loading_thread = Thread.current
35
+ end
36
+
37
+ begin
38
+ load_files
39
+ @load_mutex.synchronize do
40
+ @loaded = true
41
+ @loading = false
42
+ @loading_thread = nil
43
+ @load_cv.broadcast
44
+ end
45
+ rescue StandardError => e
46
+ @load_mutex.synchronize do
47
+ @load_error = e
48
+ @loading = false
49
+ @loading_thread = nil
50
+ @load_cv.broadcast
51
+ end
52
+ raise
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def load_files
59
+ $LOAD_PATH.unshift(PROTO_DIR) unless $LOAD_PATH.include?(PROTO_DIR)
60
+ pb_files = Dir[File.join(PROTO_DIR, "*_pb.rb")]
61
+ .reject { |f| f.end_with?("_services_pb.rb") }
62
+ .map { |f| File.basename(f, ".rb") }
63
+ .sort
64
+ services_files = Dir[File.join(PROTO_DIR, "*_services_pb.rb")]
65
+ .map { |f| File.basename(f, ".rb") }
66
+ .sort
67
+ pb_files = pb_files.partition { |f| f == "common_pb" }.flatten
68
+ (pb_files + services_files).each { |f| require f }
69
+ end
27
70
  end
28
71
  end
29
72
  end
@@ -18,14 +18,16 @@ module T
18
18
  #
19
19
  # @param timeout [Integer, nil] optional stream timeout in seconds
20
20
  # @yield [MarketDataStreamSession] session to subscribe and call each_event on
21
- def stream(timeout: nil, &block)
22
- session = nil
23
- return unless block_given?
24
-
21
+ def stream(timeout: nil)
25
22
  session = MarketDataStreamSession.new(@transport, timeout: timeout)
26
- block.call(session)
27
- ensure
28
- session&.close
23
+ return session unless block_given?
24
+
25
+ begin
26
+ yield session
27
+ ensure
28
+ session.close
29
+ end
30
+ nil
29
31
  end
30
32
 
31
33
  def method_missing(method_name, *args, **kwargs, &block)
@@ -3,7 +3,7 @@
3
3
  module T
4
4
  module Tech
5
5
  module Investments
6
- VERSION = "0.2.0"
6
+ VERSION = "0.2.2"
7
7
  end
8
8
  end
9
9
  end
@@ -141,6 +141,16 @@ module T::Tech::Investments
141
141
  class MarketDataFacade
142
142
  def initialize: (UnaryAdapter unary_adapter, Transport transport) -> void
143
143
  def stream: (?timeout: Integer) { (MarketDataStreamSession) -> void } -> void
144
+ def stream: (?timeout: Integer) -> MarketDataStreamSession
145
+ def get_candles: (**untyped kwargs) -> untyped
146
+ def get_last_prices: (**untyped kwargs) -> untyped
147
+ def get_order_book: (**untyped kwargs) -> untyped
148
+ def get_trading_status: (**untyped kwargs) -> untyped
149
+ def get_trading_statuses: (**untyped kwargs) -> untyped
150
+ def get_last_trades: (**untyped kwargs) -> untyped
151
+ def get_close_prices: (**untyped kwargs) -> untyped
152
+ def get_tech_analysis: (**untyped kwargs) -> untyped
153
+ def get_market_values: (**untyped kwargs) -> untyped
144
154
  end
145
155
  end
146
156
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t-tech-investments
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pushkin Ivan