Skip to main content

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