• Stars
    star
    307
  • Rank 135,293 (Top 3 %)
  • Language
    Python
  • License
    GNU Lesser Genera...
  • Created over 8 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Python module which allows you to specify timeouts when calling any existing function, and support for stoppable threads

func_timeout

Python module to support running any existing function with a given timeout.

Function Timeout

func_timeout

This is the function wherein you pass the timeout, the function you want to call, and any arguments, and it runs it for up to #timeout# seconds, and will return/raise anything the passed function would otherwise return or raise.

def func_timeout(timeout, func, args=(), kwargs=None):
	'''
		func_timeout - Runs the given function for up to #timeout# seconds.

		Raises any exceptions #func# would raise, returns what #func# would return (unless timeout is exceeded), in which case it raises FunctionTimedOut

		@param timeout <float> - Maximum number of seconds to run #func# before terminating
		@param func <function> - The function to call
		@param args    <tuple> - Any ordered arguments to pass to the function
		@param kwargs  <dict/None> - Keyword arguments to pass to the function.

		@raises - FunctionTimedOut if #timeout# is exceeded, otherwise anything #func# could raise will be raised

		@return - The return value that #func# gives
	'''

Example

So, for esxample, if you have a function "doit('arg1', 'arg2')" that you want to limit to running for 5 seconds, with func_timeout you can call it like this:

from func_timeout import func_timeout, FunctionTimedOut

...

try:

	doitReturnValue = func_timeout(5, doit, args=('arg1', 'arg2'))

except FunctionTimedOut:
	print ( "doit('arg1', 'arg2') could not complete within 5 seconds and was terminated.\n")
except Exception as e:
	# Handle any exceptions that doit might raise here

func_set_timeout

This is a decorator you can use on functions to apply func_timeout.

Takes two arguments, "timeout" and "allowOverride"

If "allowOverride" is present, an optional keyword argument is added to the wrapped function, 'forceTimeout'. When provided, this will override the timeout used on this function.

The "timeout" parameter can be either a number (for a fixed timeout), or a function/lambda. If a function/lambda is used, it will be passed the same arguments as the called function was passed. It should return a number which will be used as the timeout for that paticular run. For example, if you have a method that calculates data, you'll want a higher timeout for 1 million records than 50 records.

Example:

@func_set_timeout(2.5)
def myFunction(self, arg1, arg2):
	...

FunctionTimedOut

Exception raised if the function times out.

Has a "retry" method which takes the following arguments:

* No argument - Retry same args, same function, same timeout
* Number argument - Retry same args, same function, provided timeout
* None - Retry same args, same function, no timeout

How it works

func_timeout will run the specified function in a thread with the specified arguments until it returns, raises an exception, or the timeout is exceeded. If there is a return or an exception raised, it will be returned/raised as normal.

If the timeout has exceeded, the "FunctionTimedOut" exception will be raised in the context of the function being called, as well as from the context of "func_timeout". You should have your function catch the "FunctionTimedOut" exception and exit cleanly if possible. Every 2 seconds until your function is terminated, it will continue to raise FunctionTimedOut. The terminating of the timed-out function happens in the context of the thread and will not block main execution.

StoppableThread

StoppableThread is a subclass of threading.Thread, which supports stopping the thread (supports both python2 and python3). It will work to stop even in C code.

The way it works is that you pass it an exception, and it raises it via the cpython api (So the next time a "python" function is called from C api, or the next line is processed in python code, the exception is raised).

Using StoppableThread

You can use StoppableThread one of two ways:

As a Parent Class

Your thread can extend func_timeout.StoppableThread.StoppableThread and implement the "run" method, same as a normal thread.

from func_timeout.StoppableThread import StoppableThread

class MyThread(StoppableThread):

	def run(self):
		
		# Code here
		return

Then, you can create and start this thread like:

myThread = MyThread()

# Uncomment next line to start thread in "daemon mode" -- i.e. will terminate/join automatically upon main thread exit

#myThread.daemon = True

myThread.start()

Then, at any time during the thread's execution, you can call .stop( StopExceptionType ) to stop it ( more in "Stopping a Thread" below

Direct Thread To Execute A Function

Alternatively, you can instantiate StoppableThread directly and pass the "target", "args", and "kwargs" arguments to the constructor

