Skip to content
This repository has been archived by the owner on Sep 3, 2022. It is now read-only.

Use http Keep-Alive, else BigQuery queries are ~seconds slower than necessary #195

Merged
merged 2 commits into from
Feb 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions datalab/utils/_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ class Http(object):
"""A helper class for making HTTP requests.
"""

# Reuse one Http object across requests to take advantage of Keep-Alive, e.g.
# for BigQuery queries that requires at least ~5 sequential http requests.
#
# TODO(nikhilko):
# SSL cert validation seemingly fails, and workarounds are not amenable
# to implementing in library code. So configure the Http object to skip
# doing so, in the interim.
http = httplib2.Http()
http.disable_ssl_certificate_validation = True

def __init__(self):
pass

Expand Down Expand Up @@ -109,15 +119,8 @@ def request(url, args=None, data=None, headers=None, method=None,
if method is None:
method = 'GET'

# Create an Http object to issue requests. Associate the credentials
# with it if specified to perform authorization.
#
# TODO(nikhilko):
# SSL cert validation seemingly fails, and workarounds are not amenable
# to implementing in library code. So configure the Http object to skip
# doing so, in the interim.
http = httplib2.Http()
http.disable_ssl_certificate_validation = True
# Authorize with credentials if given.
http = Http.http
if credentials is not None:
http = credentials.authorize(http)
if stats is not None:
Expand Down
16 changes: 8 additions & 8 deletions tests/_util/http_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class TestCases(unittest.TestCase):

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_get_request_is_invoked(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Expand All @@ -32,23 +32,23 @@ def test_get_request_is_invoked(self, mock_request, mock_response):
self.assertEqual(mock_request.call_args[1]['method'], 'GET')

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_post_request_is_invoked(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Http.request('http://www.example.org', data={})
self.assertEqual(mock_request.call_args[1]['method'], 'POST')

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_explicit_post_request_is_invoked(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Http.request('http://www.example.org', method='POST')
self.assertEqual(mock_request.call_args[1]['method'], 'POST')

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_query_string_format(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Expand All @@ -59,7 +59,7 @@ def test_query_string_format(self, mock_request, mock_response):
self.assertTrue('b=a+b+c' in parts[1:])

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_formats_json_request(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Expand All @@ -71,7 +71,7 @@ def test_formats_json_request(self, mock_request, mock_response):
'application/json')

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_supports_custom_content(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{}')

Expand All @@ -83,15 +83,15 @@ def test_supports_custom_content(self, mock_request, mock_response):
self.assertEqual(mock_request.call_args[1]['headers']['Content-Type'], 'text/plain')

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_parses_json_response(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, '{"abc":123}')

data = Http.request('http://www.example.org')
self.assertEqual(data['abc'], 123)

@mock.patch('httplib2.Response')
@mock.patch('httplib2.Http.request')
@mock.patch('datalab.utils._http.Http.http.request')
def test_raises_http_error(self, mock_request, mock_response):
TestCases._setup_mocks(mock_request, mock_response, 'Not Found', 404)

Expand Down