需要使用多个模块功能,引用多个模块的时候,会出现冲突,导致只有一个模块的请求能成功
jasli2 opened this issue · 2 comments
jasli2 commented
如果需要使用多个模块功能的时候, 有出现一些问题。比如如下代码:
require 'tencentcloud-sdk-common'
require 'tencentcloud-sdk-sms'
require 'tencentcloud-sdk-captcha'
class Tc
def self.send_sms(phone, template_id, params)
begin
cre = TencentCloud::Common::Credential.new(Rails.application.credentials.tc[:app_id], Rails.application.credentials.tc[:app_key])
cli = TencentCloud::Sms::V20210111::Client.new(cre, 'ap-guangzhou')
req = TencentCloud::Sms::V20210111::SendSmsRequest.new([phone], '1400531212', template_id, '五号代理', params)
cli.SendSms(req)
rescue TencentCloud::Common::TencentCloudSDKException => e
Rails.logger.error '---- SendSms exception ----'
Rails.logger.error e
Rails.logger.error '---- end ----'
raise e
end
end
def self.captcha_check(appid, ticket, rand_str, ip)
return false if appid != Rails.application.credentials.tc[:captcha_id]
return false if ticket.nil? || rand_str.nil? || ip.nil?
begin
cre = TencentCloud::Common::Credential.new(Rails.application.credentials.tc[:app_id], Rails.application.credentials.tc[:app_key])
cli = TencentCloud::Captcha::V20190722::Client.new(cre, 'ap-guangzhou')
req = TencentCloud::Captcha::V20190722::DescribeCaptchaResultRequest.new(9, ticket, ip, rand_str, appid.to_i, Rails.application.credentials.tc[:captcha_key])
response = cli.DescribeCaptchaResult(req)
if response.CaptchaCode == 1
return true
else
Rails.logger.error '---- DescribeCaptchaResult failed ----'
Rails.logger.error response.CaptchaCode
Rails.logger.error response.CaptchaMsg
Rails.logger.error response.EvilLevel
Rails.logger.error '---- end ----'
return false
end
return true
rescue TencentCloud::Common::TencentCloudSDKException => e
Rails.logger.error '---- DescribeCaptchaResult exception ----'
Rails.logger.error e
Rails.logger.error '---- end ----'
raise e
end
end
end
以上代码,如果调用 Tc.captcha_check(....)
, 调用会成功。
但是如果调用 Tc.send_sms(.....)
,则会报错:
[TencentCloudSDKError] Code=InvalidAction, Message=The request action=`SendSms` is invalid or not found in service=`captcha` and version=`2019-07-22`., RequestId=a00c0378-21c7-4d15-8465-1a4347cc3ff5
而且,require的顺序会带来不一样的错误。其行为是:只有最后引用的模块(如 tencentcloud-sdk-captcha )能正常运行。
问题根源
查看sdk源码,发现主要的问题是client的抽象父类中定义的class variable带来的:api_version,endpoint, sdk_version
class AbstractClient
include Log
@@api_version = ''
@@endpoint = ''
@@sdk_version = '1.0.90'
def initialize(credential, region, profile = nil)
raise TencentCloudSDKException.new('InvalidCredential', 'Credential is None or invalid') unless credential
@credential = credential
@region = region
@profile = profile || ClientProfile.new
@request = ApiRequset.new(@profile.http_profile.scheme, endpoint, nil, @profile.http_profile.req_timeout, @profile.http_profile.proxy)
end
这三个class variable,会在各个子类中覆盖,例如,在 tencentcloud-sdk-captcha 中:
module TencentCloud
module Captcha
module V20190722
class Client < TencentCloud::Common::AbstractClient
@@api_version = '2019-07-22'
@@endpoint = 'captcha.tencentcloudapi.com'
@@sdk_version = 'CAPTCHA_' + File.read(File.expand_path('../VERSION', __dir__)).strip
这样一来,这个class variable就会在引用的时候被写入。在只使用单个模块的时候不会有问题。但是多个模块的时候就会出问题。这个问题同样会造成同一个模块的不同版本被覆盖。比如 sms 模块中的不同版本。
临时解法
我目前的解决办法如下,在抽象的client类中这样定义这些变量为实例变量:
class AbstractClient
include Log
def initialize(credential, region, profile = nil, api_version, endpoint, sdk_version)
raise TencentCloudSDKException.new('InvalidCredential', 'Credential is None or invalid') unless credential
@api_version = api_version
@endpoint = endpoint
@sdk_version = sdk_version
@credential = credential
@region = region
@profile = profile || ClientProfile.new
@request = ApiRequset.new(@profile.http_profile.scheme, endpoint, nil, @profile.http_profile.req_timeout, @profile.http_profile.proxy)
end
然后在继承类的初始化函数中,初始化对应的变量。这样不同的模块示例不会互相干扰:
module Captcha
module V20190722
class Client < TencentCloud::Common::AbstractClient
attr_writer :api_version, :endpoint, :sdk_version
def initialize(credential, region, profile = nil)
super(credential, region, profile, '2019-07-22', 'captcha.tencentcloudapi.com', 'CAPTCHA_' + File.read(File.expand_path('../VERSION', __dir__)).strip)
end
但是这样的改法需要所有的模块都做出同样的改动,供你们参考。
zqfan commented
感谢反馈,我们刚根据您的建议发布了新版本,应该可以解决你的问题
jasli2 commented
好的,我想这个问题可以关闭了