def _check_params(cls, interval_obj, interval_sec, poll_sec, interval_cb, time_func): if not hasattr(interval_obj, 'update'): raise TOSDB_Error( "'interval obj' has no 'update' function/attribute") try: test = interval_obj([0], 30, 1) except Exception as e: raise TOSDB_Error("could not instantiate 'interval_obj': %s" % str(e)) if interval_sec < cls.MIN_INTERVAL_SEC: raise TOSDB_Error("interval_sec(%i) < MIN_INTERVAL_SEC(%i)" \ % (interval_sec, cls.MIN_INTERVAL_SEC) ) if interval_sec > cls.MAX_INTERVAL_SEC: raise TOSDB_Error("interval_sec(%i) > MAX_INTERVAL_SEC(%i)" \ % (interval_sec, cls.MAX_INTERVAL_SEC) ) if interval_sec < (2 * poll_sec): raise TOSDB_Error("interval_sec(%i) < 2 * poll_sec(%i)" \ % (interval_sec, poll_sec)) if poll_sec < cls.MIN_POLL_SEC: raise TOSDB_Error("poll_sec(%i) < MIN_POLL_SEC(%i)" \ % (poll_sec, cls.MIN_POLL_SEC) ) if interval_cb is not None: if not callable(interval_cb): raise TOSDB_Error("'interval_cb' not callable") if len(_signature(interval_cb).parameters) != 3: raise TOSDB_Error( "'interval_cb' signature requires 3 paramaters") if not callable(time_func): raise TOSDB_Error("'time_func' not callable")
def _check_block(self, block): for a in TOSDB_FixedTimeIntervals.BLOCK_ATTR: if not hasattr(block, a): raise TOSDB_Error("'block' does not have attr '%s'" % a) if not block.is_thread_safe(): raise TOSDB_Error("'block' is not thread safe") if not block.is_using_datetime(): raise TOSDB_Error("'block' is not using datetime") if block.get_block_size() < self._min_block_size: print("WARN: block is too small, resize to %i" % self._min_block_size) block.set_block_size(self._min_block_size)
def _intervals_since_epoch(self, second, minute, hour, day, month, year): is_dst = self._tfunc().tm_isdst sfe = _mktime( _struct_time( [year, month, day, hour, minute, second, 0, 0, is_dst])) if sfe % self._isec: raise TOSDB_Error("invalid interval constructed") return int(sfe // self._isec)
def __init__(self, intervals_since_epoch, interval_seconds, time_func=time.localtime): self._intervals_since_epoch = intervals_since_epoch self._isec = interval_seconds if not callable(time_func): raise TOSDB_Error("time_func not callable") self._tfunc = time_func
def _init_buffer(self, topic, item): for _ in range(int(self._isec / self._psec)): dat = self._ssfunc(item, topic, date_time=True, throw_if_data_lost=False) if dat: return dat _sleep(self._psec) raise TOSDB_Error("failed to get any data for first interval: %s, %s" % (topic, item))
def stream_snapshot_between_datetimes(self, item, topic, end_datetime=tuple(), beg_datetime=tuple()): """ Return multiple interval objects between datetime tuples stream_snapshot(self, item, topic, end_datetime=tuple(), beg_datetime=tuple()) item :: str :: any item string in the block topic :: str :: any topic string in the block end_datetime :: int :: datetime tuple of least recent interval to get (second, minute, hour, day, month, year) beg_datetime :: int :: datetime tuple of most recent interval to get (second, minute, hour, day, month, year) throws TOSDB_Error if interval objects don't exist between the datetime tuples """ with self._buffers_lock: b = self._get_buffer_deque(topic, item) if beg_datetime: i_beg = self._intervals_since_epoch(*beg_datetime) off_beg = b[0].intervals_since_epoch - i_beg if off_beg < 0: raise TOSDB_Error( "'beg' OHLC does not exist at this datetime") else: off_beg = 0 if end_datetime: i_end = self._intervals_since_epoch(*end_datetime) off_end = b[0].intervals_since_epoch - i_end if off_end < 0: raise TOSDB_Error( "'end' OHLC does not exist at this datetime") off_end += 1 # make range incluseive else: off_end = -1 try: return list(b)[off_beg:off_end] except IndexError: raise TOSDB_Error("OHLCs do not exist between these datetimes")
def get_by_datetime(self, item, topic, datetime): """ Return a single interval object by its datetime tuple get(self, item, topic, datetime) item :: str :: any item string in the block topic :: str :: any topic string in the block datetime :: int :: datetime tuple of the interval object (second, minute, hour, day, month, year) throws TOSDB_Error if interval object doesn't exist at that datetime """ with self._buffers_lock: b = self._get_buffer_deque(topic, item) i = self._intervals_since_epoch(*datetime) off = b[0].intervals_since_epoch - i if off < 0: raise TOSDB_Error("OHLC does not exist at this datetime") try: return b[off] except IndexError: raise TOSDB_Error("OHLC does not exist at this datetime")
def _tune_background_worker(self, count, ni, itbeg): tnow = _perf_counter() adjbeg = itbeg + (count // ni) * self._isec terr = tnow - adjbeg #print("DEBUG RUNNING ERROR SECONDS: ", str(terr)) if terr < 0: #print("DEBUG RUNNING ERROR SLEEP: ", str(terr)) if self._wait_adj_down_exp > 0: self._wait_adj_down_exp -= 1 _sleep(abs(terr)) elif abs(terr) > (self._isec * self.WAIT_ADJ_THRESHOLD_FATAL): TOSDB_Error("_background worker entered fatal wait/sync states: %f, %i" \ % (terr, self._wait_adj_down_exp)) elif terr > (self._isec * self.WAIT_ADJ_THRESHOLD): self._wait_adj_down_exp += 1
def _inj_set_block_size(instance, sz): if sz < self._min_block_size: raise TOSDB_Error( "setting a block size < %i has been restricted " "by TOSDB_FixedTimeIntervals" % self._min_block_size) block._old_set_block_size(sz)
def add_topics(*topics): for t in topics: if type_bits(t) & tosdb.STRING_BIT: raise TOSDB_Error("topic %s returns string data" % t) with self._buffers_lock: self._block.add_topics(*topics)