Skip to content

Commit

Permalink
misc(throttling): Add throttling to hubspot services and specs
Browse files Browse the repository at this point in the history
  • Loading branch information
ivannovosad committed Nov 27, 2024
1 parent 22981ae commit 8ba7da9
Show file tree
Hide file tree
Showing 44 changed files with 177 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CreateJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(credit_note:)
result = Integrations::Aggregator::CreditNotes::CreateService.call(credit_note:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class CreateCustomerAssociationJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(invoice:)
result = Integrations::Aggregator::Invoices::Hubspot::CreateCustomerAssociationService.call(invoice:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class CreateJob < ApplicationJob
retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(invoice:)
result = Integrations::Aggregator::Invoices::Hubspot::CreateService.call(invoice:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class UpdateJob < ApplicationJob
retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(invoice:)
result = Integrations::Aggregator::Invoices::Hubspot::UpdateService.call(invoice:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class CreateCustomerAssociationJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Hubspot::CreateCustomerAssociationService.call(subscription:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class CreateJob < ApplicationJob
retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Hubspot::CreateService.call(subscription:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class UpdateJob < ApplicationJob
retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 10
retry_on Integrations::Aggregator::BasePayload::Failure, wait: :polynomially_longer, attempts: 10
retry_on RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(subscription:)
result = Integrations::Aggregator::Subscriptions::Hubspot::UpdateService.call(subscription:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Aggregator
class SyncCustomObjectsAndPropertiesJob < ApplicationJob
queue_as 'integrations'

retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
Integrations::Hubspot::Invoices::DeployObjectService.call(integration:)
Integrations::Hubspot::Subscriptions::DeployObjectService.call(integration:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class DeployPropertiesJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on Integrations::Aggregator::RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
result = Integrations::Hubspot::Companies::DeployPropertiesService.call(integration:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class DeployPropertiesJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on Integrations::Aggregator::RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
result = Integrations::Hubspot::Contacts::DeployPropertiesService.call(integration:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class DeployObjectJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on Integrations::Aggregator::RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
result = Integrations::Hubspot::Invoices::DeployObjectService.call(integration:)
Expand Down
1 change: 1 addition & 0 deletions app/jobs/integrations/hubspot/save_portal_id_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class SavePortalIdJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on Integrations::Aggregator::RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
result = Integrations::Hubspot::SavePortalIdService.call(integration:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class DeployObjectJob < ApplicationJob

retry_on LagoHttpClient::HttpError, wait: :polynomially_longer, attempts: 3
retry_on Integrations::Aggregator::RequestLimitError, wait: :polynomially_longer, attempts: 100
retry_on BaseService::ThrottlingError, wait: :polynomially_longer, attempts: 25

def perform(integration:)
result = Integrations::Hubspot::Subscriptions::DeployObjectService.call(integration:)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def action_path
end

def call
throttle!(:hubspot)

response = http_client.get(headers:)

result.account_information = OpenStruct.new(response)
Expand Down
4 changes: 2 additions & 2 deletions app/services/integrations/aggregator/base_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ def throttle!(*providers)
end

def throttle_key
# Hubspot and Xero calls are throttled globally, others are throttled per api key or token
# Hubspot and Xero calls are throttled globally, others are throttled per api key or client id
case provider
when 'netsuite'
Digest::SHA2.hexdigest(integration.token_id)
Digest::SHA2.hexdigest(integration.client_id)
when 'anrok'
Digest::SHA2.hexdigest(integration.api_key)
else
Expand Down
2 changes: 2 additions & 0 deletions app/services/integrations/aggregator/custom_object_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def action_path
end

def call
throttle!(:hubspot)

response = http_client.get(headers:, body:)

result.custom_object = OpenStruct.new(response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def call

Integrations::Hubspot::Invoices::DeployObjectService.call(integration:)

throttle!(:hubspot)

http_client.put_with_response(payload.customer_association_body, headers)

result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def call

Integrations::Hubspot::Invoices::DeployPropertiesService.call(integration:)

throttle!(:hubspot)

response = http_client.post_with_response(payload.create_body, headers)
body = JSON.parse(response.body)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def call

Integrations::Hubspot::Invoices::DeployPropertiesService.call(integration:)

throttle!(:hubspot)

response = http_client.put_with_response(payload.update_body, headers)
body = JSON.parse(response.body)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def call

Integrations::Hubspot::Subscriptions::DeployObjectService.call(integration:)

throttle!(:hubspot)

http_client.put_with_response(payload.customer_association_body, headers)

result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def call
return result unless integration
return result unless integration.sync_subscriptions

throttle!(:hubspot)

Integrations::Hubspot::Subscriptions::DeployPropertiesService.call(integration:)

response = http_client.post_with_response(payload.create_body, headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def call
return result unless integration.sync_subscriptions
return result unless payload.integration_subscription

throttle!(:hubspot)

Integrations::Hubspot::Subscriptions::DeployPropertiesService.call(integration:)

response = http_client.put_with_response(payload.update_body, headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def action_path
def call
return result unless integration.type == 'Integrations::HubspotIntegration'
return result if integration.companies_properties_version == VERSION

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
integration.settings = integration.reload.settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def action_path
def call
return result unless integration.type == 'Integrations::HubspotIntegration'
return result if integration.contacts_properties_version == VERSION

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
integration.settings = integration.reload.settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def call
return result
end

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
save_object_type_id(response['objectTypeId'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def action_path
def call
return result unless integration.type == 'Integrations::HubspotIntegration'
return result if integration.invoices_properties_version == VERSION

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
integration.settings = integration.reload.settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def call
return result
end

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
save_object_type_id(response['objectTypeId'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def action_path
def call
return unless integration.type == 'Integrations::HubspotIntegration'
return result if integration.subscriptions_properties_version == VERSION

throttle!(:hubspot)

response = http_client.post_with_response(payload, headers)
ActiveRecord::Base.transaction do
integration.settings = integration.reload.settings
Expand Down
6 changes: 4 additions & 2 deletions config/initializers/throttling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
},
anrok: { # Rate limit: 10 requests per second
secondly: {
limit: 10,
# this mutation can bypass the limit of 10, so lets set it to 9
# app/graphql/mutations/integrations/anrok/fetch_draft_invoice_taxes.rb
limit: 9,
period: 1
}
}
Expand All @@ -50,5 +52,5 @@
# Examples of how to use the throttling gem
# Throttling.for(:hubspot).check(:client, 'hubspot')
# Throttling.for(:xero).check(:client, 'xero')
# Throttling.for(:netsuite).check(:client, integration.token_id)
# Throttling.for(:netsuite).check(:client, integration.client_id)
# Throttling.for(:anrok).check(:client, integration.api_key)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require 'rails_helper'

RSpec.describe Integrations::Aggregator::AccountInformationService do
subject(:account_information_service) { described_class.new(integration:) }
subject(:service) { described_class.new(integration:) }

let(:integration) { create(:hubspot_integration) }

Expand All @@ -30,7 +30,7 @@
end

it 'successfully fetches account information' do
result = account_information_service.call
result = service.call
account_information = result.account_information

aggregate_failures do
Expand All @@ -39,5 +39,7 @@
expect(account_information.id).to eq('1234567890')
end
end

it_behaves_like 'throttles!', :hubspot
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
customer
).on_queue(:webhook)
end

it_behaves_like 'throttles!', :hubspot
end

context 'when response is a hash' do
Expand Down Expand Up @@ -139,6 +141,8 @@
customer
).on_queue(:webhook)
end

it_behaves_like 'throttles!', :hubspot
end

context 'when contact is not created' do
Expand All @@ -159,6 +163,8 @@
it 'does not create integration resource object' do
expect { service_call }.not_to change(IntegrationResource, :count)
end

it_behaves_like 'throttles!', :hubspot
end
end
end
Expand Down Expand Up @@ -221,6 +227,8 @@
}
)
end

it_behaves_like 'throttles!', :hubspot
end

context 'when it is a server payload error' do
Expand Down Expand Up @@ -256,6 +264,8 @@
}
)
end

it_behaves_like 'throttles!', :hubspot
end

context 'when it is a client error' do
Expand Down Expand Up @@ -291,6 +301,8 @@
}
)
end

it_behaves_like 'throttles!', :hubspot
end
end
end
Expand Down
Loading

0 comments on commit 8ba7da9

Please sign in to comment.