Skip to content

Commit

Permalink
Merge branch 'release/3.0.2'
Browse files Browse the repository at this point in the history
* release/3.0.2:
  3.0.2
  Removed Faraday dependency, fixes issue with infinite retries, upgrade to use 2.7.4.
  • Loading branch information
jclusso committed Jul 27, 2021
2 parents f65a1cb + b02208f commit 8b696f4
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.5
2.7.4
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ sudo: false
language: ruby
cache: bundler
rvm:
- 2.6.3
before_install: gem install bundler -v 1.17.3
- 2.7.4
before_install: gem install bundler -v 2.2.15
19 changes: 2 additions & 17 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
PATH
remote: .
specs:
emailable (3.0.0)
faraday
faraday_middleware
net-http-persistent
emailable (3.0.2)

GEM
remote: https://rubygems.org/
Expand All @@ -22,14 +19,6 @@ GEM
builder (3.2.3)
coderay (1.1.2)
concurrent-ruby (1.1.7)
connection_pool (2.2.3)
faraday (1.3.0)
faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-net_http (1.0.1)
faraday_middleware (1.0.0)
faraday (~> 1.0)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
method_source (0.9.2)
Expand All @@ -39,15 +28,11 @@ GEM
builder
minitest (>= 5.0)
ruby-progressbar
multipart-post (2.1.1)
net-http-persistent (4.0.1)
connection_pool (~> 2.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rake (13.0.1)
ruby-progressbar (1.10.1)
ruby2_keywords (0.0.4)
thread_safe (0.3.6)
tzinfo (1.2.8)
thread_safe (~> 0.1)
Expand All @@ -67,4 +52,4 @@ DEPENDENCIES
rake (~> 13.0)

BUNDLED WITH
1.17.3
2.1.4
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019 Emailable. https://emailable.com
Copyright (c) 2021 Emailable. https://emailable.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
3 changes: 0 additions & 3 deletions emailable.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ Gem::Specification.new do |s|
end
s.require_paths = ['lib']

s.add_dependency 'faraday'
s.add_dependency 'faraday_middleware'
s.add_dependency 'net-http-persistent'
s.add_development_dependency 'bundler'
s.add_development_dependency 'rake', '~> 13.0'
s.add_development_dependency 'pry'
Expand Down
9 changes: 6 additions & 3 deletions lib/emailable.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require 'faraday'
require 'faraday_middleware'
require 'emailable/version'
require 'emailable/client'
require 'emailable/response'
require 'emailable/batch'
require 'emailable/resources/api_resource'
require 'emailable/resources/account'
Expand All @@ -14,9 +13,13 @@

module Emailable
@max_network_retries = 1
@open_timeout = 30
@read_timeout = 60
@write_timeout = 30

class << self
attr_accessor :api_key, :max_network_retries
attr_accessor :api_key, :max_network_retries, :open_timeout, :read_timeout,
:write_timeout
end

module_function
Expand Down
4 changes: 4 additions & 0 deletions lib/emailable/batch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ class Batch

def initialize(id_or_emails, callback: nil)
if id_or_emails.is_a?(Array)
@id = nil
@emails = id_or_emails
@callback = callback
elsif id_or_emails.is_a?(String)
@id = id_or_emails
@emails = nil
@callback = nil
else
raise ArgumentError, 'expected an array of emails or batch id'
end

@client = Emailable::Client.new
@status = nil
end

def verify
Expand Down
85 changes: 62 additions & 23 deletions lib/emailable/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,30 @@ module Emailable
class Client

def initialize
@client = Faraday.new('https://api.emailable.com/v1') do |f|
f.request :url_encoded
f.response :json, content_type: /\bjson$/
f.adapter :net_http_persistent
end
@base_url = 'https://api.emailable.com/v1'
@connection = create_connection(URI(@base_url))
end

def request(method, endpoint, opts = {})
def request(method, endpoint, params = {})
begin
tries ||= 0
tries ||= 3

@client.params[:api_key] = Emailable.api_key
uri = URI("#{@base_url}/#{endpoint}")
params[:api_key] = Emailable.api_key

response =
http_response =
if method == :get
@client.get(endpoint, opts)
uri.query = URI.encode_www_form(params)
@connection.get(uri)
elsif method == :post
@client.post(endpoint, opts)
request = Net::HTTP::Post.new(uri, 'Content-Type': 'application/json')
request.body = params.to_json
@connection.request(request)
end

response = Response.new(http_response)
rescue => e
retry if self.class.should_retry?(e, tries)
retry if (tries -= 1) > 0 && self.class.should_retry?(e, tries)

raise e
end
Expand All @@ -48,23 +51,59 @@ def request(method, endpoint, opts = {})
raise error_map[status.to_s].new(error_attributes)
end

private

def create_connection(uri)
connection = Net::HTTP.new(uri.host, uri.port)

# Time in seconds within which Net::HTTP will try to reuse an already
# open connection when issuing a new operation. Outside this window, Ruby
# will transparently close and re-open the connection without trying to
# reuse it.
#
# Ruby's default of 2 seconds is almost certainly too short. Here I've
# reused Go's default for `DefaultTransport`.
connection.keep_alive_timeout = 30

connection.open_timeout = Emailable.open_timeout
connection.read_timeout = Emailable.read_timeout
if connection.respond_to?(:write_timeout=)
connection.write_timeout = Emailable.write_timeout
end
connection.use_ssl = uri.scheme == "https"

connection
end

def self.should_retry?(error, num_retries)
return false if num_retries >= Emailable.max_network_retries

# Retry on timeout-related problems (either on open or read).
return true if error.is_a?(Faraday::TimeoutError)
case error
when Net::OpenTimeout, Net::ReadTimeout
# Retry on timeout-related problems (either on open or read).
true
when EOFError, Errno::ECONNREFUSED, Errno::ECONNRESET,
Errno::EHOSTUNREACH, Errno::ETIMEDOUT, SocketError
# Destination refused the connection, the connection was reset, or a
# variety of other connection failures. This could occur from a single
# saturated server, so retry in case it's intermittent.
true
when Net::HTTPError
# 409 Conflict
return true if error.http_status == 409

# Destination refused the connection, the connection was reset, or a
# variety of other connection failures. This could occur from a single
# saturated server, so retry in case it's intermittent.
return true if error.is_a?(Faraday::ConnectionFailed)
# 429 Too Many Requests
return true if error.http_status == 429

if error.is_a?(Faraday::ClientError) && error.response
# 409 conflict
return true if error.response[:status] == 409
end
# 500 Internal Server Error
return true if error.http_status == 500

false
# 503 Service Unavailable
error.http_status == 503
else
false
end
end

end
end
2 changes: 1 addition & 1 deletion lib/emailable/email_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def validate_each(record, attribute, value)

api_options = { timeout: timeout, smtp: smtp }
api_options[:accept_all] = true unless accept_all
ev = Emailable.verify(value, api_options)
ev = Emailable.verify(value, **api_options)

result_accessor = "#{attribute}_verification_result"
if record.respond_to?(result_accessor)
Expand Down
12 changes: 12 additions & 0 deletions lib/emailable/response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Emailable
class Response

attr_accessor :status, :body

def initialize(response)
@status = response.code.to_i
@body = JSON.parse(response.body)
end

end
end
2 changes: 1 addition & 1 deletion lib/emailable/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Emailable
VERSION = '3.0.1'
VERSION = '3.0.2'
end

0 comments on commit 8b696f4

Please sign in to comment.