Skip to content

Commit

Permalink
Make info-provider API backwards-compatible with respect to key_patte…
Browse files Browse the repository at this point in the history
…rns parameter (#18)

* Make info-provider API backwards-compatible with respect to key_patterns parameter

* Advance version number to 0.12.0
  • Loading branch information
yaeltzirulnikov committed May 26, 2019
1 parent 94eb505 commit ce7c808
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

setup(
name='redis-info-provider',
version='0.11.0',
version='0.12.0',
python_requires='>=2.7',
package_dir={'': 'src'},
packages=find_packages('src'),
Expand Down
36 changes: 36 additions & 0 deletions src/redis_info_provider/info_servicer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import print_function
import time
import functools
import warnings
from .shard_pub import ShardPublisher
from .redis_shard import InfoType, RedisShard
import logging
Expand All @@ -9,6 +11,37 @@
logger = logging.getLogger(__name__)


def deprecated_alias(**aliases):
"""
Decorator that renames deprecated parameter names of a function to their new names and then calls the function with
the new parameter names.
:param aliases: Dict[str,str] - mapping of deprecated parameter names to their new names.
"""
def deco(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
rename_kwargs(f.__name__, kwargs, aliases)
return f(*args, **kwargs)
return wrapper
return deco


def rename_kwargs(func_name, kwargs, aliases):
"""
Rename deprecated parameters of kwargs to their new name as as it appears in aliases dict.
:param func_name: str (name of function that the decorator is applied to)
:param kwargs: Dict[str, str] of arguments the given function was called with
:param aliases: Dict[str, str] that maps deprecated parameters to new parameter names
:raises TypeError if both an argument and its deprecated alias were received
"""
for alias, new in aliases.items():
if alias in kwargs:
if new in kwargs:
raise TypeError('{} received both {} and {}'.format(func_name, alias, new))
warnings.warn('{} is deprecated; use {}'.format(alias, new), DeprecationWarning)
kwargs[new] = kwargs.pop(alias)


class InfoProviderServicer(object):
"""Implements the InfoProvider RPC interface."""

Expand Down Expand Up @@ -58,12 +91,15 @@ def _get_shard_with_info(shard_id):

return shard

@deprecated_alias(key_patterns='keys')
def GetInfos(self, shard_ids=(), keys=(), allow_partial=False, max_age=0.0):
# type: (Sequence[str], Sequence[str], bool, float) -> List[InfoType]

"""
Returns a list of info dicts according to the shard-ids and keys
specified in the query selector.
Note: if deprecated parameter "key_patterns" is passed, we use it as "keys" for backwards compatibility.
However, filtering by glob-like patterns is no longer supported.
:param shard_ids: List of shard identifiers to query. If empty, all live
shards will be returned.
:param keys: List of exact-match keys to filter for. If not empty, only
Expand Down
12 changes: 12 additions & 0 deletions tests/test_infoServicer.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ def test_allow_partial_unknown_shard(self):
msg='Expected info_age for shard-2 to be very large')
six.assertRegex(self, response_dict['shard-2']['meta']['error'], 'shard .* not found')

def test_backwards_compatibility(self):
ShardPublisher.add_shard(self.make_shard('shard-1', info={'dummy1': 'dummy1', 'dummy2': 'dummy2'}))
ShardPublisher.add_shard(self.make_shard('shard-2', info={'dummy1': 'dummy1'}))

response = self.servicer.GetInfos(shard_ids=['shard-1', 'shard-2'], key_patterns=['dummy1'])
response_dict = {info['meta']['shard_identifier']: info for info in response}
self.assertIn('dummy1', response_dict['shard-1'])
self.assertIn('dummy1', response_dict['shard-2'])

with self.assertRaises(TypeError):
self.servicer.GetInfos(shard_ids=['shard-1'], key_patterns=['dummy1'], keys=['dummy1'])

@patch('redis_info_provider.info_servicer.time.time')
def test_max_age(self, time_mock):
now = 1545240843.4637716
Expand Down

0 comments on commit ce7c808

Please sign in to comment.