myThread = StoppableThread( target=myFunction, args=('ordered', 'args', 'here'), kwargs={ 'keyword args' : 'here' } )

# Uncomment next line to start thread in "daemon mode" -- i.e. will terminate/join automatically upon main thread exit

#myThread.daemon = True

myThread.start()

This will allow you to call functions in stoppable threads, for example handlers in an event loop, which can be stopped later via the .stop() method.

Stopping a Thread

The StoppableThread class (you must extend this for your thread) adds a function, stop, which can be called to stop the thread.

def stop(self, exception, raiseEvery=2.0):
	'''
		Stops the thread by raising a given exception.

		@param exception <Exception type> - Exception to throw. Likely, you want to use something

		  that inherits from BaseException (so except Exception as e: continue; isn't a problem)

		  This should be a class/type, NOT an instance, i.e.  MyExceptionType   not  MyExceptionType()


		@param raiseEvery <float> Default 2.0 - We will keep raising this exception every #raiseEvery seconds,

			until the thread terminates.

			If your code traps a specific exception type, this will allow you #raiseEvery seconds to cleanup before exit.

			If you're calling third-party code you can't control, which catches BaseException, set this to a low number
			 
			  to break out of their exception handler.


		 @return <None>
	'''

The "exception" param must be a type, and it must be instantiable with no arguments (i.e. MyExceptionType() must create the object).

Consider using a custom exception type which extends BaseException, which you can then use to do basic cleanup ( flush any open files, etc. ).

The exception type you pass will be raised every #raiseEvery seconds in the context of that stoppable thread. You can tweak this value to give yourself more time for cleanups, or you can shrink it down to break out of empty exception handlers ( try/except with bare except ).

Notes on Exception Type

It is recommended that you create an exception that extends BaseException instead of Exception, otherwise code like this will never stop:

while True:
	try:
		doSomething()
	except Exception as e:
		continue

If you can't avoid such code (third-party lib?) you can set the "repeatEvery" to a very very low number (like .00001 ), so hopefully it will raise, go to the except clause, and then raise again before "continue" is hit.

You may want to consider using singleton types with fixed error messages, so that tracebacks, etc. log that the call timed out.

For example:

class ServerShutdownExceptionType(BaseException):

	def __init__(self, *args, **kwargs):

		BaseException.__init__(self, 'Server is shutting down')

This will force 'Server is shutting down' as the message held by this exception.

Pydoc

Find the latest pydoc at http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=4.3.5 .

Support

I've tested func_timeout with python 2.7, 3.4, 3.5, 3.6, 3.7. It should work on other versions as well.

Works on windows, linux/unix, cygwin, mac

ChangeLog can be found at https://raw.githubusercontent.com/kata198/func_timeout/master/ChangeLog

Pydoc can be found at: http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=1

More Repositories

1

AdvancedHTMLParser

Fast Indexed python HTML parser which builds a DOM node tree, providing common getElementsBy* functions for scraping, testing, modification, and formatting. Also XPath.
Python
100
star
2

python-nonblock

Pure-Python non-blocking IO and background IO functions
Python
27
star
3

PumpkinLB

A simple, fast, pure-python load balancer
Python
26
star
4

QueryableList

Python module to add support for ORM-style filtering to any list of items
Python
22
star
5

indexedredis

A super-fast ORM backed by Redis, supporting models and indexes with O(1) searches, and support for storing native/complex types and objects
Python
18
star
6

NamedAtomicLock

Python module for an atomic named lock which is local to the machine.
Python
10
star
7

cmp_version

A script and python module to compare version numbers. Use this to compare the version strings of packages, modules, really anything.
Python
9
star
8

bash-resume

Adds support in shell scripts to resume execution at last failing point, or to tag completed items to not repeat upon subsequent executions. Like "make" for shell scripts!
Shell
9
star
9

mdToRst

Tool and library to convert markdown [md] to restructed text [rst] (md to rst)
Python
8
star
10

rextract

Powerful commandline tool to extract and manipulate strings using regular exressions
Python
8
star
11

shmfile

Small shared library to use shared memory as a FILE* stream , with interprocess communication in mind
C
7
star
12

jsonToCsv

Extract data from json and convert to csv
Python
6
star
13

ioschedset

Commandline tools to query and/or set the I/O schedulers for block devices on Linux systems
Shell
6
star
14

VirtualEnvOnDemand

