Threading in the Ruby SDK
Threads in a Ruby program help you achieve parallelism. By using multiple threads, you can make a Ruby program run faster and do multiple things simultaneously.
The Ruby SDK (from version 2.x.x) supports both single-threading and multi-threading irrespective of a single-user or a multi-user app.
Refer to the below code snippets that use multi-threading for a single-user and multi-user app.
Multi-threading in a Multi-user App
The program execution starts from execute().
The details of "user1" are given in the variables user1, token1, environment1.
Similarly, the details of another user "user2" are given in the variables user2, token2, environment2.
For each user, an instance of MultiThreading class is created.
When t1.join is called which in-turn invokes the thread which has the details of user1 are passed to the switch_user function through the func1(). Therefore, this creates a thread for user1.
Similarly, When the t2.join is invoked , the details of user2 are passed to the switch_user function through the func1(). Therefore, this creates a thread for user2.
Multi-threading for multi-users is achieved using Initializer’s static switch_user().
Initializer.switch_user(user, environment, token, sdk_config)
Initializer.switch_user(user, environment, token, sdk_config, proxy)
require 'ZOHOCRMSDK2_0'
module MultiUser
class MultiThreading
def initialize(module_api_name)
@module_api_name = module_api_name
end
def execute(user_signature, environment, token,tokenstore, sdk_config,resources_path, log, proxy)
Initializer.initialize(user_signature, environment, token, tokenstore, sdk_config, resources_path, log)
token1 =Authenticator::OAuthToken.new("clientId", "clientSecret", "REFRESH/GRANT token", TokenType::REFRESH/GRANT, "redirectURL")
user1 = UserSignature.new('abc@zohocorp.com')
environment1 = DC::USDataCenter::PRODUCTION
sdk_config1 = SDKConfig::Builder.new.auto_refresh_fields(false).pick_list_validation(true).build
t1 = Thread.new{func1(user1,environment1,token1,sdk_config1)}
token2 = Authenticator::OAuthToken.new("clientId", "clientSecret", "REFRESH/GRANT token", TokenType::REFRESH/GRANT, "redirectURL")
user2 = UserSignature.new('dfg@zohocorp.com')
environment2 = DC::USDataCenter::PRODUCTION
sdk_config2 = SDKConfig::Builder.new.auto_refresh_fields(false).pick_list_validation(true).build
t2 = Thread.new{func1(user2,environment2,token2,sdk_config2)}
t1.join
t2.join
end
def func1(user,environment,token,sdk_config)
Initializer.switch_user(user,environment,token,sdk_config)
print Initializer.get_initializer.user.email
ro = Record::RecordOperations.new
ro.get_records(nil,nil,@module_api_name)
end
end
end
log = SDKLog::Log.initialize(Levels::INFO,"/Users/user_name/Documents/rubysdk_log.log")
user_signature = UserSignature.new('abc@zohocorp.com')
environment = DC::USDataCenter::PRODUCTION
token = Authenticator::OAuthToken.new("clientId", "clientSecret", "REFRESH/GRANT token", TokenType::REFRESH/GRANT, "redirectURL")
tokenstore = Store::FileStore.new("/Users/user_name/Documents/ruby_sdk_token.txt")
sdk_config = SDKConfig::Builder.new.auto_refresh_fields(false).pick_list_validation(true).build
proxy = RequestProxy.new("proxyHost", "proxyPort", "proxyUser", "password")
module_api_name = "Leads"
resource_path = "/Users/user_name/Documents"
MultiUser::MultiThreading.new(module_api_name).execute(user_signature, environment, token,tokenstore, sdk_config,resource_path, log,proxy)
Multi-threading in a Single-user App
require 'ZOHOCRMSDK2_0'
module SingleUser
class MultiThreading
def execute(user_signature, environment, token,tokenstore, sdk_config,resources_path, log,proxy)
Initializer.initialize(user_signature, environment, token, tokenstore, sdk_config, resources_path, log)
t1 = Thread.new{func1("Leads")}
t2 = Thread.new{func1("Deals")}
t1.join
t2.join
end
def func1(module_api_name)
ro = Record::RecordOperations.new
ro.get_records(nil,nil,module_api_name).inspect
end
end
end
log = SDKLog::Log.initialize(Levels::INFO,"/Users/user_name/Documents/rubysdk_log.log")
user_signature = UserSignature.new('abc@zohocorp.com')
environment = DC::USDataCenter::PRODUCTION
token = Authenticator::OAuthToken.new("clientId", "clientSecret", "REFRESH/GRANT token", TokenType::REFRESH/GRANT, "redirectURL")
tokenstore = Store::FileStore.new("/Users/user_name/Documents/ruby_sdk_token.txt")
sdk_config = SDKConfig::Builder.new.auto_refresh_fields(false).pick_list_validation(true).build
proxy = RequestProxy.new("proxyHost", "proxyPort", "proxyUser", "password")
resource_path = "/Users/user_name/Documents/rubysdk-application"
SingleUser::MultiThreading.new.execute(user_signature, environment, token,tokenstore, sdk_config,resource_path, log,proxy)
SDK Sample Code
require 'ZOHOCRMSDK2_0'
require 'date'
class Records
def get_records
# Create an instance of Log::SDKLog Class that takes two parameters
#1 -> Level of the log messages to be logged. Can be configured by typing Levels "::" and choose any level from the list displayed.
# 2 -> Absolute file path, where messages need to be logged.
log = SDKLog::Log.initialize(Levels::INFO,"/Users/user_name/Documents/rubysdk_log.log")
#Create an UserSignature instance that takes user Email as parameter
user_signature = UserSignature.new('abc@zohocorp.com')
# Configure the environment
# which is of the pattern Domain.Environment
# Available Domains: USDataCenter, EUDataCenter, INDataCenter, CNDataCenter, AUDataCenter
# Available Environments: PRODUCTION, DEVELOPER, SANDBOX
environment = DC::USDataCenter::PRODUCTION
#Create a Token instance
#1 -> OAuth client id.
#2 -> OAuth client secret.
#3 -> REFRESH/GRANT token.
#4 -> Token type(REFRESH/GRANT).
#5 -> OAuth redirect URL.(optional)
token = Authenticator::OAuthToken.new("clientId", "clientSecret", "REFRESH/GRANT token", TokenType::REFRESH/GRANT, "redirectURL")
#Create an instance of TokenStore.
#1 -> DataBase host name. Default "localhost"
#2 -> DataBase name. Default "zohooauth"
#3 -> DataBase user name. Default "root"
#4 -> DataBase password. Default ""
#5 -> DataBase port number. Default "3306"
store = Store::DBStore.new("hostName", "dataBaseName", "userName", "password", "portNumber")
#store = Store::FileStore.new("/Users/user_name/Documents/ruby_sdk_token.txt"
# auto_refresh_fields
# if true - all the modules' fields will be auto-refreshed in the background, every hour.
# if false - the fields will not be auto-refreshed in the background. The user can manually delete the file(s) or refresh the fields using methods from ModuleFieldsHandler (Util::ModuleFieldsHandler)
#
# pick_list_validation
# A boolean field that validates user input for a pick list field and allows or disallows the addition of a new value to the list.
# if true - the SDK validates the input. If the value does not exist in the pick list, the SDK throws an error.
# if false - the SDK does not validate the input and makes the API request with the user’s input to the pick list
sdk_config = SDKConfig::Builder.new.auto_refresh_fields(false).pick_list_validation(true).build
resource_path = "/Users/user_name/Documents/rubysdk-application"
# Create an instance of RequestProxy class that takes the following parameters
# 1 -> Host
# 2 -> Port Number
# 3 -> User Name
# 4 -> Password
request_proxy = RequestProxy.new('proxyHost', 'proxyPort', 'proxyUser', 'password')
# The initialize method of Initializer class that takes the following arguments
# 1 -> UserSignature instance
# 2 -> Environment instance
# 3 -> Token instance
# 4 -> TokenStore instance
# 5 -> SDKConfig instance
# 6 -> resourcePath -A String
# 7 -> Log instance (optional)
# 8 -> RequestProxy instance (optional)
#The following is the initialize method
Initializer.initialize(user_signature, environment, token, store, sdk_config, resources_path, log, request_proxy)
# Get instance of RecordOperations Class
ro = Record::RecordOperations.new
# Get instance of ParameterMap Class
pm = ParameterMap.new
pm.add(Record::RecordOperations::GetRecordParam.approved, 'false')
pm.add(Record::RecordOperations::GetRecordParam.converted, 'false')
hm = HeaderMap.new
hm.add(Record::RecordOperations::GetRecordHeader.If_modified_since, DateTime.new(2019, 8, 10, 4, 11, 9, '+03:00'))
module_api_name = "Leads"
response = ro.get_records(pm, hm, module_api_name)
unless response.nil?
status_code = response.status_code
# Get the status code from response
print "\n Status Code :" + status_code.to_s
if [204, 304].include? status_code
print(status_code == 204 ? 'No Content' : 'Not Modified')
return
end
# Check if expected instance is received.
if response.is_expected
# Get object from response
response_handler = response.data_object
# Check if expected ResponseWrapper instance is received
if response_handler.is_a? Record::ResponseWrapper
records = response_handler.data
records.each do |record|
# Get the ID of each Record
print "\n Record ID: "
print record.id.to_s
created_by = record.created_by
# Check if created_by is not None
unless created_by.nil?
# Get the Name of the created_by User
print "\n Record Created By User-Name: "
print created_by.name
# Get the ID of the created_by User
print "\n Record Created By User-Id: "
print created_by.id.to_s
# Get the Email of the created_by User
print "\n Record Created By User-Email: "
print created_by.email
end
# Get the CreatedTime of each Record
print "\n Record CreatedTime: "
print record.created_time
# Get the modified_by User instance of each Record
modified_by = record.modified_by
# Check if modifiedBy is not None
unless modified_by.nil?
# Get the Name of the modified_by User
print "\n Record Modified By User-Name: "
print modified_by.name
# Get the ID of the modified_by User
print "\n Record Modified By User-Id: "
print modified_by.id.to_s
# Get the Email of the modified_by User
print "\n Record Modified By User-Email: "
print modified_by.email
end
# Get the ModifiedTime of each Record
print "\n Record ModifiedTime: "
print record.modified_time
tags = record.tag
if !tags.nil? && tags.size.positive?
tags.each do |tag|
# Get the Name of each Tag
print "\n Record Tag Name: "
print tag.name
# Get the Id of each Tag
print "\n Record Tag ID: "
print tag.id.to_s
end
end
# To get particular field value
print "\n Record Field Value: "
print record.get_key_value('Last_Name')
# To get particular KeyValues
print "\n Record KeyValues:"
record.get_key_values.each do |key_name, value|
print "\n "
unless value.nil?
print key_name
print value
end
end
end
end
end
end
end
end
Records.new.get_records