HyperDevil
HyperDevil

Reputation: 2649

Python, function quit if it has been run the last 5 minutes

I have a python script that gets data from a USB weather station, now it puts the data into MySQL whenever the data is received from the station.

I have a MySQL class with an insert function, what i want i that the function checks if it has been run the last 5 minutes if it has, quit.

Could not find any code on the internet that does this.

Maybe I need to have a sub-process, but I am not familiar with that at all.

Does anyone have an example that I can use?

Upvotes: 1

Views: 877

Answers (5)

moooeeeep
moooeeeep

Reputation: 32542

Probably the most straight-forward approach (you can put this into a decorator if you like, but that's just cosmetics I think):

import time
import datetime

class MySQLWrapper:
  def __init__(self, min_period_seconds):
    self.min_period = datetime.timedelta(seconds=min_period_seconds)
    self.last_calltime = datetime.datetime.now() - self.min_period
  def insert(self, item):
    now = datetime.datetime.now()
    if now-self.last_calltime < self.min_period:
      print "not insert"
    else:
     self.last_calltime = now
     print "insert", item

m = MySQLWrapper(5)
m.insert(1) # insert 1
m.insert(2) # not insert
time.sleep(5)
m.insert(3) # insert 3

As a side-note: Have you noticed RRDTool during your web-search for related stuff? It does apparantly what you want to achieve, i.e.

  • a database to store the most recent values of arbitrary resolution/update frequency.
  • extrapolation/interpolation of values if updates are too frequent or missing.
  • generates graphs from the data.

An approach could be to store all data you can get into your MySQL database and forward a subset to such RRDTool database to generate a nice time series visualization of it. Depending on what you might need.

Upvotes: 1

user903589
user903589

Reputation:

import time

def timeout(f, k, n):
    last_time = [time.time()]
    count = [0]
    def inner(*args, **kwargs):
        distance = time.time() - last_time[0]
        if distance > k:
            last_time[0] = time.time()
            count[0] = 0
            return f(*args, **kwargs)
        elif distance < k and (count[0]+1) == n:
            return False
        else:
            count[0] += 1
            return f(*args, **kwargs)
    return inner

timed = timeout(lambda x, y : x + y, 300, 1)

print timed(2, 4)

First argument is the function you want run, second is the time interval, and the third is the number of times it's allowed to run in that time interval.

Upvotes: 1

zengr
zengr

Reputation: 38899

Use this timeout decorator.

import signal

class TimeoutError(Exception):
    def __init__(self, value = "Timed Out"):
        self.value = value
    def __str__(self):
        return repr(self.value)

def timeout(seconds_before_timeout):
    def decorate(f):
        def handler(signum, frame):
            raise TimeoutError()
        def new_f(*args, **kwargs):
            old = signal.signal(signal.SIGALRM, handler)
            signal.alarm(seconds_before_timeout)
            try:
                result = f(*args, **kwargs)
            finally:
                signal.signal(signal.SIGALRM, old)
            signal.alarm(0)
            return result
        new_f.func_name = f.func_name
        return new_f
    return decorate

Usage:

import time

@timeout(5)
def mytest():
    print "Start"
    for i in range(1,10):
        time.sleep(1)
        print "%d seconds have passed" % i

if __name__ == '__main__':
    mytest()

Upvotes: 2

FrostNovaZzz
FrostNovaZzz

Reputation: 842

Just derive to a new class and override the insert function. In the overwriting function, check last insert time and call father's insert method if it has been more than five minutes, and of course update the most recent insert time.

Upvotes: 0

drewag
drewag

Reputation: 94763

Each time the function is run save a file with the current time. When the function is run again check the time stored in the file and make sure it is old enough.

Upvotes: 0

Related Questions