Easily create and use virtualenvs via script and provides the ability for an application to install and use its runtime dependencies on first import
Python
6
star
15

popLines

Tools to pop/peek lines from the head/tail or known position within a given file, and output to stdout. Makes files into queues!
Python
5
star
16

python-lrzip

Python bindings to LRZIP
Python
4
star
17

con-ck-patches

The -ck patchset for the linux kernel, merged into 4.15
Shell
4
star
18

python-cllist

C-implemented linked-list module for python
C
3
star
19

python-mkdoc

An amazing helper script to generate pydoc for your python projects
Shell
3
star
20

toJiraTable

Converts input to a JIRA table
Python
3
star
21

NetFetch

Networked file storage and retrieval with optional password protection and compression using Redis
Python
3
star
22

remote_copy_and_execute

Tool to use SSH protocol to copy and execute arbitrary scripts on a list of machines in parallel
Python
3
star
23

cygwin-ps-misc

Utilities that provide missing tools from cygwin, like well-working "pidof" and "killall". Written in python.
Python
3
star
24

shell-advancedutils

Advanced commands to extend SH/Bash shell scripting into a more powerful language
Shell
3
star
25

printk-timestamp-formatter

Utilities to view kmsg/printk/dmesg timestamps in local time and date, UTC, or epoch seconds, TAKING INTO ACCOUNT clock drift
Python
3
star
26

text2datetime

Python module which can convert an extensive number of ways to represent time with strings to datetime objects
Python
2
star
27

cmd_looper

Utility for looping output of shell commands, with ability to specify filters, limits, and automatic refreshes
Shell
2
star
28

cmdtimeout

Execute an arbitrary command with a maximum given timeout
Python
2
star
29

cachebust

Provide a server-side means to ensure that clients always fetch assets when they are updated
Python
2
star
30

disttask

Provides the ability to distribute a task across a fixed number of processes, for better utilization of multiprocessing
Python
2
star
31

pacman-utils

Some utils and helper scripts for archlinux packages
Python
2
star
32

SimpleHttpFetch

Python module to just return a string of a given page provided with a url
Python
2
star
33

setutils

Commandline utilities for working with sets (difference, union, intersection) and shared library (C/C++)
C
2
star
34

usrsvc

A service manager for running/managing/monitoring/auto-restarting daemons and services at the user (non-root) level
Python
2
star
35

ProcessUtils

Utilities for advanced process management (pidfiles, finding pids based on matching strings more powerful than pidof)
Python
2
star
36

python-argumentparser

A python2/3 compatible commandline argument parser.
Python
2
star
37

python-subprocess2

Extensions on the python subprocess module
Python
2
star
38

findProcessOwner

Application which scans a list of given pids and determines the executing user
Python
2
star
39

GoodTests

A fast python unit-testing framework which supports safe, encapsulated parallel execution of tests, unlike other frameworks which share states between tests, and intuitive setup/teardown methodology
Python
2
star
40

ProcessMappingScanner

Python module for scanning running process mappings (for detecting libraries, executables, etc)
Python
2
star
41

findProcessesUsing

Scans all running applications on a host to identify those using a shared library, or an executable, or one of several.
Python
2
star
42

WatchTower

An apperatus for triggering events/actions on a remote machine
Python
1
star
43

pacman-utils-data-pkg

Achlinux PKGBUILD for pacman-utils data
Shell
1
star
44

pacman-utils-pkg

PKGBUILD for pacman-utils
Shell
1
star
45

ichorORM

A python library for postgresql focused on performance and supporting ORM and query-building functionality
Python
1
star
46

SafeRedisLock

Python library for locks across processes/servers which is safe and implements expiration/global timeout
Python
1
star
47

xvfbman

A python module for managing Xvfb sessions / ensuring DISPLAY through a simple interface
Python
1
star
48

mtime_utils

A collection of tools for accessing and working with mtime (modification time) and other stat properties
C
1
star
49

shell-advancedutils-pkg

Archlinux PKGBUILD for shell-advancedutils
Shell
1
star
50

myps2

Faster and special purpose alternatives to standard "ps"
C
1
star
51

pid-tools

Some commandline tools for dealing with pids, information about processes, and their relations
C
1
star
52

socket-gatekeeper

Socket Gatekeeper provides a means of password-securing sockets and providing authentication-based routing
Python
1
star