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.0.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
Multi-threading for multi-users is achieved using Initializer's static switch_user().
switch_user() takes the value initialized previously for user, enviroment, token and sdk_config incase None is passed (or default value is passed). In case of request_proxy, if intended, the value has to be passed again else None(default value) will be taken.
Multi-threading for multi-users is achieved using Initializer’s static switch_user().
ZOHOCRMSDK::Initializer.switch_user(user: user, environment:environment, token:token, sdk_config:sdk_config)
ZOHOCRMSDK::Initializer.switch_user(user: user, environment:environment, token:token, sdk_config:sdk_config, request_proxy: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)
ZOHOCRMSDK::Initializer.initialize(user: user_signature, environment: environment, token: token, store: tokenstore, sdk_config: sdk_config, resources_path: resource_path, log:log, request_proxy: proxy)
token1 = ZOHOCRMSDK::Authenticator::OAuthToken.new(client_id: "clientId", client_secret:"clientSecret", grant_token:"grant_token", refresh_token:"refresh_token", redirect_url:"redirectURL","id")
user1 = ZOHOCRMSDK::UserSignature.new('abc@zohocorp.com')
environment1 = ZOHOCRMSDK::DC::USDataCenter::PRODUCTION
sdk_config1 = ZOHOCRMSDK::SDKConfig.new(auto_refresh_fields: false,pick_list_validation: true,open_timeout: 60,read_timeout: 60,write_timeout: 60,keep_alive_timeout: 2)
t1 = Thread.new{func1(user1,environment1,token1,sdk_config1)}
token2 = ZOHOCRMSDK::Authenticator::OAuthToken.new(client_id: "clientId", client_secret:"clientSecret", grant_token:"grant_token", refresh_token:"refresh_token", redirect_url:"redirectURL","id")
user2 = ZOHOCRMSDK::UserSignature.new('dfg@zohocorp.com')
environment2 = ZOHOCRMSDK::DC::USDataCenter::PRODUCTION
sdk_config2 = ZOHOCRMSDK::SDKConfig.new(auto_refresh_fields: false, pick_list_validation: true, open_timeout: 60, read_timeout: 60,write_timeout: 60,keep_alive_timeout: 2)
t2 = Thread.new{func1(user2, environment2, token2, sdk_config2)}
t1.join
t2.join
end
def func1(user,environment,token,sdk_config)
ZOHOCRMSDK::Initializer.switch_user(user: user, environment:environment, token:token, sdk_config:sdk_config)
print ZOHOCRMSDK::Initializer.get_initializer.user.email
ro = ZOHOCRMSDK::Record::RecordOperations.new
ro.get_records(@module_api_name,nil,nil)
end
end
end
log = ZOHOCRMSDK::SDKLog::Log.initialize(level:ZOHOCRMSDK::Levels::INFO, path:"/Users/user_name/Documents/rubysdk_log.log")
user_signature = ZOHOCRMSDK::UserSignature.new('abc@zohocorp.com')
environment = ZOHOCRMSDK::DC::USDataCenter::PRODUCTION
token = ZOHOCRMSDK::Authenticator::OAuthToken.new(client_id: "clientId", client_secret:"clientSecret", grant_token:"grant_token", refresh_token:"refresh_token", redirect_url:"redirectURL","id")
tokenstore = ZOHOCRMSDK::Store::FileStore.new("/Users/user_name/Documents/ruby_sdk_token.txt")
sdk_config = ZOHOCRMSDK::SDKConfig.new(auto_refresh_fields: false,pick_list_validation: true, open_timeout: 60, read_timeout: 60, write_timeout: 60,keep_alive_timeout: 2)
proxy = ZOHOCRMSDK::RequestProxy.new(host:"proxyHost", post:"proxyPort", user_name:"proxyUser", password:"password")
module_api_name = "Leads"
resource_path = "/Users/user_name/Documents"
ZOHOCRMSDK::MultiUser::MultiThreading.new(module_api_name).execute(user_signature, environment, token,tokenstore, sdk_config,resource_path, log,proxy)
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 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)
ZOHOCRMSDK::Initializer.initialize(user: user_signature, environment: environment, token: token, store: tokenstore, sdk_config: sdk_config, resources_path: resource_path, log:log, request_proxy: proxy)
t1 = Thread.new{func1("Leads")}
t2 = Thread.new{func1("Deals")}
t1.join
t2.join
end
def func1(module_api_name)
ro = ZOHOCRMSDK::Record::RecordOperations.new
ro.get_records(module_api_name,nil,nil)
end
end
end
log = ZOHOCRMSDK::SDKLog::Log.initialize(level:ZOHOCRMSDK::Levels::INFO,path:"/Users/user_name/Documents/rubysdk_log.log")
user_signature = ZOHOCRMSDK::UserSignature.new('abc@zohocorp.com')
environment = ZOHOCRMSDK::DC::USDataCenter::PRODUCTION
token = ZOHOCRMSDK::Authenticator::OAuthToken.new(client_id: "clientId", client_secret:"clientSecret", grant_token:"grant_token", refresh_token:"refresh_token", redirect_url:"redirectURL", id:"id")
tokenstore = ZOHOCRMSDK::Store::FileStore.new("/Users/user_name/Documents/ruby_sdk_token.txt")
sdk_config = ZOHOCRMSDK::SDKConfig.new(auto_refresh_fields: false, pick_list_validation: true, open_timeout: 60, read_timeout: 60, write_timeout: 60,keep_alive_timeout: 2)
proxy = ZOHOCRMSDK::RequestProxy.new(host:"proxyHost", post:"proxyPort", user_name:"proxyUser", password:"password")
resource_path = "/Users/user_name/Documents/rubysdk-application"
SingleUser::MultiThreading.new.execute(user_signature, environment, token,tokenstore, sdk_config, resource_path, log, proxy)
The program execution starts from execute() where the SDK is initialized with the details of user and an instance of MultiThreading class is created.
When the t1.join is called which in-turn invokes the func1(), the module_api_name is switched through the MultiThreading object. Therefore, this creates a thread for the particular operation
Similarly, When the t2.join is invoked , the module_api_name is switched through the MultiThreading object. Therefore, this creates a thread for the particular operation
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 = ZOHOCRMSDK::SDKLog::Log.initialize(level:ZOHOCRMSDK::Levels::INFO, path:"/Users/user_name/Documents/rubysdk_log.log")
#Create an UserSignature instance that takes user Email as parameter
user_signature = ZOHOCRMSDK::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 = ZOHOCRMSDK::DC::USDataCenter::PRODUCTION
#Create a Token instance
#1 -> OAuth client id.
#2 -> OAuth client secret.
#3 -> grant token
#4 -> refresh token
#5 -> OAuth redirect URL.
#6 -> id
token = ZOHOCRMSDK::Authenticator::OAuthToken.new(client_id: "clientId", client_secret:"clientSecret", grant_token:"grant_token", refresh_token:"refresh_token", redirect_url:"redirectURL", id:"id")
#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 = ZOHOCRMSDK::Store::DBStore.new(host: "host_name", database_name: "database_name", table_name: "table_name", user_name: "user_name", password: "password", port_number:"port_number")
#store = ZOHOCRMSDK::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 (ZOHOCRMSDK::Util::ModuleFieldsHandler)
#
# pickListValidation
# if true - value for any picklist field will be validated with the available values.
# if false - value for any picklist field will not be validated, resulting in creation of a new value.
#
# open_timeout
# Number of seconds to wait for the connection to open (default 60 seconds)
#
# read_timeout
# Number of seconds to wait for one block to be read (via one read(2) call) (default 60 seconds)
#
# write_timeout
# Number of seconds to wait for one block to be written (via one write(2) call) (default 60 seconds)
#
# keep_alive_timeout
# Seconds to reuse the connection of the previous request(default 2 seconds)
#
sdk_config = ZOHOCRMSDK::SDKConfig.new(auto_refresh_fields: false, pick_list_validation: true, open_timeout: 60, read_timeout: 60, write_timeout: 60, keep_alive_timeout: 2)
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 = ZOHOCRMSDK::RequestProxy.new(host:"proxyHost", post:"proxyPort", user_name:"proxyUser", password:"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
ZOHOCRMSDK::Initializer.initialize(user: user_signature, environment: environment, token: token, store: store, sdk_config: sdk_config, resources_path: resource_path, log:log, request_proxy: request_proxy)
# Get instance of RecordOperations Class
ro = ZOHOCRMSDK::Record::RecordOperations.new
# Get instance of ParameterMap Class
pm = ZOHOCRMSDK::ParameterMap.new
pm.add(ZOHOCRMSDK::Record::RecordOperations::GetRecordParam.approved, 'false')
pm.add(ZOHOCRMSDK::Record::RecordOperations::GetRecordParam.converted, 'false')
hm = ZOHOCRMSDK::HeaderMap.new
hm.add(ZOHOCRMSDK::Record::RecordOperations::GetRecordHeader.If_modified_since, DateTime.new(2019, 8, 10, 4, 11, 9, '+03:00'))
module_api_name = "Leads"
response = ro.get_records(module_api_name,pm, hm)
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? ZOHOCRMSDK::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