Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add all versions of coach... #80

Merged
merged 4 commits into from
Mar 29, 2017
Merged
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
79 changes: 72 additions & 7 deletions poloniex/coach.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,99 @@

import logging
from time import time, sleep
from threading import Semaphore
from threading import Semaphore, Timer
from collections import deque

logger = logging.getLogger(__name__)


class Coach(object):
"""
Coaches the api wrapper, makes sure it doesn't get all hyped up on Mt.Dew
Poloniex default call limit is 6 calls per 1 sec.
"""

def __init__(self, timeFrame=1.0, callLimit=6):
"""
timeFrame = float time in secs [default = 1.0]
callLimit = int max amount of calls per 'timeFrame' [default = 6]
"""
self.timeFrame = timeFrame
self.semaphore = Semaphore(callLimit)
#self.semaphore = Semaphore(callLimit)
self.timeBook = deque(maxlen=callLimit, iterable=[time()])

def wait(self):
""" Makes sure our api calls don't go past the api call limit """
self.semaphore.acquire() # blocking call
self.timeBook.append(time())
# newest time - the oldest time = time elapsed between calls
elapsed = self.timeBook[-1] - self.timeBook[0]
waitTime = elapsed - self.timeFrame
if waitTime < 0:
sleep(waitTime + self.timeFrame)
# if elapsed is less than timeframe
if elapsed < self.timeFrame:
# waittime = timeframe - elapsed
sleep(self.timeFrame - elapsed)
# put now in timebook
self.timeBook.append(time())
# release semaphore
self.semaphore.release()
else:
# put now in timebook
self.timeBook.append(time())
# release semaphore
self.semaphore.release()


class Coach2(object):
"""
Coaches the api wrapper, makes sure it doesn't get all hyped up on Mt.Dew
Poloniex default call limit is 6 calls per 1 sec.
"""
def __init__(self, timeFrame=1.0, callLimit=6):
"""
timeFrame = float time in secs [default = 1.0]
callLimit = int max amount of calls per 'timeFrame' [default = 6]
"""
self.timeFrame = timeFrame
self.timeBook = deque(list(), callLimit)

@property
def timeOverTimeframe(self):
elapsed = self.timeBook[-1] - self.timeBook[0]
logging.debug("Timebook=%s, Elapsed over time frame = %f",
self.timeBook, elapsed)
return elapsed

def maybeSleep(self):
if len(self.timeBook) == 1:
logging.debug("First API call. No need to sleep.")
return

requiredElapsed = self.timeOverTimeframe - self.timeFrame
if requiredElapsed < 0:
requiredElapsed *= -1
logging.debug("Need to sleep %f seconds", requiredElapsed)
sleep(requiredElapsed)

def wait(self):
""" Makes sure our api calls don't go past the api call limit """
self.timeBook.append(time())
self.maybeSleep()


class Coach3(object):
"""
Coaches the api wrapper, makes sure it doesn't get all hyped up on Mt.Dew
Poloniex default call limit is 6 calls per 1 sec.
"""
def __init__(self, timeFrame=1.0, callLimit=6):
"""
timeFrame = float time in secs [default = 1.0]
callLimit = int max amount of calls per 'timeFrame' [default = 6]
"""
self.timeFrame = timeFrame
self.semaphore = Semaphore(callLimit)

def wait(self):
""" Makes sure our api calls don't go past the api call limit """
self.semaphore.acquire() # blocking call
timer = Timer(self.timeFrame, self.semaphore.release) # delayed release
timer.setDaemon(True) # allows the timer to be canceled on exit
timer.start()