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.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