Created
September 4, 2018 06:49
-
-
Save darrenjs/2505df8ad6ab2782b2f0e6f4c811a65c to your computer and use it in GitHub Desktop.
example of using redis with python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import redis | |
import redis.sentinel | |
import logging | |
# TODO: would be useful to also | |
def discover_redis_master(sentinel_addrs, redis_name): | |
"""Use listed sentinels to find the redis master | |
""" | |
sentinel = redis.sentinel.Sentinel(sentinel_addrs, socket_timeout=0.1) | |
master_addr = sentinel.discover_master(redis_name) | |
redis_client = sentinel.master_for(redis_name, socket_timeout=0.1) | |
if redis_client.ping(): | |
return redis_client, master_addr | |
else: | |
raise Exception("failed to ping redis master") | |
class SignupState: | |
CHKSUM_FAILED = "chksum mismatch" | |
NO_SUCH_REQUEST = "no such request" | |
ALREADY_VERIFIED = "already verified" | |
BACKEND_ERROR = "backend error" | |
SUCCESS = "success" | |
NOT_PENDING = "not pending" | |
# TODO: add enum here (as class) for signup status | |
# Attempt to update a redis signup record, to indicate that the user has clicked | |
# in order to verify the signup. | |
def update_signup_record_to_verified(r, user_key, user_chksum): | |
stored_obj = r.hgetall(user_key) | |
if not stored_obj: | |
logging.warning("{}: signup request not found".format(user_key)) | |
return SignupState.NO_SUCH_REQUEST | |
status = stored_obj[b'status'].decode('utf-8') | |
chksum = stored_obj[b'chksum'].decode('utf-8') | |
# Check the user provided checksum matches the signup checksum. This is | |
# needed so that an invalid (spoofing?) attempt to validate a signup account | |
# can be detected. So for signup to be successful, the user needs to new the | |
# signup key (which is guessable), the encoding key, and the original record | |
# checksum. | |
if user_chksum != chksum: | |
logging.warn("verify failed; chksum mismatch") | |
return SignupState.CHKSUM_FAILED | |
# TODO: return error codes in here, instead of exceptions | |
if (status == 'pending'): | |
rv = r.hset(user_key, 'status', 'verified') | |
if rv == 0: | |
logging.info("{}: signup status set to verified".format(user_key)) | |
# TODO: here, set the state to 'verified' | |
return SignupState.SUCCESS | |
else: | |
logging.warn("hset expectedly returned value {}".format(rv)) | |
return SignupState.BACKEND_ERROR | |
else: | |
logging.warn( | |
"{}: sign-up request is not in pending state, so cannot progress to verified; current state is '{}'".format(user_key, status)) | |
return SignupState.NOT_PENDING | |
def get_global_id_block(r, key, blocksize=100): | |
"""Reserve a block of global id numbers. | |
The usable inclusive range is returned in the tuple as (lower,upper). | |
""" | |
assert isinstance(key, str) | |
assert isinstance(blocksize, int) | |
upper = r.incrby(key, max(blocksize, 1)) | |
#lower = max(1, upper-blocksize) # min valid id is 1 | |
return (upper-blocksize, upper-1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment