Skip to content

Commit

Permalink
Adding copy methods to Cluster and Client.
Browse files Browse the repository at this point in the history
This is so that a Connection pool won't re-use the same
client instance to make connections.
  • Loading branch information
dhermes committed Sep 5, 2015
1 parent 5de060c commit db2711b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 1 deletion.
19 changes: 18 additions & 1 deletion gcloud_bigtable/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"""


import copy
import os
import six
import socket
Expand Down Expand Up @@ -329,6 +330,22 @@ def from_service_account_p12(cls, client_email, private_key_path,
return cls(credentials=credentials, project_id=project_id,
read_only=read_only, admin=admin)

def copy(self):
"""Make a copy of this client.
Copies the local data stored as simple types but does not copy the
current state of any open connections with the Cloud Bigtable API.
:rtype: :class:`.Client`
:returns: A copy of the current client.
"""
new_client = copy.deepcopy(self)
new_client._data_stub = None
new_client._cluster_stub = None
new_client._operations_stub = None
new_client._table_stub = None
return new_client

@property
def credentials(self):
"""Getter for client's credentials.
Expand Down Expand Up @@ -364,7 +381,7 @@ def project_name(self):
:returns: The project name to be used with the Cloud Bigtable Admin
API RPC service.
"""
return 'projects/' + self._project_id
return 'projects/' + self.project_id

@property
def data_stub(self):
Expand Down
15 changes: 15 additions & 0 deletions gcloud_bigtable/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ def from_pb(cls, cluster_pb, client):
result._update_from_pb(cluster_pb)
return result

def copy(self):
"""Make a copy of this cluster.
Copies the local data stored as simple types but does not copy the
current state of any operations with the Cloud Bigtable API. Also
copies the client attached to this instance.
:rtype: :class:`.Cluster`
:returns: A copy of the current cluster.
"""
new_client = self.client.copy()
return Cluster(self.zone, self.cluster_id, new_client,
display_name=self.display_name,
serve_nodes=self.serve_nodes)

@property
def client(self):
"""Getter for cluster's client.
Expand Down
36 changes: 36 additions & 0 deletions gcloud_bigtable/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,42 @@ def test_from_service_account_p12(self):
# Load private key (via _get_contents) from the key path.
mock_get_contents.check_called(self, [(private_key_path,)])

def test_copy(self):
from gcloud_bigtable._testing import _MockWithAttachedMethods

class Credentials(object):

def __init__(self, value):
self.value = value

def __eq__(self, other):
return self.value == other.value

scoped_creds = Credentials('value')
credentials = _MockWithAttachedMethods(scoped_creds)
client = self._makeOne(credentials, project_id=PROJECT_ID)
# Put some fake stubs in place so that we can verify they
# don't get copied.
client._data_stub = object()
client._cluster_stub = object()
client._operations_stub = object()
client._table_stub = object()

new_client = client.copy()
self.assertEqual(new_client._admin, client._admin)
self.assertEqual(new_client._credentials, client._credentials)
# Make sure credentials (a non-simple type) gets copied
# to a new instance.
self.assertFalse(new_client._credentials is client._credentials)
self.assertEqual(new_client._project_id, client._project_id)
self.assertEqual(new_client.user_agent, client.user_agent)
self.assertEqual(new_client.timeout_seconds, client.timeout_seconds)
# Make sure stubs are not preserved.
self.assertEqual(new_client._data_stub, None)
self.assertEqual(new_client._cluster_stub, None)
self.assertEqual(new_client._operations_stub, None)
self.assertEqual(new_client._table_stub, None)

def test_credentials_getter(self):
from gcloud_bigtable._testing import _MockWithAttachedMethods

Expand Down
23 changes: 23 additions & 0 deletions gcloud_bigtable/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ def test_constructor_non_default(self):
self.assertEqual(cluster.serve_nodes, serve_nodes)
self.assertTrue(cluster._client is client)

def test_copy(self):
client = _Client(PROJECT_ID)
display_name = 'DISPLAY_NAME'
serve_nodes = 8
cluster = self._makeOne(ZONE, CLUSTER_ID, client,
display_name=display_name,
serve_nodes=serve_nodes)
new_cluster = cluster.copy()

# Make sure the client got copied to a new instance.
self.assertFalse(new_cluster._client is client)
self.assertEqual(new_cluster._client.__dict__,
client.__dict__)
# Just replace the client on the new_cluster so we can
# check cluster equality.
new_cluster._client = client
self.assertFalse(cluster is new_cluster)
self.assertEqual(cluster, new_cluster)

def test_client_getter(self):
client = object()
cluster = self._makeOne(ZONE, CLUSTER_ID, client)
Expand Down Expand Up @@ -602,3 +621,7 @@ class _Client(object):
def __init__(self, project_id):
self.project_id = project_id
self.project_name = 'projects/' + project_id

def copy(self):
import copy as copy_module
return copy_module.deepcopy(self)

0 comments on commit db2711b

Please sign in to comment.