ampedxx-yrpc 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,79 @@
1
+ module Yrpc
2
+ class Client < SimpleDelegator
3
+
4
+ def initialize(service:, options: {}, client_options: {})
5
+ @base_klass = service
6
+ @service_klass = "#{base_klass}::Service".constantize
7
+ @opts = options || {}
8
+ @opts[:password] = options.fetch(:password, '').to_s
9
+ @opts[:hostname] = options.fetch(:hostname, Yrpc.default_client_host)
10
+ client = "#{service}::Stub".constantize.new(@opts[:hostname], build_ssl_credentials, interceptors: [*client_options[:interceptors]])
11
+ super(client)
12
+ end
13
+
14
+ attr_reader :service_klass
15
+ attr_reader :base_klass
16
+ attr_reader :opts
17
+
18
+ def invoke(request_method, params = {}, metadata={}, opts={}, &block)
19
+ request_method = request_method.to_sym
20
+ req = streaming_request?(request_method) ? params : request_object(request_method, params)
21
+ md = build_metadata(metadata)
22
+ call_sig = call_signature(request_method)
23
+ raise NotImplementedError, "The method #{request_method} has not been implemented in this service." unless call_sig
24
+ resp = execute(call_sig, req, md, opts, &block)
25
+ p resp
26
+ Response.new(resp)
27
+ end
28
+
29
+ def build_metadata(metadata = {})
30
+ unless opts[:password].empty?
31
+ username = opts.fetch(:username, 'grpc').to_s
32
+ username = username.empty? ? '' : "#{username}:"
33
+ auth_string = Base64.encode64("#{username}#{opts[:password]}")
34
+ metadata[:authorization] = "Basic #{auth_string}".tr("\n", '')
35
+ end
36
+ metadata
37
+ end
38
+
39
+ def execute(call_sig, req, metadata, opts = {}, &block)
40
+ # Timer.time do
41
+ opts[:return_op] = true
42
+ opts[:metadata] = metadata
43
+ # end
44
+ send(call_sig, req, opts, &block)
45
+ end
46
+
47
+ def rpc_desc(request_method)
48
+ service_klass.rpc_descs[request_method]
49
+ end
50
+
51
+ def request_object(request_method, params = {})
52
+ desc = rpc_desc(request_method)
53
+ desc && desc.input ? desc.input.new(params) : nil
54
+ end
55
+
56
+ def call_signature(request_method)
57
+ desc = rpc_desc(request_method)
58
+ desc && desc.name ? desc.name.to_s.underscore.to_sym : nil
59
+ end
60
+
61
+ def build_ssl_credentials
62
+ cert = nil
63
+ if opts[:ssl_certificate_file]
64
+ cert = File.read(opts[:ssl_certificate_file]).to_s.strip
65
+ elsif opts[:ssl_certificate]
66
+ cert = opts[:ssl_certificate].to_s.strip
67
+ end
68
+
69
+ cert ? GRPC::Core::ChannelCredentials.new(cert) : :this_channel_is_insecure
70
+ end
71
+
72
+ def streaming_request?(request_method)
73
+ desc = rpc_desc(request_method)
74
+ desc && (desc.client_streamer? || desc.bidi_streamer?)
75
+ end
76
+
77
+
78
+ end
79
+ end
@@ -0,0 +1,48 @@
1
+ require_relative "interceptors/active_record"
2
+ require 'logger'
3
+ module Yrpc
4
+ module Configuration
5
+ VALID_CONFIG_KEYS = {
6
+ server_binding_url: '0.0.0.0:9001',
7
+ interceptors: nil,
8
+ use_default_interceptors: true,
9
+ default_client_host: '',
10
+ controllers_path: 'app/controllers',
11
+ server_options: {},
12
+ services: [],
13
+ logger:nil,
14
+ use_ssl: false,
15
+ }.freeze
16
+
17
+ attr_accessor *VALID_CONFIG_KEYS.keys
18
+
19
+ def self.extended(base)
20
+ base.reset
21
+ end
22
+
23
+ def configure
24
+ yield self
25
+ end
26
+
27
+ def options
28
+ opts = {}
29
+ VALID_CONFIG_KEYS.each_key do |k|
30
+ opts.merge!(k => send(k))
31
+ end
32
+ opts
33
+ end
34
+
35
+ #重制一些配置
36
+ def reset
37
+ VALID_CONFIG_KEYS.each do |k, v|
38
+ send((k.to_s + '='), v)
39
+ end
40
+ self.logger = ::Logger.new(STDOUT)
41
+ self.interceptors = Yrpc::Interceptors::Registry.new
42
+ if use_default_interceptors
43
+ interceptors.use(Yrpc::Interceptors::ActiveRecord::ResetConnection)
44
+ end
45
+ options
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ module Yrpc
2
+ module Controllers
3
+ class Base
4
+ include ActiveSupport::Callbacks
5
+
6
+ define_callbacks :call
7
+
8
+ attr_reader :request
9
+
10
+
11
+ def initialize(method_key:, service:, rpc_desc:, active_call:, message:)
12
+ @request = Request.new(
13
+ method_key: method_key,
14
+ service: service,
15
+ rpc_desc: rpc_desc,
16
+ active_call: active_call,
17
+ message: message
18
+ )
19
+ end
20
+
21
+ def self.before_action(methods)
22
+ [*methods].each do |method|
23
+ set_callback :call, :before, method
24
+ end
25
+ end
26
+
27
+ def self.after_action(methods)
28
+ [*methods].each do |method|
29
+ set_callback :call, :after, method
30
+ end
31
+ end
32
+
33
+
34
+ def self.bind(service_class)
35
+ Yrpc.services << service_class.name.constantize
36
+ ServiceBinder.new(service_class).bind!(self)
37
+ end
38
+
39
+
40
+ def call(method_key, &block)
41
+ run_callbacks :call do
42
+ send(method_key, &block)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,91 @@
1
+ module Yrpc
2
+ module Controllers
3
+
4
+ class Request
5
+
6
+ attr_reader :message
7
+ # @var [GRPC::ActiveCall] active_call
8
+ attr_reader :active_call
9
+ # @var [Symbol] method_key
10
+ attr_reader :method_key
11
+ # @var [Grpc::Controllers::Request::Type] type
12
+ attr_reader :type
13
+ # @var [Class] service
14
+ attr_reader :service
15
+
16
+ delegate :metadata, to: :active_call
17
+ delegate :messages, :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :type
18
+
19
+ ##
20
+ # Abstract representation of a gRPC request type
21
+ #
22
+ class Type
23
+ delegate :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :@rpc_desc
24
+
25
+ ##
26
+ # Initialize a new request type object
27
+ #
28
+ # @param [GRPC::RpcDesc] rpc_desc The RPC descriptor for the request type
29
+ #
30
+ def initialize(rpc_desc)
31
+ @rpc_desc = rpc_desc
32
+ end
33
+ end
34
+
35
+ ##
36
+
37
+ #struct GRPC::RpcDesc
38
+ def initialize(method_key:, service:, rpc_desc:, active_call:, message:)
39
+ @method_key = method_key
40
+ @service = service
41
+ @active_call = active_call
42
+ @message = message
43
+ @rpc_desc = rpc_desc
44
+ @type = Type.new(rpc_desc)
45
+ end
46
+
47
+
48
+ def service_key
49
+ @service.name.underscore.tr('/', '.').gsub('.service', '')
50
+ end
51
+
52
+ def method_missing(method_id, *arguments, &block)
53
+ method_message = *arguments.join
54
+ if (method_id.to_s =~ /^raise_[\w]+/) == 0
55
+ error_type = method_id.to_s.split('raise_')[1].upcase!
56
+ code = "Yrpc::Response::Code::#{error_type}".constantize
57
+ message = method_message
58
+ raise Yrpc::Error::ResponseError.new(code, message)
59
+ else
60
+ super
61
+ end
62
+ end
63
+
64
+
65
+ def response_class
66
+ @rpc_desc.output
67
+ end
68
+
69
+
70
+ def request_class
71
+ @rpc_desc.input
72
+ end
73
+
74
+ # grpc 中的 service.method
75
+ def method_name
76
+ "#{service_key}.#{method_key}"
77
+ end
78
+
79
+ # 返回这个request的所有mesage 要根据stremer类型来判断
80
+ def messages
81
+ if client_streamer?
82
+ message.call { |msg| yield msg }
83
+ elsif bidi_streamer?
84
+ message
85
+ else
86
+ [message]
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,104 @@
1
+ module Yrpc
2
+
3
+ class Response
4
+
5
+ module Code
6
+ # 添加模型常量国际化方法
7
+ # include Dictionary::Module::I18n
8
+
9
+ ################################################################################
10
+ #
11
+ # 20000 成功
12
+ #
13
+ ################################################################################
14
+
15
+ SUCCESS = '20000'
16
+
17
+ ################################################################################
18
+ #
19
+ # 3xxxx 数据相关
20
+ #
21
+ ################################################################################
22
+
23
+ # 用户绑定第三方账户
24
+
25
+ # 第三方账户已绑定其它用户
26
+ PROVIDER_BIND_ANOTHER_USER = '30010'
27
+
28
+ ################################################################################
29
+ #
30
+ # 4xxxx 业务相关
31
+ #
32
+ ################################################################################
33
+
34
+ # 非法请求
35
+ INVALID_REQUEST = '40300'
36
+
37
+ # 终端密钥错误
38
+ INVALID_TERMINAL_SESSION_KEY = '40301'
39
+
40
+ # 用户密钥错误
41
+ INVALID_USER_SESSION_KEY = '40302'
42
+
43
+ # 超出请求限制数
44
+ EXCEED_REQUEST_LIMIT = '40303'
45
+
46
+ # 版本号不适配
47
+ NOT_COMPATIBLE_REVISION = '40304'
48
+
49
+ # 访问令牌过期
50
+ ACCESS_TOKEN_EXPIRED = '40305'
51
+
52
+ ################################################################################
53
+ #
54
+ # 5xxxx 系统相关
55
+ #
56
+ ################################################################################
57
+
58
+ # 未知错误(通常在捕捉异常后使用)
59
+ ERROR = '50000'
60
+
61
+ # 请求参数缺失
62
+ # Todo: 移动到数据相关
63
+ MISS_REQUEST_PARAMS = '50001'
64
+
65
+ # 数据处理错误
66
+ # Todo: 移动到数据相关
67
+ DATA_PROCESS_ERROR = '51000'
68
+
69
+ # 数据缺失错误
70
+ # Todo: 移动到数据相关
71
+ DATA_MISS_ERROR = '51001'
72
+
73
+ ORDER_PAYMENT_COMPLETED = '55000'
74
+
75
+ NEED_LOGIN = '40100'
76
+
77
+ ERROR_VALIDATE_CODE = '40200'
78
+
79
+ # 全部
80
+ # ALL = get_all_constants.map { |constant| constant.to_s.downcase }
81
+ end
82
+
83
+
84
+ def initialize(operation, execution_time = nil)
85
+ @operation = operation
86
+ @message = operation.execute
87
+ @metadata = operation.metadata
88
+ @trailing_metadata = operation.trailing_metadata
89
+ @deadline = operation.deadline
90
+ @cancelled = operation.cancelled?
91
+ @execution_time = execution_time || 0.0
92
+ end
93
+
94
+ def message
95
+ @message ||= @operation.execute
96
+ end
97
+
98
+ def status
99
+ @message ||= @operation.execute
100
+ @message&.status
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,87 @@
1
+ module Yrpc
2
+ module Controllers
3
+
4
+ class ServiceBinder
5
+ ##
6
+ #未来可能会有一些desc 的 拓展,先预留一个肉便器类。
7
+ #
8
+ class BoundDesc < SimpleDelegator;
9
+ end
10
+
11
+ #初始化。。没什么好解释的
12
+ def initialize(service)
13
+ @service = service
14
+ end
15
+
16
+
17
+ # 通过controller绑定所有的方法
18
+ def bind!(controller)
19
+ rpc_methods.each { |name, desc| bind_method(controller, name, desc) }
20
+ end
21
+
22
+ def rpc_desc(request_method)
23
+ @service.rpc_descs[request_method]
24
+ end
25
+
26
+ private
27
+
28
+
29
+ #打开类并且进行一个方法define,返回给这个方法打call。这里要注意的是request 会以参数形式构造进controller
30
+ #这里也涉及到stream 类型。
31
+ def bind_method(controller, method_name, desc)
32
+ method_desc = method_name.to_s.to_sym
33
+ method_key = method_name.to_s.underscore.to_sym
34
+ current_desc = rpc_desc(method_desc)
35
+ service_ref = @service
36
+ @service.class_eval do
37
+ if desc.request_response?
38
+ define_method(method_key) do |message, active_call|
39
+ c = controller.new(method_key: method_key, service: service_ref, message: message, active_call: active_call, rpc_desc: desc)
40
+ begin
41
+ c.call(method_key)
42
+ rescue => e
43
+ p method_key
44
+ p e.backtrace_locations
45
+ desc && desc.output ? desc.output.new(status: {code: e.respond_to?(:code) ? e.code : Yrpc::Response::Code::ERROR , message: e.message}) : (raise e)
46
+ end
47
+ end
48
+ elsif desc.client_streamer?
49
+ define_method(method_key) do |active_call|
50
+ c = controller.new(method_key: method_key, service: service_ref, message: proc { |&block| active_call.each_remote_read(&block) }, active_call: active_call, rpc_desc: desc)
51
+ begin
52
+ c.call(method_key)
53
+ rescue => e
54
+ desc && desc.output ? desc.output.new(status: {code: e&.code || Yrpc::Response::Code::ERROR, message: e.message}) : (raise e)
55
+ end
56
+ end
57
+ elsif desc.server_streamer?
58
+ define_method(method_key) do |message, active_call, &block|
59
+ c = controller.new(method_key: method_key, service: service_ref, message: message, active_call: active_call, rpc_desc: desc)
60
+ begin
61
+ c.call(method_key)
62
+ rescue => e
63
+ desc && desc.output ? desc.output.new(status: {code: e&.code || Yrpc::Response::Code::ERROR , message: e.message}) : (raise e)
64
+ end
65
+ end
66
+ else # bidi
67
+ define_method(method_key) do |messages, active_call, &block|
68
+ c = controller.new(method_key: method_key, service: service_ref, message: messages, active_call: active_call, rpc_desc: desc)
69
+ begin
70
+ c.call(method_key)
71
+ rescue => e
72
+ desc && desc.output ? desc.output.new(status: {code: e&.code || Yrpc::Response::Code::ERROR, message: e.message}) : (raise e)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ ##
80
+ # 讲方法都代理到boundDesc 上
81
+ #
82
+ def rpc_methods
83
+ @service.rpc_descs.map { |rd| BoundDesc.new(rd) }
84
+ end
85
+ end
86
+ end
87
+ end